codama_nodes/
node.rs

1use crate::{
2    AccountNode, ContextualValueNode, CountNode, DefinedTypeNode, DiscriminatorNode, ErrorNode,
3    HasKind, InstructionAccountNode, InstructionArgumentNode, InstructionByteDeltaNode,
4    InstructionNode, InstructionRemainingAccountsNode, LinkNode, NodeUnionTrait, PdaNode,
5    PdaSeedNode, ProgramNode, RegisteredContextualValueNode, RegisteredTypeNode,
6    RegisteredValueNode, RootNode, TypeNode, ValueNode,
7};
8use derive_more::derive::From;
9use serde::{Deserialize, Serialize};
10
11#[derive(From, Debug, PartialEq, Clone, Serialize, Deserialize)]
12#[serde(untagged)]
13pub enum Node {
14    // Node unions.
15    ContextualValue(RegisteredContextualValueNode),
16    Count(CountNode),
17    Discriminator(DiscriminatorNode),
18    Link(LinkNode),
19    PdaSeed(PdaSeedNode),
20    Type(RegisteredTypeNode),
21    Value(RegisteredValueNode),
22
23    // Nodes.
24    Account(AccountNode),
25    DefinedType(DefinedTypeNode),
26    Error(ErrorNode),
27    Instruction(InstructionNode),
28    InstructionAccount(InstructionAccountNode),
29    InstructionArgument(InstructionArgumentNode),
30    InstructionByteDelta(InstructionByteDeltaNode),
31    InstructionRemainingAccounts(InstructionRemainingAccountsNode),
32    Pda(PdaNode),
33    Program(ProgramNode),
34    Root(RootNode),
35}
36
37impl From<ContextualValueNode> for Node {
38    fn from(node: ContextualValueNode) -> Self {
39        Node::ContextualValue(node.into())
40    }
41}
42
43impl From<TypeNode> for Node {
44    fn from(node: TypeNode) -> Self {
45        match node {
46            TypeNode::Link(link) => link.into(),
47            _ => Node::Type(node.try_into().unwrap()),
48        }
49    }
50}
51
52impl From<ValueNode> for Node {
53    fn from(node: ValueNode) -> Self {
54        Node::Value(node.into())
55    }
56}
57
58impl NodeUnionTrait for Node {}
59impl HasKind for Node {
60    fn kind(&self) -> &'static str {
61        match self {
62            Node::ContextualValue(node) => node.kind(),
63            Node::Count(node) => node.kind(),
64            Node::Discriminator(node) => node.kind(),
65            Node::Link(node) => node.kind(),
66            Node::PdaSeed(node) => node.kind(),
67            Node::Type(node) => node.kind(),
68            Node::Value(node) => node.kind(),
69            Node::Account(node) => node.kind(),
70            Node::DefinedType(node) => node.kind(),
71            Node::Error(node) => node.kind(),
72            Node::Instruction(node) => node.kind(),
73            Node::InstructionAccount(node) => node.kind(),
74            Node::InstructionArgument(node) => node.kind(),
75            Node::InstructionByteDelta(node) => node.kind(),
76            Node::InstructionRemainingAccounts(node) => node.kind(),
77            Node::Pda(node) => node.kind(),
78            Node::Program(node) => node.kind(),
79            Node::Root(node) => node.kind(),
80        }
81    }
82}
83
84impl HasKind for Option<Node> {
85    fn kind(&self) -> &'static str {
86        match self {
87            Some(node) => node.kind(),
88            None => "None",
89        }
90    }
91}
92
93#[cfg(test)]
94mod tests {
95    use super::*;
96    use crate::{NumberTypeNode, U32};
97
98    #[test]
99    fn kind() {
100        let node: Node = ProgramNode::default().into();
101        assert_eq!(node.kind(), "programNode");
102    }
103
104    #[test]
105    fn type_node_to_json() {
106        let node: Node = NumberTypeNode::le(U32).into();
107        let json = serde_json::to_string(&node).unwrap();
108        assert_eq!(
109            json,
110            r#"{"kind":"numberTypeNode","format":"u32","endian":"le"}"#
111        );
112    }
113
114    #[test]
115    fn type_node_from_json() {
116        let json = r#"{"kind":"numberTypeNode","format":"u32","endian":"le"}"#;
117        let node: Node = serde_json::from_str(json).unwrap();
118        assert_eq!(
119            node,
120            Node::Type(RegisteredTypeNode::Number(NumberTypeNode::le(U32)))
121        );
122    }
123
124    #[test]
125    fn defined_type_to_json() {
126        let node: Node = DefinedTypeNode::new("myType", NumberTypeNode::le(U32)).into();
127        let json = serde_json::to_string(&node).unwrap();
128        assert_eq!(
129            json,
130            r#"{"kind":"definedTypeNode","name":"myType","type":{"kind":"numberTypeNode","format":"u32","endian":"le"}}"#
131        );
132    }
133
134    #[test]
135    fn defined_type_from_json() {
136        let json = r#"{"kind":"definedTypeNode","name":"myType","type":{"kind":"numberTypeNode","format":"u32","endian":"le"}}"#;
137        let node: Node = serde_json::from_str(json).unwrap();
138        assert_eq!(
139            node,
140            Node::DefinedType(DefinedTypeNode::new("myType", NumberTypeNode::le(U32)))
141        );
142    }
143}