PartialOrd of Rust Enums based on encapsulated data

595 Views Asked by At

I have an Enum the encapsulates numeric primitives (u8, i8, u16, i16, u32, i32, u64, i64, f32, f64) into a common type called "Number". I want to implement a PartialOrd train for the enum based on the encapsulated data allowing different numbers to be compared. I have a solution that uses nested pattern matching and casting, but it seems unwieldy. Is there a better way to do this?

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=7edcbe456847fb129475ee40568d21c2

use std::cmp::Ordering;

#[derive(PartialEq)]
enum Number {
    U8(u8),
    I8(i8),
    U16(u16),
    I16(i16)
}

impl PartialOrd for Number {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        // self.height.partial_cmp(&other.height)
        match self {
            Number::U8(x) => {
                match other {
                    Number::U8(y) => (*x).partial_cmp(y),
                    Number::I8(y) => (*x as i16).partial_cmp(&(*y as i16)),
                    Number::U16(y) => (*x as u16).partial_cmp(y),
                    Number::I16(y) => (*x as i32).partial_cmp(&(*y as i32)),
                }
            },
            Number::I8(x) => {
                match other {
                    Number::U8(y) => (*x as i16).partial_cmp(&(*y as i16)),
                    Number::I8(y) => (*x).partial_cmp(y),
                    Number::U16(y) => (*x as u16).partial_cmp(y),
                    Number::I16(y) => (*x as i32).partial_cmp(&(*y as i32)),
                }
            },
            Number::U16(x) => {
                match other {
                    Number::U8(y) => (*x).partial_cmp(&(*y as u16)),
                    Number::I8(y) => (*x as i32).partial_cmp(&(*y as i32)),
                    Number::U16(y) => (*x).partial_cmp(y),
                    Number::I16(y) => (*x as i32).partial_cmp(&(*y as i32)),
                }
            },
            Number::I16(x) => {
                match other {
                    Number::U8(y) => (*x).partial_cmp(&(*y as i16)),
                    Number::I8(y) => (*x).partial_cmp(&(*y as i16)),
                    Number::U16(y) => (*x as i32).partial_cmp(&(*y as i32)),
                    Number::I16(y) => (*x).partial_cmp(y),
                }
            },
        }
    }
}
0

There are 0 best solutions below