1
votes

I'm using the texture-synthesis crate. I'm creating a structure RenderSettings that I'm going to feed into some of this crate's functions:

texture-synthesis = "0.8.0"
use texture_synthesis as ts;

#[derive(Debug, Clone, Copy)]
pub struct RenderSettings{
    seed: u64,
    tiling_mode: bool, 
    nearest_neighbors: u32,
    output_size: ts::Dims, //throws error
}

However this gives me the error:

`texture_synthesis::Dims` doesn't implement `std::fmt::Debug`

`texture_synthesis::Dims` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`

I see in the source code this definition of the Dims structure, which seems to implement Debug:

#[derive(Copy, Clone)]
#[cfg_attr(test, derive(Debug, PartialEq))]
pub struct Dims {
    pub width: u32,
    pub height: u32,
}

I'm imagining my problem has something to do with #[cfg_attr(test, derive(Debug, PartialEq))]. I'm not really sure what this statement means, but it seems to suggest that I can use Debug somehow with this struct. So how can I fix this error?

1
#[cfg_attr(test, derive(Debug, PartialEq))] means that Debug and PartialEq will only be derived when it's in test mode (a.k.a you're running cargo test). I don't know why the crate authors decided to do this, but you could always make a newtype (tuple struct with one element) and make your own Debug on that since width and height are public fields. - Aplet123
@Aplet123 could you possible demonstrate what doing that would look like? - ANimator120

1 Answers

2
votes

#[cfg_attr(test, derive(Debug, PartialEq))] is an example of conditional compilation that will only derive Debug and PartialEq when the test attribute is specified (essentially when you're running cargo test.

If you want Debug, you could consider making a newtype wrapper:

use std::fmt;

#[derive(Copy, Clone)]
pub struct DimsWrapper(ts::Dims);

impl fmt::Debug for DimsWrapper {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("DimsWrapper")
            .field("width", &self.0.width)
            .field("height", &self.0.height)
            .finish()
    }
}

Then, you could create one with:

DimsWrapper(ts::Dims {
    width: 5,
    height: 6
});

And extract the ts::Dims with:

dims_wrapper.0

or with pattern matching. If you want to be able to call Dims's methods directly on it, consider implementing Deref:

impl std::ops::Deref for DimsWrapper {
    type Target = ts::Dims;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}