I am currently making my way through the Rust book and rustlings. try_from_into.rs
asks us to implement TryFrom
for a tuple, and array, and a slice. The array and slice versions fit nicely into an iter/map/collect
pattern, e.g. as follows:
// Array implementation
impl TryFrom<[i16; 3]> for Color {
type Error = IntoColorError;
fn try_from(arr: [i16; 3]) -> Result<Self, Self::Error> {
match arr
.iter()
.map(|x| u8::try_from(*x))
.collect::<Result<Vec<_>, _>>()
{
Ok(v) => Ok(Color {
red: v[0],
green: v[1],
blue: v[2],
}),
_ => Err(IntoColorError::IntConversion),
}
}
}
Possibly this is not idiomatic either, so I'd appreciate any corrections.
However, the tuple implementation seems to leave me with two choices:
Put the tuple (of 3
i16
s) into an array and then use themap
pattern above. This seems wasteful.Repeat myself by converting each value to
u8
, checking the result, and assigning to a local variable, e.g.fn try_from(tuple: (i16, i16, i16)) -> Result<Self, Self::Error> { let red = match u8::try_from(val) { Ok(v) => Ok(v), _ => return Err(IntoColorError::IntConversion), }; let green = ... let blue = ... Ok(Color { red, green, blue }) }
My first instinct is to put the match
code into a helper and inline it if the language supported doing so, but Rust seems to have some barriers to that:
- Private trait methods are not allowed, so I can't just add a helper inside the implementation. However, I lose any notion of what
Self::Error
is outside of the implementation. - We can't use generic parameters from outer functions, so neither can I create an inner function which uses
Self::Error
in thetry_from
definition, e.g. likefn try_from(tuple: (i16, i16, i16)) -> Result<Self, Self::Error> { #[inline] fn i16_to_u8(val: i16) -> Result<u8, Self::Error> { match u8::try_from(val) { Ok(v) => Ok(v), _ => return Err(IntoColorError::IntConversion), } } let red = i16_to_u8(tuple.0)?; ... }
What are the Rust idioms for avoiding repeated code inside trait implementations, especially where a helper method seems like the obvious choice to someone coming from languages where these are commonplace?