webwire_cli/schema/
struct.rs

1use std::collections::HashMap;
2
3use crate::common::FilePosition;
4use crate::idl;
5
6use super::errors::ValidationError;
7use super::fqtn::FQTN;
8use super::namespace::Namespace;
9use super::r#type::Type;
10use super::typemap::TypeMap;
11
12pub struct Struct {
13    pub fqtn: FQTN,
14    pub generics: Vec<String>,
15    pub fields: Vec<Field>,
16    pub position: FilePosition,
17}
18
19#[derive(Clone)]
20pub struct Field {
21    pub name: String,
22    pub type_: Type,
23    pub optional: bool,
24    // FIXME add options
25    pub length: (Option<i64>, Option<i64>),
26    pub format: Option<String>,
27    pub position: FilePosition,
28}
29
30impl Struct {
31    pub(crate) fn from_idl(
32        istruct: &idl::Struct,
33        ns: &Namespace,
34        builtin_types: &HashMap<String, String>,
35    ) -> Self {
36        let fields = istruct
37            .fields
38            .iter()
39            .map(|ifield| Field::from_idl(ifield, ns, &builtin_types))
40            .collect();
41        Self {
42            fqtn: FQTN::new(&istruct.name, ns),
43            generics: istruct.generics.clone(),
44            fields,
45            position: istruct.position.clone(),
46        }
47    }
48    pub(crate) fn resolve(&mut self, type_map: &TypeMap) -> Result<(), ValidationError> {
49        for field in self.fields.iter_mut() {
50            field.type_.resolve(type_map)?;
51        }
52        Ok(())
53    }
54}
55
56impl Field {
57    pub fn from_idl(
58        ifield: &idl::Field,
59        ns: &Namespace,
60        builtin_types: &HashMap<String, String>,
61    ) -> Self {
62        let mut length: (Option<i64>, Option<i64>) = (None, None);
63        let mut format: Option<String> = None;
64        for option in &ifield.options {
65            match (option.name.as_str(), &option.value) {
66                ("length", idl::Value::Range(min, max)) => length = (*min, *max),
67                //("format", format) => format = Some(format),
68                ("format", idl::Value::String(f)) => format = Some(f.clone()),
69                (name, _) => panic!("Unsupported option: {}", name),
70            }
71        }
72        Field {
73            name: ifield.name.clone(),
74            type_: Type::from_idl(&ifield.type_, ns, &builtin_types),
75            optional: ifield.optional,
76            // FIXME add options
77            //options: ifield.options
78            length,
79            format,
80            position: ifield.position.clone(),
81        }
82    }
83}