Skip to main content

codama_nodes/
node.rs

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