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