let me show the code first:
pub trait TryFromBuf: Sized {
fn try_from_buf<B: AsRef<[u8]>>(b: B) -> Result<Self, ()>;
}
pub trait InternalTryInto<T: Sized>: Sized {
fn try_into(self) -> Result<T, ()>;
}
impl<T, B> InternalTryInto<T> for B
where
T: TryFromBuf,
B: AsRef<[u8]>,
{
fn try_into(self) -> Result<T, ()> {
T::try_from_buf(self)
}
}
fn main() {
let b = &[4, 2];
println!("{}", u16::from_le_bytes(b[0..2].try_into().unwrap()));
}
or test it on playground:
(can I just link to the playground or do I have to paste the code here?)
it emits this error:
error[E0034]: multiple applicable items in scope
--> src/main.rs:21:47
|
21 | println!("{}", u16::from_le_bytes(b[0..2].try_into().unwrap()));
| ^^^^^^^^ multiple `try_into` found
|
note: candidate #1 is defined in an impl of the trait `InternalTryInto` for the type `B`
this is a little surprising for me, since there's no impl TryFromBuf for [u8;2]
. and we already knew std
try_into
works because rust type inference can match on return type (is my understanding wrong?).
Programming rust is mostly fun but sometimes feel like wrestling with the compiler
BTW, this was a (failed) attempt of a workaround for rust not allowing implementing external trait generically, in this case:
impl<T: AsRef<u8>> std::convert::TryFrom<T> for MyStrcut
or:
impl<T: TryFromBuf> std::convert::TryFrom<&[u8]> for T
I have multiple internal structs that can be constructed from &[u8]
or mmap
and I wanted to generalize on that, and using the familiar .try_into()
pattern, I settled by just renaming try_into
to parse
. maybe this is bad practice, I'm of course open to suggestions.