webwire_cli/schema/
fieldset.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#struct::Field;
10use super::r#type::TypeRef;
11use super::typemap::TypeMap;
12
13pub struct Fieldset {
14    pub fqtn: FQTN,
15    pub generics: Vec<String>,
16    pub r#struct: TypeRef,
17    pub fields: Vec<FieldsetField>,
18}
19
20pub struct FieldsetField {
21    pub name: String,
22    pub optional: bool,
23    pub field: Option<Field>,
24}
25
26impl Fieldset {
27    pub(crate) fn from_idl(
28        ifieldset: &idl::Fieldset,
29        ns: &Namespace,
30        builtin_types: &HashMap<String, String>,
31    ) -> Self {
32        Self {
33            fqtn: FQTN::new(&ifieldset.name, ns),
34            generics: ifieldset.generics.clone(),
35            r#struct: TypeRef::from_idl(&ifieldset.r#struct, ns, &builtin_types),
36            fields: ifieldset
37                .fields
38                .iter()
39                .map(|ifield| FieldsetField {
40                    name: ifield.name.clone(),
41                    optional: ifield.optional,
42                    field: None,
43                })
44                .collect(),
45        }
46    }
47    pub(crate) fn resolve(&mut self, type_map: &TypeMap) -> Result<(), ValidationError> {
48        self.r#struct.resolve(type_map)?;
49        if let TypeRef::Struct(struct_) = &self.r#struct {
50            let struct_rc = struct_.struct_.upgrade().unwrap();
51            let struct_borrow = struct_rc.borrow();
52            let field_map = struct_borrow
53                .fields
54                .iter()
55                .map(|f| (f.name.clone(), f))
56                .collect::<HashMap<_, _>>();
57            for field in self.fields.iter_mut() {
58                if let Some(&struct_field) = field_map.get(&field.name) {
59                    field.field.replace(struct_field.clone());
60                } else {
61                    return Err(ValidationError::NoSuchField {
62                        position: FilePosition { line: 0, column: 0 },
63                        fieldset: self.fqtn.clone(),
64                        r#struct: struct_borrow.fqtn.clone(),
65                        field: field.name.clone(),
66                    });
67                }
68            }
69        } else {
70            return Err(ValidationError::FieldsetExtendsNonStruct {
71                position: FilePosition { line: 0, column: 0 },
72                fieldset: self.fqtn.clone(),
73                r#struct: self.r#struct.fqtn().clone(),
74            });
75        }
76        // FIXME fields need to be resolved, too.
77        Ok(())
78    }
79}