Implement Display trait for enum struct variants

I have the following code for deserializing some YAML file with serde-yaml:

#[derive(Serialize, Deserialize, Clone)]
pub enum Solution {
    // a solution which is an error where the error is supposed to happen
    ErrorSolution {
        solution_type: String,
        error_name: String,
        error_message: String
    },
    // a solution which is the value for a defined variable
    VariableSolution {
        solution_type: String,
        variable_name: String,
        variable_type: String,
        variable_value: String
    }
}

and am trying to implement the Display trait as follows:

impl fmt::Display for Solution::VariableSolution {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{{solution_type: {}, variable_name: {}, variable_type: {}, variable_value: {}}}",
               self.solution_type,
               self.variable_name,
               self.variable_type,
               self.variable_value)
    }
}

But this does not work. I get the following error:

expected type, found variant `Solution::VariableSolution` (not a type) [E0573]

you can try using the variant's enum: `model::Solution` [E0573]

How can I implement traits for enum struct variants, so that I can println! them for example?

I believe that you can't implement a trait only for a variant of a type, but that you should implement it for the whole type:

impl fmt::Display for Solution {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match (self) {
            VariableSolution => {
                write!(f, "{{solution_type: {}, variable_name: {}, variable_type: {}, variable_value: {}}}",
                     self.solution_type,
                     self.variable_name,
                     self.variable_type,
                     self.variable_value) },
             _ => ... something else ...
        }
    }
}

Code not tested

2 Likes

Thanks! That helped. The working code is:

impl fmt::Display for Solution {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Solution::VariableSolution{
                solution_type,
                variable_name,
                variable_type,
                variable_value
            } =>
                write!(f, "{{solution_type: {},\
                            variable_name: {},\
                            variable_type: {},\
                            variable_value: {}}}",
                       solution_type,
                       variable_name,
                       variable_type,
                       variable_value),
            _ => ... something else ...
        }
    }
}

... at least before running the program. Turns out I need to use &Solution::VariableSolution in the match, leave away the * before self and use ref before the fields to avoid moving borrowed content:

impl fmt::Display for Solution {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Solution::VariableSolution{
                ref solution_type,
                ref variable_name,
                ref variable_type,
                ref variable_value
            } =>
                write!(f, "{{solution_type: {},\
                            variable_name: {},\
                            variable_type: {},\
                            variable_value: {}}}",
                       solution_type,
                       variable_name,
                       variable_type,
                       variable_value),
            _ => ... something else ...
        }
    }
}
1 Like