codama_nodes/
node.rs

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