codama_nodes/value_nodes/
number_value_node.rs1use 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}