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
84#[cfg(test)]
85mod tests {
86 use super::*;
87 use crate::{NumberTypeNode, U32};
88
89 #[test]
90 fn kind() {
91 let node: Node = ProgramNode::default().into();
92 assert_eq!(node.kind(), "programNode");
93 }
94
95 #[test]
96 fn type_node_to_json() {
97 let node: Node = NumberTypeNode::le(U32).into();
98 let json = serde_json::to_string(&node).unwrap();
99 assert_eq!(
100 json,
101 r#"{"kind":"numberTypeNode","format":"u32","endian":"le"}"#
102 );
103 }
104
105 #[test]
106 fn type_node_from_json() {
107 let json = r#"{"kind":"numberTypeNode","format":"u32","endian":"le"}"#;
108 let node: Node = serde_json::from_str(json).unwrap();
109 assert_eq!(
110 node,
111 Node::Type(RegisteredTypeNode::Number(NumberTypeNode::le(U32)))
112 );
113 }
114
115 #[test]
116 fn defined_type_to_json() {
117 let node: Node = DefinedTypeNode::new("myType", NumberTypeNode::le(U32)).into();
118 let json = serde_json::to_string(&node).unwrap();
119 assert_eq!(
120 json,
121 r#"{"kind":"definedTypeNode","name":"myType","type":{"kind":"numberTypeNode","format":"u32","endian":"le"}}"#
122 );
123 }
124
125 #[test]
126 fn defined_type_from_json() {
127 let json = r#"{"kind":"definedTypeNode","name":"myType","type":{"kind":"numberTypeNode","format":"u32","endian":"le"}}"#;
128 let node: Node = serde_json::from_str(json).unwrap();
129 assert_eq!(
130 node,
131 Node::DefinedType(DefinedTypeNode::new("myType", NumberTypeNode::le(U32)))
132 );
133 }
134}