/* * This file is part of modulo. * * Copyright (C) 2020-2021 Federico Terzi * * modulo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * modulo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with modulo. If not, see . */ use super::config::{FieldConfig, FieldTypeConfig, FormConfig}; use super::parser::layout::Token; use crate::sys::form::types::*; use std::collections::HashMap; pub fn generate(config: FormConfig) -> Form { let structure = super::parser::layout::parse_layout(&config.layout); build_form(config, structure) } fn create_field(token: &Token, field_map: &HashMap) -> Field { match token { Token::Text(text) => Field { field_type: FieldType::Label(LabelMetadata { text: text.clone() }), ..Default::default() }, Token::Field(name) => { let config = if let Some(config) = field_map.get(name) { config.clone() } else { Default::default() }; let field_type = match &config.field_type { FieldTypeConfig::Text(config) => FieldType::Text(TextMetadata { default_text: config.default.clone(), multiline: config.multiline, }), FieldTypeConfig::Choice(config) => FieldType::Choice(ChoiceMetadata { values: config.values.clone(), choice_type: ChoiceType::Dropdown, default_value: config.default.clone(), }), FieldTypeConfig::List(config) => FieldType::Choice(ChoiceMetadata { values: config.values.clone(), choice_type: ChoiceType::List, default_value: config.default.clone(), }), }; Field { id: Some(name.clone()), field_type, } } } } fn build_form(form: FormConfig, structure: Vec>) -> Form { let field_map = form.fields; let mut fields = Vec::new(); for row in structure.iter() { let current_field = if row.len() == 1 { // Single field create_field(&row[0], &field_map) } else { // Row field let inner_fields = row .iter() .map(|token| create_field(token, &field_map)) .collect(); Field { field_type: FieldType::Row(RowMetadata { fields: inner_fields, }), ..Default::default() } }; fields.push(current_field) } Form { title: form.title, icon: form.icon, fields, } }