Skip to main content

use_js_value/
lib.rs

1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4/// Primitive JavaScript-like values for metadata and validation helpers.
5#[derive(Clone, Debug, PartialEq)]
6pub enum JsPrimitiveValue {
7    Undefined,
8    Null,
9    Boolean(bool),
10    Number(f64),
11    String(String),
12    BigInt(String),
13    Symbol(String),
14}
15
16impl JsPrimitiveValue {
17    /// Returns a JavaScript-style primitive type label.
18    #[must_use]
19    pub const fn type_name(&self) -> &'static str {
20        match self {
21            Self::Undefined => "undefined",
22            Self::Null => "null",
23            Self::Boolean(_) => "boolean",
24            Self::Number(_) => "number",
25            Self::String(_) => "string",
26            Self::BigInt(_) => "bigint",
27            Self::Symbol(_) => "symbol",
28        }
29    }
30
31    /// Returns whether the value is approximately truthy by JavaScript primitive rules.
32    #[must_use]
33    pub fn is_truthy_like(&self) -> bool {
34        match self {
35            Self::Undefined | Self::Null => false,
36            Self::Boolean(value) => *value,
37            Self::Number(value) => *value != 0.0 && !value.is_nan(),
38            Self::String(value) => !value.is_empty(),
39            Self::BigInt(value) => !matches!(value.as_str(), "0" | "-0"),
40            Self::Symbol(_) => true,
41        }
42    }
43
44    /// Returns whether the value is `null` or `undefined`.
45    #[must_use]
46    pub const fn is_nullish(&self) -> bool {
47        matches!(self, Self::Undefined | Self::Null)
48    }
49}
50
51#[cfg(test)]
52mod tests {
53    use super::JsPrimitiveValue;
54
55    #[test]
56    fn reports_type_names() {
57        assert_eq!(JsPrimitiveValue::Undefined.type_name(), "undefined");
58        assert_eq!(
59            JsPrimitiveValue::BigInt(String::from("1")).type_name(),
60            "bigint"
61        );
62    }
63
64    #[test]
65    fn checks_nullish_and_truthy_values() {
66        assert!(JsPrimitiveValue::Null.is_nullish());
67        assert!(!JsPrimitiveValue::Number(0.0).is_truthy_like());
68        assert!(!JsPrimitiveValue::Number(f64::NAN).is_truthy_like());
69        assert!(JsPrimitiveValue::String(String::from("x")).is_truthy_like());
70        assert!(JsPrimitiveValue::Symbol(String::new()).is_truthy_like());
71    }
72}