Skip to main content

codama_nodes/value_nodes/
number_value_node.rs

1use crate::NumberValueNode;
2use derive_more::derive::From;
3use serde::{Deserialize, Serialize};
4use serde_json::Number as JsonNumber;
5
6impl NumberValueNode {
7    pub fn new<T>(number: T) -> Self
8    where
9        T: Into<Number>,
10    {
11        Self {
12            number: number.into(),
13        }
14    }
15}
16
17#[derive(From, Debug, PartialEq, Clone, Copy, Serialize, Deserialize)]
18#[serde(from = "JsonNumber", into = "JsonNumber")]
19pub enum Number {
20    UnsignedInteger(u64),
21    SignedInteger(i64),
22    Float(f64),
23}
24
25impl From<u8> for Number {
26    fn from(number: u8) -> Self {
27        Number::UnsignedInteger(number as u64)
28    }
29}
30
31impl From<u16> for Number {
32    fn from(number: u16) -> Self {
33        Number::UnsignedInteger(number as u64)
34    }
35}
36
37impl From<u32> for Number {
38    fn from(number: u32) -> Self {
39        Number::UnsignedInteger(number as u64)
40    }
41}
42
43impl From<i8> for Number {
44    fn from(number: i8) -> Self {
45        Number::SignedInteger(number as i64)
46    }
47}
48
49impl From<i16> for Number {
50    fn from(number: i16) -> Self {
51        Number::SignedInteger(number as i64)
52    }
53}
54
55impl From<i32> for Number {
56    fn from(number: i32) -> Self {
57        Number::SignedInteger(number as i64)
58    }
59}
60
61impl From<f32> for Number {
62    fn from(number: f32) -> Self {
63        Number::Float(number as f64)
64    }
65}
66
67impl From<JsonNumber> for Number {
68    fn from(number: JsonNumber) -> Self {
69        if number.is_u64() {
70            Number::UnsignedInteger(number.as_u64().unwrap())
71        } else if number.is_i64() {
72            Number::SignedInteger(number.as_i64().unwrap())
73        } else {
74            Number::Float(number.as_f64().unwrap())
75        }
76    }
77}
78
79impl From<Number> for JsonNumber {
80    fn from(val: Number) -> Self {
81        match val {
82            Number::UnsignedInteger(number) => JsonNumber::from(number),
83            Number::SignedInteger(number) => JsonNumber::from(number),
84            Number::Float(number) => JsonNumber::from_f64(number).unwrap(),
85        }
86    }
87}
88
89#[cfg(test)]
90mod tests {
91    use super::*;
92
93    #[test]
94    fn new() {
95        assert_eq!(NumberValueNode::new(42).number, Number::SignedInteger(42));
96        assert_eq!(
97            NumberValueNode::new(42u8).number,
98            Number::UnsignedInteger(42)
99        );
100        assert_eq!(
101            NumberValueNode::new(42u16).number,
102            Number::UnsignedInteger(42)
103        );
104        assert_eq!(
105            NumberValueNode::new(42u32).number,
106            Number::UnsignedInteger(42)
107        );
108        assert_eq!(
109            NumberValueNode::new(42u64).number,
110            Number::UnsignedInteger(42)
111        );
112        assert_eq!(
113            NumberValueNode::new(-42i8).number,
114            Number::SignedInteger(-42)
115        );
116        assert_eq!(
117            NumberValueNode::new(-42i16).number,
118            Number::SignedInteger(-42)
119        );
120        assert_eq!(
121            NumberValueNode::new(-42i32).number,
122            Number::SignedInteger(-42)
123        );
124        assert_eq!(
125            NumberValueNode::new(-42i64).number,
126            Number::SignedInteger(-42)
127        );
128        assert_eq!(NumberValueNode::new(1.5).number, Number::Float(1.5));
129        assert_eq!(NumberValueNode::new(1.5f32).number, Number::Float(1.5));
130        assert_eq!(NumberValueNode::new(1.5f64).number, Number::Float(1.5));
131    }
132
133    #[test]
134    fn to_json() {
135        let node = NumberValueNode::new(42u16);
136        let json = serde_json::to_string(&node).unwrap();
137        assert_eq!(json, r#"{"kind":"numberValueNode","number":42}"#);
138    }
139
140    #[test]
141    fn from_json() {
142        let node: NumberValueNode =
143            serde_json::from_str(r#"{"kind":"numberValueNode","number":42}"#).unwrap();
144        assert_eq!(node.number, Number::UnsignedInteger(42));
145    }
146}