codama_nodes/
instruction_argument_node.rs1use crate::{
2 CamelCaseString, DefaultValueStrategy, Docs, InstructionInputValueNode, StructFieldTypeNode,
3 StructTypeNode, TypeNode,
4};
5use codama_nodes_derive::node;
6
7#[node]
8pub struct InstructionArgumentNode {
9 pub name: CamelCaseString,
11 #[serde(skip_serializing_if = "crate::is_default")]
12 pub default_value_strategy: Option<DefaultValueStrategy>,
13 #[serde(default, skip_serializing_if = "crate::is_default")]
14 pub docs: Docs,
15
16 pub r#type: TypeNode,
18 #[serde(skip_serializing_if = "crate::is_default")]
19 pub default_value: Option<InstructionInputValueNode>,
20}
21
22impl InstructionArgumentNode {
23 pub fn new<T, U>(name: T, r#type: U) -> Self
24 where
25 T: Into<CamelCaseString>,
26 U: Into<TypeNode>,
27 {
28 Self {
29 name: name.into(),
30 default_value_strategy: None,
31 docs: Docs::default(),
32 r#type: r#type.into(),
33 default_value: None,
34 }
35 }
36}
37
38impl From<StructFieldTypeNode> for InstructionArgumentNode {
39 fn from(value: StructFieldTypeNode) -> Self {
40 Self {
41 name: value.name,
42 default_value_strategy: value.default_value_strategy,
43 docs: value.docs,
44 r#type: value.r#type,
45 default_value: value.default_value.map(InstructionInputValueNode::from),
46 }
47 }
48}
49
50impl From<StructTypeNode> for Vec<InstructionArgumentNode> {
51 fn from(val: StructTypeNode) -> Self {
52 val.fields
53 .into_iter()
54 .map(InstructionArgumentNode::from)
55 .collect()
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62 use crate::{ArgumentValueNode, NumberTypeNode, U32};
63
64 #[test]
65 fn new() {
66 let node = InstructionArgumentNode::new("my_argument", NumberTypeNode::le(U32));
67 assert_eq!(node.name, CamelCaseString::new("myArgument"));
68 assert_eq!(node.r#type, TypeNode::Number(NumberTypeNode::le(U32)));
69 }
70
71 #[test]
72 fn direct_instantiation() {
73 let node = InstructionArgumentNode {
74 name: "myArgument".into(),
75 default_value_strategy: Some(DefaultValueStrategy::Optional),
76 docs: vec!["Hello".to_string()].into(),
77 r#type: NumberTypeNode::le(U32).into(),
78 default_value: Some(ArgumentValueNode::new("myOtherArgument").into()),
79 };
80
81 assert_eq!(node.name, CamelCaseString::new("myArgument"));
82 assert_eq!(
83 node.default_value_strategy,
84 Some(DefaultValueStrategy::Optional)
85 );
86 assert_eq!(*node.docs, vec!["Hello".to_string()]);
87 assert_eq!(node.r#type, TypeNode::Number(NumberTypeNode::le(U32)));
88 assert_eq!(
89 node.default_value,
90 Some(InstructionInputValueNode::Argument(ArgumentValueNode::new(
91 "myOtherArgument"
92 )))
93 );
94 }
95
96 #[test]
97 fn to_json() {
98 let node = InstructionArgumentNode::new("myArgument", NumberTypeNode::le(U32));
99 let json = serde_json::to_string(&node).unwrap();
100 assert_eq!(
101 json,
102 r#"{"kind":"instructionArgumentNode","name":"myArgument","type":{"kind":"numberTypeNode","format":"u32","endian":"le"}}"#
103 );
104 }
105
106 #[test]
107 fn from_json() {
108 let json = r#"{"kind":"instructionArgumentNode","name":"myArgument","type":{"kind":"numberTypeNode","format":"u32","endian":"le"}}"#;
109 let node: InstructionArgumentNode = serde_json::from_str(json).unwrap();
110 assert_eq!(
111 node,
112 InstructionArgumentNode::new("myArgument", NumberTypeNode::le(U32))
113 );
114 }
115}