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
84#[cfg(test)]
85mod tests {
86    use super::*;
87    use crate::{NumberTypeNode, U32};
88
89    #[test]
90    fn kind() {
91        let node: Node = ProgramNode::default().into();
92        assert_eq!(node.kind(), "programNode");
93    }
94
95    #[test]
96    fn type_node_to_json() {
97        let node: Node = NumberTypeNode::le(U32).into();
98        let json = serde_json::to_string(&node).unwrap();
99        assert_eq!(
100            json,
101            r#"{"kind":"numberTypeNode","format":"u32","endian":"le"}"#
102        );
103    }
104
105    #[test]
106    fn type_node_from_json() {
107        let json = r#"{"kind":"numberTypeNode","format":"u32","endian":"le"}"#;
108        let node: Node = serde_json::from_str(json).unwrap();
109        assert_eq!(
110            node,
111            Node::Type(RegisteredTypeNode::Number(NumberTypeNode::le(U32)))
112        );
113    }
114
115    #[test]
116    fn defined_type_to_json() {
117        let node: Node = DefinedTypeNode::new("myType", NumberTypeNode::le(U32)).into();
118        let json = serde_json::to_string(&node).unwrap();
119        assert_eq!(
120            json,
121            r#"{"kind":"definedTypeNode","name":"myType","type":{"kind":"numberTypeNode","format":"u32","endian":"le"}}"#
122        );
123    }
124
125    #[test]
126    fn defined_type_from_json() {
127        let json = r#"{"kind":"definedTypeNode","name":"myType","type":{"kind":"numberTypeNode","format":"u32","endian":"le"}}"#;
128        let node: Node = serde_json::from_str(json).unwrap();
129        assert_eq!(
130            node,
131            Node::DefinedType(DefinedTypeNode::new("myType", NumberTypeNode::le(U32)))
132        );
133    }
134}