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 ContextualValue(RegisteredContextualValueNode),
16 Count(CountNode),
17 Discriminator(DiscriminatorNode),
18 Link(LinkNode),
19 PdaSeed(PdaSeedNode),
20 Type(RegisteredTypeNode),
21 Value(RegisteredValueNode),
22
23 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}