Skip to main content

presolve_compiler/
runtime_form_registry.rs

1//! I14 versioned compiler-generated Form runtime registry.
2use crate::{
3    FieldId, FormEntity, FormFieldBinding, FormFieldEntity, FormId, FormInstanceId, FormIrReport,
4    FormSerializationPlan, FormSubmissionPlan, ResetProducts, SerializationProducts,
5    SubmissionHost, SubmissionHostId, SubmissionProducts, ValidationRule, ValidationRuleId,
6};
7use std::collections::BTreeMap;
8pub const RUNTIME_FORM_REGISTRY_VERSION: u32 = 1;
9#[derive(Debug, Clone, PartialEq, Eq)]
10pub struct RuntimeFormRecord {
11    pub form: FormId,
12    pub fields: Vec<FieldId>,
13    pub submission: Option<FormSubmissionPlan>,
14    pub serialization: Option<FormSerializationPlan>,
15}
16#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct RuntimeFormInstanceRecord {
18    pub instance: FormInstanceId,
19    pub form: FormId,
20    pub programs: usize,
21}
22#[derive(Debug, Clone, PartialEq, Eq)]
23pub struct RuntimeFormRegistry {
24    pub version: u32,
25    pub forms: BTreeMap<FormId, RuntimeFormRecord>,
26    pub instances: BTreeMap<FormInstanceId, RuntimeFormInstanceRecord>,
27    pub bindings: Vec<FormFieldBinding>,
28    pub rules: BTreeMap<ValidationRuleId, ValidationRule>,
29    pub reset: ResetProducts,
30    pub hosts: BTreeMap<SubmissionHostId, SubmissionHost>,
31}
32#[must_use]
33#[allow(clippy::too_many_arguments)]
34pub fn build_runtime_form_registry(
35    forms: &BTreeMap<FormId, FormEntity>,
36    fields: &BTreeMap<FieldId, FormFieldEntity>,
37    bindings: &BTreeMap<crate::FieldBindingId, FormFieldBinding>,
38    rules: &BTreeMap<ValidationRuleId, ValidationRule>,
39    ir: &FormIrReport,
40    submissions: &SubmissionProducts,
41    serialization: &SerializationProducts,
42    reset: &ResetProducts,
43    hosts: &BTreeMap<SubmissionHostId, SubmissionHost>,
44) -> RuntimeFormRegistry {
45    let forms = forms
46        .values()
47        .map(|form| {
48            let mut ids = fields
49                .values()
50                .filter(|f| f.owner_form == form.id)
51                .collect::<Vec<_>>();
52            ids.sort_by_key(|f| f.declaration_order);
53            (
54                form.id.clone(),
55                RuntimeFormRecord {
56                    form: form.id.clone(),
57                    fields: ids.into_iter().map(|f| f.id.clone()).collect(),
58                    submission: submissions
59                        .plans
60                        .get(&crate::SubmissionPlanId::for_form(&form.id))
61                        .cloned(),
62                    serialization: serialization
63                        .plans
64                        .get(&crate::SerializationPlanId::for_form(&form.id))
65                        .cloned(),
66                },
67            )
68        })
69        .collect();
70    let instances = ir
71        .instances
72        .values()
73        .map(|instance| {
74            (
75                instance.id.clone(),
76                RuntimeFormInstanceRecord {
77                    instance: instance.id.clone(),
78                    form: instance.form.clone(),
79                    programs: instance.input.len() + instance.blur.len() + 1,
80                },
81            )
82        })
83        .collect();
84    RuntimeFormRegistry {
85        version: RUNTIME_FORM_REGISTRY_VERSION,
86        forms,
87        instances,
88        bindings: bindings.values().cloned().collect(),
89        rules: rules.clone(),
90        reset: reset.clone(),
91        hosts: hosts.clone(),
92    }
93}
94#[cfg(test)]
95mod tests {
96    #[test]
97    fn is_versioned_and_instance_qualified() {
98        let parsed = presolve_parser::parse_file(
99            "src/X.tsx",
100            r#"@component("x")class X{@form()form!:Form;@field(this.form)value="";render(){return <input field={this.value}/>;}}"#,
101        );
102        let asm = crate::build_application_semantic_model(&parsed);
103        assert_eq!(asm.runtime_forms.version, 1);
104        assert!(asm
105            .runtime_forms
106            .instances
107            .values()
108            .all(|r| asm.runtime_forms.forms.contains_key(&r.form)));
109    }
110}