codama_nodes/type_nodes/
hidden_prefix_type_node.rs1use crate::{
2 ConstantValueNode, NestedTypeNode, NestedTypeNodeTrait, TypeNode, TypeNodeTrait,
3 TypeNodeUnionTrait,
4};
5use codama_errors::{CodamaError, CodamaResult};
6use codama_nodes_derive::nestable_type_node;
7
8#[nestable_type_node]
9pub struct HiddenPrefixTypeNode<T: TypeNodeUnionTrait> {
10 #[serde(bound = "T: TypeNodeUnionTrait")]
12 pub r#type: Box<T>,
13 pub prefix: Vec<ConstantValueNode>,
14}
15
16impl From<HiddenPrefixTypeNode<crate::TypeNode>> for crate::Node {
17 fn from(val: HiddenPrefixTypeNode<crate::TypeNode>) -> Self {
18 crate::Node::Type(val.into())
19 }
20}
21
22impl<T: TypeNodeTrait> From<HiddenPrefixTypeNode<NestedTypeNode<T>>>
23 for HiddenPrefixTypeNode<TypeNode>
24{
25 fn from(node: HiddenPrefixTypeNode<NestedTypeNode<T>>) -> Self {
26 HiddenPrefixTypeNode {
27 r#type: Box::new(TypeNode::from(*node.r#type)),
28 prefix: node.prefix,
29 }
30 }
31}
32
33impl<T: TypeNodeTrait> TryFrom<HiddenPrefixTypeNode<TypeNode>>
34 for HiddenPrefixTypeNode<NestedTypeNode<T>>
35{
36 type Error = CodamaError;
37 fn try_from(node: HiddenPrefixTypeNode<TypeNode>) -> CodamaResult<Self> {
38 Ok(HiddenPrefixTypeNode {
39 r#type: Box::new(NestedTypeNode::try_from(*node.r#type)?),
40 prefix: node.prefix,
41 })
42 }
43}
44
45impl<T: TypeNodeUnionTrait> HiddenPrefixTypeNode<T> {
46 pub fn new<U>(r#type: U, prefix: Vec<ConstantValueNode>) -> Self
47 where
48 U: Into<T>,
49 {
50 Self {
51 r#type: Box::new(r#type.into()),
52 prefix,
53 }
54 }
55}
56
57impl<T: TypeNodeTrait> NestedTypeNodeTrait<T> for HiddenPrefixTypeNode<NestedTypeNode<T>> {
58 type Mapped<U: TypeNodeTrait> = HiddenPrefixTypeNode<NestedTypeNode<U>>;
59
60 fn get_nested_type_node(&self) -> &T {
61 self.r#type.get_nested_type_node()
62 }
63
64 fn try_map_nested_type_node<U: TypeNodeTrait, F: FnOnce(T) -> CodamaResult<U>>(
65 self,
66 f: F,
67 ) -> CodamaResult<Self::Mapped<U>> {
68 Ok(HiddenPrefixTypeNode {
69 r#type: Box::new(self.r#type.try_map_nested_type_node(f)?),
70 prefix: self.prefix,
71 })
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78 use crate::{Base16, NestedTypeNode, StringTypeNode, TypeNode};
79
80 #[test]
81 fn new_type_node() {
82 let node = HiddenPrefixTypeNode::<TypeNode>::new(
83 StringTypeNode::utf8(),
84 vec![ConstantValueNode::bytes(Base16, "ffff")],
85 );
86 assert_eq!(*node.r#type, TypeNode::String(StringTypeNode::utf8()));
87 assert_eq!(node.prefix, vec![ConstantValueNode::bytes(Base16, "ffff")]);
88 }
89
90 #[test]
91 fn new_nested_type_node() {
92 let node = HiddenPrefixTypeNode::<NestedTypeNode<StringTypeNode>>::new(
93 StringTypeNode::utf8(),
94 vec![],
95 );
96 assert_eq!(*node.r#type, NestedTypeNode::Value(StringTypeNode::utf8()));
97 assert_eq!(node.get_nested_type_node(), &StringTypeNode::utf8());
98 assert_eq!(node.prefix, vec![]);
99 }
100
101 #[test]
102 fn to_json() {
103 let node = HiddenPrefixTypeNode::<TypeNode>::new(
104 StringTypeNode::utf8(),
105 vec![ConstantValueNode::bytes(Base16, "ffff")],
106 );
107 let json = serde_json::to_string(&node).unwrap();
108 assert_eq!(
109 json,
110 r#"{"kind":"hiddenPrefixTypeNode","type":{"kind":"stringTypeNode","encoding":"utf8"},"prefix":[{"kind":"constantValueNode","type":{"kind":"bytesTypeNode"},"value":{"kind":"bytesValueNode","data":"ffff","encoding":"base16"}}]}"#
111 );
112 }
113
114 #[test]
115 fn from_json() {
116 let json = r#"{"kind":"hiddenPrefixTypeNode","type":{"kind":"stringTypeNode","encoding":"utf8"},"prefix":[{"kind":"constantValueNode","type":{"kind":"bytesTypeNode"},"value":{"kind":"bytesValueNode","data":"ffff","encoding":"base16"}}]}"#;
117 let node: HiddenPrefixTypeNode<TypeNode> = serde_json::from_str(json).unwrap();
118 assert_eq!(
119 node,
120 HiddenPrefixTypeNode::<TypeNode>::new(
121 StringTypeNode::utf8(),
122 vec![ConstantValueNode::bytes(Base16, "ffff")],
123 )
124 );
125 }
126}