Rustlings 'traits3.rs' question

Hi all, apologies for the noob question, but I'm working my way through the rustlings course and I'm stuck at the traits3.rs question, where we are expected to provide a default implementation of a trait to allow the the tests to pass.

For reference, the question is:

/ traits3.rs
//
// Your task is to implement the Licensed trait for
// both structures and have them return the same
// information without writing the same function twice.
//
// Consider what you can add to the Licensed trait.
// Execute `rustlings hint traits3` or use the `hint` watch subcommand for a hint.

// I AM NOT DONE

pub trait Licensed {
    fn licensing_info(&self) -> String
}

struct SomeSoftware {
    version_number: i32,
}

struct OtherSoftware {
    version_number: String,
}

impl Licensed for SomeSoftware {} // Don't edit this line
impl Licensed for OtherSoftware {} // Don't edit this line

My naive fix was to provide a default implementation that accessed the version_number, e.g.:

pub trait Licensed {
    fn licensing_info(&self) -> String {
        format!("{}", self.version_number)
    }
}

But of course this doesn't work since there's no guarantee that Self has such a member.

I'm at a loss how to to solve this without providing getters for the version number as part of each structs implementation.

What am I missing?

I have no idea what the true answer is,but derive macro could help.

perhaps write a derive macro could solve your problem.

If derive is not allow, maybe you could firstly use Debug trait to convert structs into "SomeSoftware(version_number)" and then discard useless chars.

Appreciate the suggestions but the solutions here are usually straightforward one or two liners (and we haven't even got to the use of derive yet).

1 Like

Oops, my bad - apparently the tests only expected a constant, placeholder string. :slight_smile: Solved!

1 Like

If the goal is to provide a default information, and your trait has no other methods or super-traits which you can use to find out more about self (e.g. getters), your only real choice is to return a hard-coded value.

pub trait Licensed {
    fn licensing_info(&self) -> String {
        "unknown".into()
    }
}
1 Like

It likely is. Judging from the test:

fn is_licensing_info_the_same() {
    let licensing_info = String::from("Some information");
    let some_software = SomeSoftware { version_number: 1 };
    let other_software = OtherSoftware {
        version_number: "v2.0.0".to_string(),
    };
    assert_eq!(some_software.licensing_info(), licensing_info);
    assert_eq!(other_software.licensing_info(), licensing_info);
}