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