tf_bindgen/codegen/
type_info.rs

1use heck::ToUpperCamelCase;
2use tf_bindgen_schema::provider::v1_0::BlockType;
3
4use super::path::Path;
5
6#[derive(Debug, Clone)]
7pub enum Wrapper {
8    List,
9    Map,
10    Type,
11    Set,
12}
13
14#[derive(Debug, Clone)]
15pub struct TypeInfo {
16    wrapper: Wrapper,
17    name: String,
18}
19
20impl TypeInfo {
21    pub fn from_schema(path: &Path, name: &str, schema: &BlockType) -> Self {
22        let composed_type = path.type_name() + &name.to_upper_camel_case();
23        let type_name = match schema {
24            BlockType::Set(inner) | BlockType::Map(inner) | BlockType::List(inner) => match **inner
25            {
26                BlockType::Set(_) | BlockType::Map(_) | BlockType::List(_) => {
27                    unimplemented!("double nested types are not supported")
28                }
29                BlockType::Object(_) => &composed_type,
30                _ => base_type_to_string(inner),
31            },
32            BlockType::Object(_) => &composed_type,
33            _ => base_type_to_string(schema),
34        };
35        let wrapper = match schema {
36            BlockType::Set(_) => Wrapper::Set,
37            BlockType::Map(_) => Wrapper::Map,
38            BlockType::List(_) => Wrapper::List,
39            _ => Wrapper::Type,
40        };
41        Self {
42            wrapper,
43            name: type_name.to_string(),
44        }
45    }
46
47    pub fn new(wrapper: Wrapper, name: impl Into<String>) -> Self {
48        Self {
49            wrapper,
50            name: name.into(),
51        }
52    }
53
54    pub fn wrapper(&self) -> &Wrapper {
55        &self.wrapper
56    }
57
58    /// Returns the unwrapped type.
59    pub fn type_name(&self) -> &str {
60        &self.name
61    }
62
63    /// Returns the composed type.
64    pub fn source(&self) -> String {
65        let type_name = &self.name;
66        let type_name = format!("::tf_bindgen::Value<{type_name}>");
67        match self.wrapper {
68            Wrapper::List => format!("::std::vec::Vec<{type_name}>"),
69            Wrapper::Map => {
70                format!("::std::collections::HashMap<::std::string::String, {type_name}>")
71            }
72            Wrapper::Type => type_name,
73            Wrapper::Set => format!("::std::collections::HashSet<{type_name}>"),
74        }
75    }
76}
77
78fn base_type_to_string(schema: &BlockType) -> &str {
79    match schema {
80        BlockType::String => "::std::string::String",
81        BlockType::Bool => "bool",
82        BlockType::Number => "i64",
83        BlockType::Dynamic => "::tf_bindgen::json::Value",
84        _ => unimplemented!(),
85    }
86}