Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  number.rs

  Sprache: Rust
 

use core::{
    cmp::{Eq, Ordering},
    hash::{Hash, Hasher},
};

use serde::{de::Visitor, Serialize, Serializer};

/// A wrapper for any numeric primitive type in Rust.
///
/// Some varints of the `Number` enum are enabled by features:
/// - `Number::I128` and `Number::U128` by the `integer128` feature
///
/// To ensure that feature unification does not break `match`ing over `Number`,
/// the `Number` enum is non-exhaustive.
///
/// <details>
/// <summary>Exhaustively matching on <code>Number</code> in tests</summary>
///
/// If you want to ensure that you exhaustively handle every variant, you can
/// match on the hidden `Number::__NonExhaustive(x)` variant by using the
/// `x.never() -> !` method.
///
/// <div class="warning">
/// Matching on this variant means that your code may break when RON is
/// upgraded or when feature unification enables further variants in the
/// <code>Number</code> enum than your code expects.
/// </div>
///
/// It is your responsibility to only *ever* match on `Number::__NonExhaustive`
/// inside tests, e.g. by using `#[cfg(test)]` on the particular match arm, to
/// ensure that only your tests break (e.g. in CI) when your code is not
/// exhaustively matching on every variant, e.g. after a version upgrade or
/// feature unification.
/// </details>
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Hash, Ord)]
#[cfg_attr(doc, non_exhaustive)]
pub enum Number {
    I8(i8),
    I16(i16),
    I32(i32),
    I64(i64),
    #[cfg(feature = "integer128")]
    I128(i128),
    U8(u8),
    U16(u16),
    U32(u32),
    U64(u64),
    #[cfg(feature = "integer128")]
    U128(u128),
    F32(F32),
    F64(F64),
    #[cfg(not(doc))]
    #[allow(private_interfaces)]
    __NonExhaustive(private::Never),
}

mod private {
    #[derive(Debug, PartialEq, PartialOrd, Eq, Hash, Ord)]
    enum _Never {}

    #[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Hash, Ord)]
    pub struct Never {
        never: &'static _Never,
    }

    impl Never {
        pub fn never(self) -> ! {
            match *self.never {}
        }
    }

    #[cfg(not(feature = "integer128"))]
    /// ```compile_fail
    /// # use ron::Number;
    /// fn match_number(x: Number) {
    ///     match x {
    ///         Number::I8(v) => println!("i8: {}", v),
    ///         Number::I16(v) => println!("i16: {}", v),
    ///         Number::I32(v) => println!("i32: {}", v),
    ///         Number::I64(v) => println!("i64: {}", v),
    ///         Number::U8(v) => println!("u8: {}", v),
    ///         Number::U16(v) => println!("u16: {}", v),
    ///         Number::U32(v) => println!("u32: {}", v),
    ///         Number::U64(v) => println!("u64: {}", v),
    ///         Number::F32(v) => println!("f32: {}", v.0),
    ///         Number::F64(v) => println!("f64: {}", v.0),
    ///     }
    /// }
    /// ```
    fn _assert_non_exhaustive_check_fails_not_integer128() {}

    #[cfg(feature = "integer128")]
    /// ```compile_fail
    /// # use ron::Number;
    /// fn match_number(x: Number) {
    ///     match x {
    ///         Number::I8(v) => println!("i8: {}", v),
    ///         Number::I16(v) => println!("i16: {}", v),
    ///         Number::I32(v) => println!("i32: {}", v),
    ///         Number::I64(v) => println!("i64: {}", v),
    ///         Number::I128(v) => println!("i128: {}", v),
    ///         Number::U8(v) => println!("u8: {}", v),
    ///         Number::U16(v) => println!("u16: {}", v),
    ///         Number::U32(v) => println!("u32: {}", v),
    ///         Number::U64(v) => println!("u64: {}", v),
    ///         Number::U128(v) => println!("u128: {}", v),
    ///         Number::F32(v) => println!("f32: {}", v.0),
    ///         Number::F64(v) => println!("f64: {}", v.0),
    ///     }
    /// }
    /// ```
    fn _assert_non_exhaustive_check_fails_integer128() {}
}

impl Serialize for Number {
    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        match self {
            Self::I8(v) => serializer.serialize_i8(*v),
            Self::I16(v) => serializer.serialize_i16(*v),
            Self::I32(v) => serializer.serialize_i32(*v),
            Self::I64(v) => serializer.serialize_i64(*v),
            #[cfg(feature = "integer128")]
            Self::I128(v) => serializer.serialize_i128(*v),
            Self::U8(v) => serializer.serialize_u8(*v),
            Self::U16(v) => serializer.serialize_u16(*v),
            Self::U32(v) => serializer.serialize_u32(*v),
            Self::U64(v) => serializer.serialize_u64(*v),
            #[cfg(feature = "integer128")]
            Self::U128(v) => serializer.serialize_u128(*v),
            Self::F32(v) => serializer.serialize_f32(v.get()),
            Self::F64(v) => serializer.serialize_f64(v.get()),
            #[cfg(not(doc))]
            Self::__NonExhaustive(never) => never.never(),
        }
    }
}

impl Number {
    pub fn visit<'de, V: Visitor<'de>, E: serde::de::Error>(
        &self,
        visitor: V,
    ) -> Result<V::Value, E> {
        match self {
            Self::I8(v) => visitor.visit_i8(*v),
            Self::I16(v) => visitor.visit_i16(*v),
            Self::I32(v) => visitor.visit_i32(*v),
            Self::I64(v) => visitor.visit_i64(*v),
            #[cfg(feature = "integer128")]
            Self::I128(v) => visitor.visit_i128(*v),
            Self::U8(v) => visitor.visit_u8(*v),
            Self::U16(v) => visitor.visit_u16(*v),
            Self::U32(v) => visitor.visit_u32(*v),
            Self::U64(v) => visitor.visit_u64(*v),
            #[cfg(feature = "integer128")]
            Self::U128(v) => visitor.visit_u128(*v),
            Self::F32(v) => visitor.visit_f32(v.get()),
            Self::F64(v) => visitor.visit_f64(v.get()),
            #[cfg(not(doc))]
            Self::__NonExhaustive(never) => never.never(),
        }
    }
}

macro_rules! float_ty {
    ($ty:ident($float:ty)) => {
        #[doc = concat!(
                    "A wrapper for [`", stringify!($float), "`], which implements [`Eq`], ",
                    "[`Hash`] and [`Ord`] using [`", stringify!($float), "::total_cmp`] ",
                    "for a total order comparison",
                )]
        #[derive(Copy, Clone, Debug)] // GRCOV_EXCL_LINE
        pub struct $ty(pub $float);

        impl $ty {
            #[doc = concat!("Construct a new [`", stringify!($ty), "`].")]
            #[must_use]
            pub fn new(v: $float) -> Self {
                Self(v)
            }

            #[doc = concat!("Returns the wrapped [`", stringify!($float), "`].")]
            #[must_use]
            pub fn get(self) -> $float {
                self.0
            }
        }

        impl From<$float> for $ty {
            fn from(v: $float) -> Self {
                Self::new(v)
            }
        }

        /// Partial equality comparison
        ///
        #[doc = concat!(
                    "In order to be able to use [`", stringify!($ty), "`] as a mapping key, ",
                    "floating values use [`", stringify!($float), "::total_cmp`] for a total ",
                    "order comparison.",
                )]
        ///
        /// See the [`Ord`] implementation.
        impl PartialEq for $ty {
            fn eq(&self, other: &Self) -> bool {
                self.cmp(other).is_eq()
            }
        }

        /// Equality comparison
        ///
        #[doc = concat!(
                    "In order to be able to use [`", stringify!($ty), "`] as a mapping key, ",
                    "floating values use [`", stringify!($float), "::total_cmp`] for a total ",
                    "order comparison.",
                )]
        ///
        /// See the [`Ord`] implementation.
        impl Eq for $ty {}

        impl Hash for $ty {
            fn hash<H: Hasher>(&self, state: &mut H) {
                self.0.to_bits().hash(state);
            }
        }

        /// Partial ordering comparison
        ///
        #[doc = concat!(
                    "In order to be able to use [`", stringify!($ty), "`] as a mapping key, ",
                    "floating values use [`", stringify!($float), "::total_cmp`] for a total ",
                    "order comparison.",
                )]
        ///
        /// See the [`Ord`] implementation.
        impl PartialOrd for $ty {
            fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
                Some(self.cmp(other))
            }
        }

        /// Ordering comparison
        ///
        #[doc = concat!(
                    "In order to be able to use [`", stringify!($ty), "`] as a mapping key, ",
                    "floating values use [`", stringify!($float), "::total_cmp`] for a total ",
                    "order comparison.",
                )]
        ///
        /// ```
        #[doc = concat!("use ron::value::", stringify!($ty), ";")]
        #[doc = concat!(
                    "assert!(", stringify!($ty), "::new(", stringify!($float), "::NAN) > ",
                    stringify!($ty), "::new(", stringify!($float), "::INFINITY));",
                )]
        #[doc = concat!(
                    "assert!(", stringify!($ty), "::new(-", stringify!($float), "::NAN) < ",
                    stringify!($ty), "::new(", stringify!($float), "::NEG_INFINITY));",
                )]
        #[doc = concat!(
                    "assert!(", stringify!($ty), "::new(", stringify!($float), "::NAN) == ",
                    stringify!($ty), "::new(", stringify!($float), "::NAN));",
                )]
        /// ```
        impl Ord for $ty {
            fn cmp(&self, other: &Self) -> Ordering {
                self.0.total_cmp(&other.0)
            }
        }
    };
}

float_ty! { F32(f32) }
float_ty! { F64(f64) }

impl Number {
    /// Construct a new number.
    pub fn new(v: impl Into<Number>) -> Self {
        v.into()
    }

    /// Returns the [`f64`] representation of the [`Number`] regardless of
    /// whether the number is stored as a float or integer.
    ///
    /// # Example
    ///
    /// ```
    /// # use ron::value::Number;
    /// let i = Number::new(5);
    /// let f = Number::new(2.0);
    /// assert_eq!(i.into_f64(), 5.0);
    /// assert_eq!(f.into_f64(), 2.0);
    /// ```
    #[must_use]
    pub fn into_f64(self) -> f64 {
        #[allow(clippy::cast_precision_loss)]
        match self {
            Self::I8(v) => f64::from(v),
            Self::I16(v) => f64::from(v),
            Self::I32(v) => f64::from(v),
            Self::I64(v) => v as f64,
            #[cfg(feature = "integer128")]
            Self::I128(v) => v as f64,
            Self::U8(v) => f64::from(v),
            Self::U16(v) => f64::from(v),
            Self::U32(v) => f64::from(v),
            Self::U64(v) => v as f64,
            #[cfg(feature = "integer128")]
            Self::U128(v) => v as f64,
            Self::F32(v) => f64::from(v.get()),
            Self::F64(v) => v.get(),
            #[cfg(not(doc))]
            Self::__NonExhaustive(never) => never.never(),
        }
    }
}

macro_rules! number_from_impl {
    (Number::$variant:ident($wrap:ident($ty:ty))) => {
        impl From<$ty> for Number {
            fn from(v: $ty) -> Number {
                Number::$variant($wrap(v))
            }
        }
    };
    (Number::$variant:ident($ty:ty)) => {
        impl From<$ty> for Number {
            fn from(v: $ty) -> Number {
                Number::$variant(v)
            }
        }
    };
}

number_from_impl! { Number::I8(i8) }
number_from_impl! { Number::I16(i16) }
number_from_impl! { Number::I32(i32) }
number_from_impl! { Number::I64(i64) }
#[cfg(feature = "integer128")]
number_from_impl! { Number::I128(i128) }
number_from_impl! { Number::U8(u8) }
number_from_impl! { Number::U16(u16) }
number_from_impl! { Number::U32(u32) }
number_from_impl! { Number::U64(u64) }
#[cfg(feature = "integer128")]
number_from_impl! { Number::U128(u128) }
number_from_impl! { Number::F32(F32(f32)) }
number_from_impl! { Number::F64(F64(f64)) }

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_nan() {
        assert_eq!(F32(f32::NAN), F32(f32::NAN));
        assert_eq!(F32(-f32::NAN), F32(-f32::NAN));
        assert_ne!(F32(f32::NAN), F32(-f32::NAN));
    }

    #[cfg(feature = "std")]
    #[test]
    fn test_nan_hash() {
        use std::collections::hash_map::DefaultHasher;
        use std::hash::{Hash, Hasher};

        fn hash<T: Hash>(v: &T) -> u64 {
            let mut state = DefaultHasher::new();
            v.hash(&mut state);
            state.finish()
        }

        assert_eq!(hash(&F32(f32::NAN)), hash(&F32(f32::NAN)));
        assert_eq!(hash(&F32(-f32::NAN)), hash(&F32(-f32::NAN)));
        assert_ne!(hash(&F32(f32::NAN)), hash(&F32(-f32::NAN)));
    }

    #[test]
    fn test_partial_ord() {
        assert!(F32(f32::NAN) > F32(f32::INFINITY));
        assert!(F32(-f32::NAN) < F32(f32::NEG_INFINITY));
        assert!(F32(f32::NAN) == F32(f32::NAN));
    }
}

Messung V0.5 in Prozent
C=76 H=100 G=88

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=277311
#Domains=752002