Here is a link to this example in Rust playground
I am creating two traits. The one trait uses the other as an associated type. The associated trait extends FromStr
:
trait Behaviour where Self: FromStr {}
trait AnotherBehaviour {
type Assoc: Behaviour;
}
I can implement these traits for Derp
and AnotherDerp
respectively, remembering to implement FromStr
for Derp
:
struct Error {}
struct Derp {}
struct AnotherDerp {}
impl Behaviour for Derp {}
impl FromStr for Derp {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s { "derp" => Ok(Derp{}), _ => Err(Error {}) }
}
}
impl AnotherBehaviour for AnotherDerp {
type Assoc = Derp;
}
Now I want to create a generic function that uses the encapsulating trait.
fn run<T: AnotherBehaviour>() {
let derp = T::Assoc::from_str("derp").expect("expected derp");
}
fn main() {
run::<AnotherDerp>();
}
I get the error:
note: the method `expect` exists but the following trait bounds were not satisfied:
`<<T as AnotherBehaviour>::Assoc as std::str::FromStr>::Err : std::fmt::Debug`
I implement Debug
for my Error
type:
#[derive(Debug)]
struct Error {}
But this won't work because I actually need to constrain the trait.
I know that I can constrain the generic function with
where
<T::Assoc as FromStr>::Err: Debug,
but how can I constrain the Behaviour
or AnotherBehaviour
trait to require FromStr::Err
to implement Debug
? I can't figure out the syntax.
I have tried
trait Behaviour: FromStr
where
<Self as FromStr>::Err: Debug
and
trait Behaviour: FromStr
where
Self::Err: Debug