codama_nodes/
node.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
use crate::{
    AccountNode, ContextualValueNode, CountNode, DefinedTypeNode, DiscriminatorNode, ErrorNode,
    HasKind, InstructionAccountNode, InstructionArgumentNode, InstructionByteDeltaNode,
    InstructionNode, InstructionRemainingAccountsNode, LinkNode, NodeUnionTrait, PdaNode,
    PdaSeedNode, ProgramNode, RegisteredContextualValueNode, RegisteredTypeNode,
    RegisteredValueNode, RootNode, TypeNode, ValueNode,
};
use derive_more::derive::From;
use serde::{Deserialize, Serialize};

#[derive(From, Debug, PartialEq, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Node {
    // Node unions.
    ContextualValue(RegisteredContextualValueNode),
    Count(CountNode),
    Discriminator(DiscriminatorNode),
    Link(LinkNode),
    PdaSeed(PdaSeedNode),
    Type(RegisteredTypeNode),
    Value(RegisteredValueNode),

    // Nodes.
    Account(AccountNode),
    DefinedType(DefinedTypeNode),
    Error(ErrorNode),
    Instruction(InstructionNode),
    InstructionAccount(InstructionAccountNode),
    InstructionArgument(InstructionArgumentNode),
    InstructionByteDelta(InstructionByteDeltaNode),
    InstructionRemainingAccounts(InstructionRemainingAccountsNode),
    Pda(PdaNode),
    Program(ProgramNode),
    Root(RootNode),
}

impl From<ContextualValueNode> for Node {
    fn from(node: ContextualValueNode) -> Self {
        Node::ContextualValue(node.into())
    }
}

impl From<TypeNode> for Node {
    fn from(node: TypeNode) -> Self {
        match node {
            TypeNode::Link(link) => link.into(),
            _ => Node::Type(node.try_into().unwrap()),
        }
    }
}

impl From<ValueNode> for Node {
    fn from(node: ValueNode) -> Self {
        Node::Value(node.into())
    }
}

impl NodeUnionTrait for Node {}
impl HasKind for Node {
    fn kind(&self) -> &'static str {
        match self {
            Node::ContextualValue(node) => node.kind(),
            Node::Count(node) => node.kind(),
            Node::Discriminator(node) => node.kind(),
            Node::Link(node) => node.kind(),
            Node::PdaSeed(node) => node.kind(),
            Node::Type(node) => node.kind(),
            Node::Value(node) => node.kind(),
            Node::Account(node) => node.kind(),
            Node::DefinedType(node) => node.kind(),
            Node::Error(node) => node.kind(),
            Node::Instruction(node) => node.kind(),
            Node::InstructionAccount(node) => node.kind(),
            Node::InstructionArgument(node) => node.kind(),
            Node::InstructionByteDelta(node) => node.kind(),
            Node::InstructionRemainingAccounts(node) => node.kind(),
            Node::Pda(node) => node.kind(),
            Node::Program(node) => node.kind(),
            Node::Root(node) => node.kind(),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::{NumberTypeNode, U32};

    #[test]
    fn kind() {
        let node: Node = ProgramNode::default().into();
        assert_eq!(node.kind(), "programNode");
    }

    #[test]
    fn type_node_to_json() {
        let node: Node = NumberTypeNode::le(U32).into();
        let json = serde_json::to_string(&node).unwrap();
        assert_eq!(
            json,
            r#"{"kind":"numberTypeNode","format":"u32","endian":"le"}"#
        );
    }

    #[test]
    fn type_node_from_json() {
        let json = r#"{"kind":"numberTypeNode","format":"u32","endian":"le"}"#;
        let node: Node = serde_json::from_str(json).unwrap();
        assert_eq!(
            node,
            Node::Type(RegisteredTypeNode::Number(NumberTypeNode::le(U32)))
        );
    }

    #[test]
    fn defined_type_to_json() {
        let node: Node = DefinedTypeNode::new("myType", NumberTypeNode::le(U32)).into();
        let json = serde_json::to_string(&node).unwrap();
        assert_eq!(
            json,
            r#"{"kind":"definedTypeNode","name":"myType","type":{"kind":"numberTypeNode","format":"u32","endian":"le"}}"#
        );
    }

    #[test]
    fn defined_type_from_json() {
        let json = r#"{"kind":"definedTypeNode","name":"myType","type":{"kind":"numberTypeNode","format":"u32","endian":"le"}}"#;
        let node: Node = serde_json::from_str(json).unwrap();
        assert_eq!(
            node,
            Node::DefinedType(DefinedTypeNode::new("myType", NumberTypeNode::le(U32)))
        );
    }
}