100-exercises-to-learn-rust
100-exercises-to-learn-rust copied to clipboard
Need suggestions for 04_traits/14_outro
I want to write an minimal solution to reduce duplications. Everything is good except this part:
impl<'a, T: Unsigned + Into<u16> + Copy> From<&'a T> for SaturatingU16 {
fn from(value: &'a T) -> Self {
Self {value: (*value).into()}
}
}
where I want to implement From for &T types. Could you give me any suggestions? Below is my complete solution. I also write a macro solution for From traits.
// TODO: Define a new `SaturatingU16` type.
// It should hold a `u16` value.
// It should provide conversions from `u16`, `u8`, `&u16` and `&u8`.
// It should support addition with a right-hand side of type
// SaturatingU16, u16, &u16, and &SaturatingU16. Addition should saturate at the
// maximum value for `u16`.
// It should be possible to compare it with another `SaturatingU16` or a `u16`.
// It should be possible to print its debug representation.
//
// Tests are located in the `tests` folder—pay attention to the visibility of your types and methods.
use std::ops::Add;
use num::Unsigned;
trait IntoU16<T> {
fn into_u16(self) -> u16;
}
impl IntoU16<SaturatingU16> for SaturatingU16 {
fn into_u16(self) -> u16 {
self.value
}
}
impl<'a> IntoU16<&'a SaturatingU16> for &'a SaturatingU16 {
fn into_u16(self) -> u16 {
self.value
}
}
impl<T> IntoU16<T> for T
where
T: Unsigned + Into<u16>,
{
fn into_u16(self) -> u16 {
self.into()
}
}
impl<'a, T> IntoU16<T> for &'a T
where
T: Unsigned + Into<u16> + Copy,
{
fn into_u16(self) -> u16 {
(*self).into()
}
}
#[derive(Debug, Clone, Copy)]
pub struct SaturatingU16 {
value: u16
}
impl<T: Unsigned + Into<u16>> From<T> for SaturatingU16 {
fn from(value: T) -> Self {
Self {value: value.into()}
}
}
impl<'a, T: Unsigned + Into<u16> + Copy> From<&'a T> for SaturatingU16 {
fn from(value: &'a T) -> Self {
Self {value: (*value).into()}
}
}
// macro_rules! impl_from {
// ($t:ty) => {
// impl From<$t> for SaturatingU16 {
// fn from(value: $t) -> Self {
// SaturatingU16 {
// value: value.into(),
// }
// }
// }
// impl<'a> From<&'a $t> for SaturatingU16 {
// fn from(value: &'a $t) -> Self {
// SaturatingU16 {
// value: (*value).into(),
// }
// }
// }
// };
// }
// impl_from!(u8);
// impl_from!(u16);
impl<T> Add<T> for SaturatingU16
where
T: IntoU16<T>,
{
type Output = SaturatingU16;
fn add(self, rhs: T) -> Self::Output {
let rhs_value: u16 = rhs.into_u16();
let new_value = self.value.saturating_add(rhs_value);
SaturatingU16 {value: new_value}
}
}
impl<T> PartialEq<T> for SaturatingU16
where
T: IntoU16<T> + Copy,
{
fn eq(&self, other: &T) -> bool {
self.value == other.into_u16()
}
}
There is a discord server working on the repo also, check it out: https://discord.gg/tH5HpRJZ