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 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 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}