codama_nodes/type_nodes/
number_type_node.rs1use codama_errors::{CodamaError, CodamaResult};
2use codama_nodes_derive::type_node;
3use serde::{Deserialize, Serialize};
4
5pub use NumberFormat::*;
6
7#[type_node]
8pub struct NumberTypeNode {
9 pub format: NumberFormat,
11 pub endian: Endian,
12}
13
14impl From<NumberTypeNode> for crate::Node {
15 fn from(val: NumberTypeNode) -> Self {
16 crate::Node::Type(val.into())
17 }
18}
19
20impl NumberTypeNode {
21 pub fn new(format: NumberFormat, endian: Endian) -> Self {
22 Self { format, endian }
23 }
24
25 pub fn le(format: NumberFormat) -> Self {
26 Self::new(format, Endian::Little)
27 }
28
29 pub fn be(format: NumberFormat) -> Self {
30 Self::new(format, Endian::Big)
31 }
32}
33
34#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
35#[serde(rename_all = "camelCase")]
36pub enum NumberFormat {
37 U8,
38 U16,
39 U32,
40 U64,
41 U128,
42 I8,
43 I16,
44 I32,
45 I64,
46 I128,
47 F32,
48 F64,
49 ShortU16,
50}
51
52impl TryFrom<String> for NumberFormat {
53 type Error = CodamaError;
54
55 fn try_from(value: String) -> CodamaResult<Self> {
56 value.as_str().try_into()
57 }
58}
59
60impl TryFrom<&str> for NumberFormat {
61 type Error = CodamaError;
62
63 fn try_from(value: &str) -> CodamaResult<Self> {
64 match value {
65 "u8" => Ok(U8),
66 "u16" => Ok(U16),
67 "u32" => Ok(U32),
68 "u64" => Ok(U64),
69 "u128" => Ok(U128),
70 "i8" => Ok(I8),
71 "i16" => Ok(I16),
72 "i32" => Ok(I32),
73 "i64" => Ok(I64),
74 "i128" => Ok(I128),
75 "f32" => Ok(F32),
76 "f64" => Ok(F64),
77 "short_u16" => Ok(ShortU16),
78 _ => Err(CodamaError::InvalidNumberFormat(value.to_string())),
79 }
80 }
81}
82
83#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
84pub enum Endian {
85 #[serde(rename = "be")]
86 Big,
87 #[serde(rename = "le")]
88 Little,
89}
90
91impl TryFrom<String> for Endian {
92 type Error = CodamaError;
93
94 fn try_from(value: String) -> CodamaResult<Self> {
95 value.as_str().try_into()
96 }
97}
98
99impl TryFrom<&str> for Endian {
100 type Error = CodamaError;
101
102 fn try_from(value: &str) -> CodamaResult<Self> {
103 match value {
104 "be" | "big" => Ok(Endian::Big),
105 "le" | "little" => Ok(Endian::Little),
106 _ => Err(CodamaError::InvalidEndian(value.to_string())),
107 }
108 }
109}
110
111#[cfg(test)]
112mod tests {
113 use super::*;
114
115 #[test]
116 fn new() {
117 let node = NumberTypeNode::new(U8, Endian::Big);
118 assert_eq!(node.format, NumberFormat::U8);
119 assert_eq!(node.endian, Endian::Big);
120 }
121
122 #[test]
123 fn le() {
124 let node = NumberTypeNode::le(U32);
125 assert_eq!(node.format, NumberFormat::U32);
126 assert_eq!(node.endian, Endian::Little);
127 }
128
129 #[test]
130 fn be() {
131 let node = NumberTypeNode::be(U32);
132 assert_eq!(node.format, NumberFormat::U32);
133 assert_eq!(node.endian, Endian::Big);
134 }
135
136 #[test]
137 fn to_json() {
138 let node = NumberTypeNode::be(U8);
139 let json = serde_json::to_string(&node).unwrap();
140 assert_eq!(
141 json,
142 r#"{"kind":"numberTypeNode","format":"u8","endian":"be"}"#
143 );
144 }
145
146 #[test]
147 fn from_json() {
148 let json = r#"{"kind":"numberTypeNode","format":"u8","endian":"be"}"#;
149 let node: NumberTypeNode = serde_json::from_str(json).unwrap();
150 assert_eq!(node, NumberTypeNode::be(U8));
151 }
152}