I am trying to write a function that can descent into any kind of Value
and inform a Delegate
about the similarities it observes. The idea is to make this work across all kinds of Json/Yaml/YouNameIt values, generically.
Here is an MVCE to trigger the issue (playground link):
pub trait Value: PartialEq<Self> {
type Item;
type Key;
fn items<'a>(&'a self) -> Option<Box<Iterator<Item = (Self::Key, &'a Self::Item)> + 'a>>;
}
pub trait Delegate<'a, V> {
fn something(&mut self, _v: &'a V) {}
}
pub fn diff<'a, V, D>(l: &'a V, d: &'a mut D)
where V: Value,
<V as Value>::Item: Value,
D: Delegate<'a, V>
{
d.something(l);
let v = l.items().unwrap().next().unwrap();
d.something(v.1);
}
struct Recorder;
impl<'a, V> Delegate<'a, V> for Recorder {}
#[derive(PartialEq)]
struct RecursiveValue;
impl Value for RecursiveValue {
type Key = usize;
type Item = RecursiveValue;
fn items<'a>(&'a self) -> Option<Box<Iterator<Item = (Self::Key, &'a Self::Item)> + 'a>> {
None
}
}
fn main() {
let v = RecursiveValue;
let mut r = Recorder;
diff(&v, &mut r);
}
When attempting to compile the code, the following error is produced:
error[E0308]: mismatched types
--> <anon>:19:17
|
19 | d.something(v.1);
| ^^^ expected type parameter, found associated type
|
= note: expected type `&'a V`
= note: found type `&<V as Value>::Item`
I'm trying to say that the associated Item
type is of type V
too. Is there a way to make such an algorithm work generically?