multiversx_sc/abi/
type_description_container.rs

1use super::*;
2use alloc::borrow::ToOwned;
3use multiversx_sc_codec::Vec;
4
5pub trait TypeDescriptionContainer {
6    fn new() -> Self;
7
8    fn contains_type(&self, type_name: &str) -> bool;
9
10    // A placeholder gets inserted while computing field descriptions for a type,
11    // to avoid an infinite loop for recursive types (if the same type appears again lower in the tree).
12    fn reserve_type_name(&mut self, type_names: TypeNames) {
13        self.insert(type_names, TypeDescription::PLACEHOLDER);
14    }
15
16    fn insert(&mut self, type_names: TypeNames, type_description: TypeDescription);
17
18    fn insert_all(&mut self, other: &Self);
19}
20
21#[derive(Clone, Default, Debug)]
22pub struct TypeDescriptionContainerImpl(pub Vec<(TypeNames, TypeDescription)>);
23
24impl TypeDescriptionContainerImpl {
25    pub fn find(&self, abi_type_name: &str) -> Option<&TypeDescription> {
26        self.0
27            .iter()
28            .find(|(existing_type_name, _)| existing_type_name.abi == abi_type_name)
29            .map(|(_, description)| description)
30    }
31
32    pub fn find_or_default(&self, abi_type_name: &str) -> TypeDescription {
33        if let Some(type_description) = self.find(abi_type_name) {
34            type_description.clone()
35        } else {
36            TypeDescription {
37                docs: Vec::new(),
38                names: TypeNames::from_abi(abi_type_name.to_owned()),
39                contents: TypeContents::NotSpecified,
40                macro_attributes: Vec::new(),
41            }
42        }
43    }
44}
45
46impl TypeDescriptionContainer for TypeDescriptionContainerImpl {
47    fn new() -> Self {
48        TypeDescriptionContainerImpl(Vec::new())
49    }
50
51    fn contains_type(&self, type_name: &str) -> bool {
52        self.0
53            .iter()
54            .any(|(existing_type_name, _)| existing_type_name.abi == type_name)
55    }
56
57    fn insert(&mut self, type_names: TypeNames, type_description: TypeDescription) {
58        if let Some((_existing_type_name, existing_type_description)) = self
59            .0
60            .iter_mut()
61            .find(|(name, _)| name.abi == type_names.abi)
62        {
63            *existing_type_description = type_description;
64        } else {
65            self.0.push((type_names, type_description));
66        }
67    }
68
69    fn insert_all(&mut self, other: &Self) {
70        for (key, value) in other.0.iter() {
71            self.insert(key.clone(), value.clone());
72        }
73    }
74}