codama_nodes/contextual_value_nodes/
conditional_value_node.rs

1use crate::{
2    AccountValueNode, ArgumentValueNode, InstructionInputValueNode, ResolverValueNode, ValueNode,
3};
4use codama_nodes_derive::{node, node_union};
5
6#[node]
7pub struct ConditionalValueNode {
8    // Children.
9    pub condition: ConditionNode,
10    #[serde(skip_serializing_if = "crate::is_default")]
11    pub value: Option<ValueNode>,
12    #[serde(skip_serializing_if = "crate::is_default")]
13    pub if_true: Box<Option<InstructionInputValueNode>>,
14    #[serde(skip_serializing_if = "crate::is_default")]
15    pub if_false: Box<Option<InstructionInputValueNode>>,
16}
17
18impl From<ConditionalValueNode> for crate::Node {
19    fn from(val: ConditionalValueNode) -> Self {
20        crate::Node::ContextualValue(val.into())
21    }
22}
23
24#[node_union]
25pub enum ConditionNode {
26    Account(AccountValueNode),
27    Argument(ArgumentValueNode),
28    Resolver(ResolverValueNode),
29}
30
31#[cfg(test)]
32mod tests {
33    use crate::NumberValueNode;
34
35    use super::*;
36
37    #[test]
38    fn direct_instantiation() {
39        let node = ConditionalValueNode {
40            condition: ArgumentValueNode::new("myArgument").into(),
41            value: Some(NumberValueNode::new(42).into()),
42            if_true: Box::new(Some(AccountValueNode::new("myOtherAccount").into())),
43            if_false: Box::new(None),
44        };
45        assert_eq!(
46            node.condition,
47            ConditionNode::Argument(ArgumentValueNode::new("myArgument"))
48        );
49        assert_eq!(
50            node.value,
51            Some(ValueNode::Number(NumberValueNode::new(42)))
52        );
53        assert_eq!(
54            *node.if_true,
55            Some(InstructionInputValueNode::Account(AccountValueNode::new(
56                "myOtherAccount"
57            )))
58        );
59        assert_eq!(*node.if_false, None);
60    }
61
62    #[test]
63    fn to_json() {
64        let node = ConditionalValueNode {
65            condition: ArgumentValueNode::new("myArgument").into(),
66            value: Some(NumberValueNode::new(42).into()),
67            if_true: Box::new(Some(AccountValueNode::new("myOtherAccount").into())),
68            if_false: Box::new(None),
69        };
70        let json = serde_json::to_string(&node).unwrap();
71        assert_eq!(
72            json,
73            r#"{"kind":"conditionalValueNode","condition":{"kind":"argumentValueNode","name":"myArgument"},"value":{"kind":"numberValueNode","number":42},"ifTrue":{"kind":"accountValueNode","name":"myOtherAccount"}}"#
74        );
75    }
76
77    #[test]
78    fn from_json() {
79        let json = r#"{"kind":"conditionalValueNode","condition":{"kind":"argumentValueNode","name":"myArgument"},"value":{"kind":"numberValueNode","number":42},"ifTrue":{"kind":"accountValueNode","name":"myOtherAccount"}}"#;
80        let node: ConditionalValueNode = serde_json::from_str(json).unwrap();
81        assert_eq!(
82            node,
83            ConditionalValueNode {
84                condition: ArgumentValueNode::new("myArgument").into(),
85                value: Some(NumberValueNode::new(42u32).into()),
86                if_true: Box::new(Some(AccountValueNode::new("myOtherAccount").into())),
87                if_false: Box::new(None),
88            }
89        );
90    }
91}