Reputation: 3426
I'm attempting to generalize/decouple an API, so that alternative structs that satisfy a Trait can be used. Struggling on Syntax regarding nested traits. This is a stripped down example of what I'm attempting to do. Note that in the real one, there are multiple sub-traits, which potentially makes a follow-on question of "how to reduce verbosity, if I'm on the right track".
pub mod general {
/// A trait to make the API generic
pub trait MyTrait<A: PartialEq> {
// type A: Partial
fn val(self) -> A;
}
/// Part of the generic API
pub struct Data<A: PartialEq, T: MyTrait<A>> {
mys: T
}
/// Another part of the generic API
fn doit<A: PartialEq>(s: impl MyTrait<A>) -> impl MyTrait {
s
}
}
pub mod specific {
/// Api-specific substruct
#[derive(PartialEq)]
pub struct Aval {
val: u32
}
/// My top-level custom struct
pub struct MyS {
val: Aval
}
}
impl<A: PartialEq> crate::general::MyTrait<A> for crate::specific::MyS {
fn val(self) -> crate::specific::Aval {
self.val
}
}
/// Example of how we'd use this
fn main() {
let mys = crate::specific::MyS{ val: crate::specific::Aval{ val: 0 } };
let S = crate::general::Data{mys};
crate::general::doit(mys); // Eg pretend we cloned or didn't create S.
}
In this specific example, we have a chicken+egg: Error on the Data struct of error[E0392]: parameter `A` is never used
. Where if we remove A: error[E0412]: cannot find type `A` in this scope
I suspect this is a syntax problem related to associated types.
Upvotes: 1
Views: 326
Reputation: 3875
Just remove the trait bound from your struct
.
struct Data<T> {
mys: T
}
You can still add methods and trait implementations for Data<T>
requiring more specific bounds on T
, but you don’t need them to define the layout of Data<T>
, so you shouldn’t specify them there (and in this case, you can’t, unless you add a PhantomData
member referring to A
).
Your code has a number of other errors, but I trust you’ll figure them out. Feel free to comment if you get stuck again.
Upvotes: 1