codama_nodes/type_nodes/
hidden_prefix_type_node.rs

1use 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    // Children.
11    #[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}