1use crate::{
2 CamelCaseString, DiscriminatorNode, Docs, HasName, NestedTypeNode, PdaLinkNode, StructTypeNode,
3};
4use codama_nodes_derive::node;
5
6#[node]
7pub struct AccountNode {
8 pub name: CamelCaseString,
10 #[serde(skip_serializing_if = "crate::is_default")]
11 pub size: Option<usize>,
12 #[serde(default, skip_serializing_if = "crate::is_default")]
13 pub docs: Docs,
14
15 pub data: NestedTypeNode<StructTypeNode>,
17 #[serde(skip_serializing_if = "crate::is_default")]
18 pub pda: Option<PdaLinkNode>,
19 #[serde(default, skip_serializing_if = "crate::is_default")]
20 pub discriminators: Vec<DiscriminatorNode>,
21}
22
23impl AccountNode {
24 pub fn new<T, U>(name: T, data: U) -> Self
25 where
26 T: Into<CamelCaseString>,
27 U: Into<NestedTypeNode<StructTypeNode>>,
28 {
29 Self {
30 name: name.into(),
31 size: None,
32 docs: Docs::default(),
33 data: data.into(),
34 pda: None,
35 discriminators: vec![],
36 }
37 }
38}
39
40impl HasName for AccountNode {
41 fn name(&self) -> &CamelCaseString {
42 &self.name
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49 use crate::{NumberTypeNode, StringTypeNode, StructFieldTypeNode, U8};
50
51 #[test]
52 fn new() {
53 let node = AccountNode::new(
54 "myAccount",
55 StructTypeNode::new(vec![
56 StructFieldTypeNode::new("name", StringTypeNode::utf8()),
57 StructFieldTypeNode::new("age", NumberTypeNode::le(U8)),
58 ]),
59 );
60 assert_eq!(node.name, CamelCaseString::new("myAccount"));
61 assert_eq!(node.size, None);
62 assert_eq!(node.docs, Docs::default());
63 assert_eq!(
64 node.data,
65 NestedTypeNode::Value(StructTypeNode::new(vec![
66 StructFieldTypeNode::new("name", StringTypeNode::utf8()),
67 StructFieldTypeNode::new("age", NumberTypeNode::le(U8)),
68 ]))
69 );
70 assert_eq!(node.pda, None);
71 assert_eq!(node.discriminators, vec![]);
72 }
73
74 #[test]
75 fn direct_instantiation() {
76 let node = AccountNode {
77 name: "myAccount".into(),
78 size: None,
79 docs: Docs::default(),
80 data: StructTypeNode::new(vec![
81 StructFieldTypeNode::new("name", StringTypeNode::utf8()),
82 StructFieldTypeNode::new("age", NumberTypeNode::le(U8)),
83 ])
84 .into(),
85 pda: None,
86 discriminators: vec![],
87 };
88 assert_eq!(node.name, CamelCaseString::new("myAccount"));
89 assert_eq!(node.size, None);
90 assert_eq!(node.docs, Docs::default());
91 assert_eq!(
92 node.data,
93 NestedTypeNode::Value(StructTypeNode::new(vec![
94 StructFieldTypeNode::new("name", StringTypeNode::utf8()),
95 StructFieldTypeNode::new("age", NumberTypeNode::le(U8)),
96 ]))
97 );
98 assert_eq!(node.pda, None);
99 assert_eq!(node.discriminators, vec![]);
100 }
101
102 #[test]
103 fn to_json() {
104 let node = AccountNode::new(
105 "myAccount",
106 StructTypeNode::new(vec![
107 StructFieldTypeNode::new("name", StringTypeNode::utf8()),
108 StructFieldTypeNode::new("age", NumberTypeNode::le(U8)),
109 ]),
110 );
111 let json = serde_json::to_string(&node).unwrap();
112 assert_eq!(
113 json,
114 r#"{"kind":"accountNode","name":"myAccount","data":{"kind":"structTypeNode","fields":[{"kind":"structFieldTypeNode","name":"name","type":{"kind":"stringTypeNode","encoding":"utf8"}},{"kind":"structFieldTypeNode","name":"age","type":{"kind":"numberTypeNode","format":"u8","endian":"le"}}]}}"#
115 );
116 }
117
118 #[test]
119 fn from_json() {
120 let json = r#"{"kind":"accountNode","name":"myAccount","data":{"kind":"structTypeNode","fields":[{"kind":"structFieldTypeNode","name":"name","type":{"kind":"stringTypeNode","encoding":"utf8"}},{"kind":"structFieldTypeNode","name":"age","type":{"kind":"numberTypeNode","format":"u8","endian":"le"}}]}}"#;
121 let node: AccountNode = serde_json::from_str(json).unwrap();
122 assert_eq!(
123 node,
124 AccountNode::new(
125 "myAccount",
126 StructTypeNode::new(vec![
127 StructFieldTypeNode::new("name", StringTypeNode::utf8()),
128 StructFieldTypeNode::new("age", NumberTypeNode::le(U8)),
129 ]),
130 )
131 );
132 }
133}