codama_nodes/
root_node.rs

1use crate::ProgramNode;
2use codama_nodes_derive::node;
3
4#[node]
5pub struct RootNode {
6    // Data.
7    standard: String,
8    pub version: String,
9
10    // Children.
11    pub program: ProgramNode,
12    pub additional_programs: Vec<ProgramNode>,
13}
14
15impl Default for RootNode {
16    fn default() -> Self {
17        Self {
18            standard: "codama".into(),
19            version: "1.0.0".into(), // TODO: Get this from Cargo.toml.
20            program: Default::default(),
21            additional_programs: Default::default(),
22        }
23    }
24}
25
26impl RootNode {
27    pub fn new(program: ProgramNode) -> Self {
28        Self {
29            program,
30            ..Self::default()
31        }
32    }
33
34    pub fn add_program(mut self, program: ProgramNode) -> Self {
35        self.additional_programs.push(program);
36        self
37    }
38}
39
40impl From<ProgramNode> for RootNode {
41    fn from(program: ProgramNode) -> Self {
42        Self::new(program)
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use super::*;
49
50    #[test]
51    fn new() {
52        let node = RootNode::new(ProgramNode {
53            name: "myProgram".into(),
54            ..ProgramNode::default()
55        });
56        assert_eq!(
57            node.program,
58            ProgramNode {
59                name: "myProgram".into(),
60                ..ProgramNode::default()
61            }
62        );
63        assert_eq!(node.additional_programs, vec![]);
64    }
65
66    #[test]
67    fn from_program() {
68        let node: RootNode = ProgramNode {
69            name: "myProgram".into(),
70            ..ProgramNode::default()
71        }
72        .into();
73        assert_eq!(
74            node.program,
75            ProgramNode {
76                name: "myProgram".into(),
77                ..ProgramNode::default()
78            }
79        );
80        assert_eq!(node.additional_programs, vec![]);
81    }
82
83    #[test]
84    fn direct_instantiation() {
85        let node = RootNode {
86            standard: "codama".into(),
87            version: "1.0.0".into(),
88            program: ProgramNode::new("myProgram", "1111"),
89            additional_programs: vec![
90                ProgramNode::new("myProgramDependencyA", "2222"),
91                ProgramNode::new("myProgramDependencyB", "3333"),
92            ],
93        };
94        assert_eq!(node.program, ProgramNode::new("myProgram", "1111"));
95        assert_eq!(
96            node.additional_programs,
97            vec![
98                ProgramNode::new("myProgramDependencyA", "2222"),
99                ProgramNode::new("myProgramDependencyB", "3333"),
100            ]
101        );
102    }
103
104    #[test]
105    fn to_json() {
106        let node = RootNode::new(ProgramNode {
107            name: "myProgram".into(),
108            public_key: "1234..5678".into(),
109            version: "1.2.3".into(),
110            ..ProgramNode::default()
111        });
112        let json = serde_json::to_string(&node).unwrap();
113        assert_eq!(
114            json,
115            r#"{"kind":"rootNode","standard":"codama","version":"1.0.0","program":{"kind":"programNode","name":"myProgram","publicKey":"1234..5678","version":"1.2.3","accounts":[],"instructions":[]},"additionalPrograms":[]}"#
116        );
117    }
118
119    #[test]
120    fn from_json() {
121        let json = r#"{"kind":"rootNode","standard":"codama","version":"1.0.0","program":{"kind":"programNode","name":"myProgram","publicKey":"1234..5678","version":"1.2.3","accounts":[],"instructions":[]},"additionalPrograms":[]}"#;
122        let node: RootNode = serde_json::from_str(json).unwrap();
123        assert_eq!(
124            node,
125            RootNode::new(ProgramNode {
126                name: "myProgram".into(),
127                public_key: "1234..5678".into(),
128                version: "1.2.3".into(),
129                ..ProgramNode::default()
130            })
131        );
132    }
133}