1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4#[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 #[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 #[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 #[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}