Conflicting implementations!


#1

Code

struct B32<T>(T);
trait B32Encode<I,O>{fn encode(input:I)->O;}

pub trait C8CPP{fn c8p_ptr(&self)->*const u8;}
impl C8CPP for u8{
    fn c8p_ptr(&self)->*const u8{
        self as *const u8
    }
}

pub trait C16CPP{fn c16p_ptr(&self)->*const u16;}
impl C16CPP for u16{
    fn c16p_ptr(&self)->*const u16{
        self as *const u16
    }
}


impl<T:C8CPP> B32Encode<T,String> for B32<String>{
    fn encode(input:T)->String{
        input.c8p_ptr();
        String::from("C8")
    }
}

impl<T:C16CPP> B32Encode<T,String> for B32<String>{
    fn encode(input:T)->String{
        input.c16p_ptr();
        String::from("C16")
    }
}


fn main(){
    println!("{}",B32::<String>::encode(0u8));
    println!("{}",B32::<String>::encode(0u16));
}

Error:

error[E0119]: conflicting implementations of trait `B32Encode<_, std::string::String>` for type `B32<std::string::String>`:
  --> src\main.rs:49:1
   |
42 | / impl<T:C8CPP> B32Encode<T,String> for B32<String>{
43 | |     fn encode(input:T)->String{
44 | |         input.c8p_ptr();
45 | |         String::from("C8")
46 | |     }
47 | | }
   | |_- first implementation here
48 |
49 | / impl<T:C16CPP> B32Encode<T,String> for B32<String>{
50 | |     fn encode(input:T)->String{
51 | |         input.c16p_ptr();
52 | |         String::from("C16")
53 | |     }
54 | | }
   | |_^ conflicting implementation for `B32<std::string::String>`

error: aborting due to previous error

It can be fixed?


#2

This is the solution! I dont like it. Are there any solutions?

struct B32<T>(T);
trait B32Encode<I,O,K>{fn encode(input:I)->O;}

pub trait C8CPP{fn c8p_ptr(&self)->*const u8;}
impl C8CPP for u8{
    fn c8p_ptr(&self)->*const u8{
        self as *const u8
    }
}

pub trait C16CPP{fn c16p_ptr(&self)->*const u16;}
impl C16CPP for u16{
    fn c16p_ptr(&self)->*const u16{
        self as *const u16
    }
}


impl<T:C8CPP> B32Encode<T,String,u8> for B32<String>{
    fn encode(input:T)->String{
        input.c8p_ptr();
        String::from("C8")
    }
}

impl<T:C16CPP> B32Encode<T,String,u16> for B32<String>{
    fn encode(input:T)->String{
        input.c16p_ptr();
        String::from("C16")
    }
}


fn main(){
    println!("{}",B32::<String>::encode(0u8));
    println!("{}",B32::<String>::encode(0u16));
}

#3

The problem is that there could in theory exist a type that implements both C8CPP and C16CPP, and then both of your implementations would apply to it.

Perhaps you could have one level of indirection less and implement B32Encode for &u8 and &u16?