100-exercises-to-learn-rust icon indicating copy to clipboard operation
100-exercises-to-learn-rust copied to clipboard

Need suggestions for 04_traits/14_outro

Open zhoubin-me opened this issue 1 year ago • 1 comments

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()
    }
}

zhoubin-me avatar Oct 28 '24 08:10 zhoubin-me

There is a discord server working on the repo also, check it out: https://discord.gg/tH5HpRJZ

GoLangCentral avatar Nov 22 '24 20:11 GoLangCentral