xeere
xeere

Reputation: 23

how to avoid unconstrained type paramameter error

I can't think of a way to get the functionality below, without the use of unconstrained types.

struct Things<T> {
    thing: T
}
trait ThingActions<D> {//will be implemented for 'D's of different types
    fn foo(&self, data: D) {}
    fn bar(&self, data: D) {}
}
impl<T: ThingActions<D>, D> Things<T> {
    fn do_foos(&self, data: D) {//any D with corresponding foo can be used here
        self.thing.foo(data)
    }
}
impl<T: ThingActions<D>, D: Send + Sync> Things<T> {
    fn do_bars_multithreaded(&self, data: D) {
        self.thing.bar(&self.thing, data)//this happens in a different thread
    }
}

My end goal is to have the code below work for any configuration of foo and bar, with relatively few changes to it.

fn main(){
    let number = Things {thing: 5isize};
    number.do_foos(2);
    number.do_foos('a');
}
impl ThingActions<isize> for isize {
    fn foo(&self, data: isize){
        println!("{}", data + self)
    }
}
impl ThingActions<char> for isize {
    fn foo(&self, data: char){
        println!("{}, {}", data, self)
    }
}

There are also possible situations where none of this is used except "Things".

Upvotes: 0

Views: 27

Answers (1)

phimuemue
phimuemue

Reputation: 35973

You could try to bound D only on the fn, and not on the whole struct:

struct Things<T> {
    thing: T
}
trait ThingActions<D> {//will be implemented for 'D's of different types
    fn foo(&self, data: D) {}
    fn bar(&self, data: D) {}
}
impl<T> Things<T> {
    fn do_foos<D>(&self, data: D)
        where T: ThingActions<D>
    {//any D with corresponding foo can be used here
        self.thing.foo(data)
    }
}
impl<T> Things<T> {
    fn do_bars_multithreaded<D>(&self, data: D)
        where T: ThingActions<D>, D: Send + Sync
    {
        self.thing.bar(data)//this happens in a different thread
    }
}

fn main(){
    let number = Things {thing: 5isize};
    number.do_foos(2);
    number.do_foos('a');
}
impl ThingActions<isize> for isize {
    fn foo(&self, data: isize){
        println!("{}", data + self)
    }
}
impl ThingActions<char> for isize {
    fn foo(&self, data: char){
        println!("{}, {}", data, self)
    }
}

Upvotes: 1

Related Questions