use-js-value 0.0.1

JavaScript-like primitive value metadata for RustUse
Documentation
#![forbid(unsafe_code)]
#![doc = include_str!("../README.md")]

/// Primitive JavaScript-like values for metadata and validation helpers.
#[derive(Clone, Debug, PartialEq)]
pub enum JsPrimitiveValue {
    Undefined,
    Null,
    Boolean(bool),
    Number(f64),
    String(String),
    BigInt(String),
    Symbol(String),
}

impl JsPrimitiveValue {
    /// Returns a JavaScript-style primitive type label.
    #[must_use]
    pub const fn type_name(&self) -> &'static str {
        match self {
            Self::Undefined => "undefined",
            Self::Null => "null",
            Self::Boolean(_) => "boolean",
            Self::Number(_) => "number",
            Self::String(_) => "string",
            Self::BigInt(_) => "bigint",
            Self::Symbol(_) => "symbol",
        }
    }

    /// Returns whether the value is approximately truthy by JavaScript primitive rules.
    #[must_use]
    pub fn is_truthy_like(&self) -> bool {
        match self {
            Self::Undefined | Self::Null => false,
            Self::Boolean(value) => *value,
            Self::Number(value) => *value != 0.0 && !value.is_nan(),
            Self::String(value) => !value.is_empty(),
            Self::BigInt(value) => !matches!(value.as_str(), "0" | "-0"),
            Self::Symbol(_) => true,
        }
    }

    /// Returns whether the value is `null` or `undefined`.
    #[must_use]
    pub const fn is_nullish(&self) -> bool {
        matches!(self, Self::Undefined | Self::Null)
    }
}

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

    #[test]
    fn reports_type_names() {
        assert_eq!(JsPrimitiveValue::Undefined.type_name(), "undefined");
        assert_eq!(
            JsPrimitiveValue::BigInt(String::from("1")).type_name(),
            "bigint"
        );
    }

    #[test]
    fn checks_nullish_and_truthy_values() {
        assert!(JsPrimitiveValue::Null.is_nullish());
        assert!(!JsPrimitiveValue::Number(0.0).is_truthy_like());
        assert!(!JsPrimitiveValue::Number(f64::NAN).is_truthy_like());
        assert!(JsPrimitiveValue::String(String::from("x")).is_truthy_like());
        assert!(JsPrimitiveValue::Symbol(String::new()).is_truthy_like());
    }
}