use indexmap::{indexmap, IndexMap}; use serde::{Deserialize, Serialize, Serializer}; use stringlit::s; #[allow(dead_code)] pub const WORD_DESCRIPTION: &str = // r#"The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119). "#; #[allow(dead_code)] pub const HIGHLIGHTED_WORDS: [&str; 10] = [ "must not", "must", "required", "shall not", "shall", "should not", "should", "recommended", "may", "optional", ]; pub fn my_trim(v: &String, s: S) -> Result where S: Serializer, { s.serialize_str(v.trim()) } #[derive(Deserialize, Serialize)] pub struct Requirement { pub name: String, #[serde(serialize_with = "my_trim")] pub description: String, #[serde(default, skip_serializing_if = "IndexMap::is_empty")] pub depends: IndexMap, } #[derive(Deserialize, Serialize)] pub struct Topic { pub name: String, #[serde(default, skip_serializing_if = "IndexMap::is_empty")] pub requirements: IndexMap, #[serde(default, skip_serializing_if = "IndexMap::is_empty")] pub subtopics: IndexMap, } #[derive(Deserialize, Serialize)] pub struct Definition { pub name: String, pub value: String, #[serde(default, skip_serializing_if = "Vec::is_empty")] pub additional_info: Vec, } #[derive(Deserialize, Serialize)] pub struct ConfigDefault { pub name: String, #[serde(rename = "type")] pub typ: String, #[serde(default, skip_serializing_if = "Vec::is_empty")] pub valid_values: Vec, #[serde(default, skip_serializing_if = "Option::is_none")] pub unit: Option, #[serde(default, skip_serializing_if = "Option::is_none")] pub default_value: Option, #[serde(default, skip_serializing_if = "Option::is_none")] pub hint: Option, } #[derive(Deserialize, Serialize)] pub struct Project { pub name: String, #[serde(serialize_with = "my_trim")] pub description: String, #[serde(default, skip_serializing_if = "IndexMap::is_empty")] pub topics: IndexMap, #[serde(default, skip_serializing_if = "Vec::is_empty")] pub definitions: Vec, #[serde(default, skip_serializing_if = "Vec::is_empty")] pub config_defaults: Vec, } pub fn demo_project() -> Project { Project { name: s!("journal-uploader"), description: s!(r#" The journal-uploader has two main functionalities. - Take a stream of log messages and filter them depending on their severity - Upload journal logs for a specified time when activated through cloud call"#), topics: indexmap! { s!("FEAT-1") => Topic { name: s!("Traced Logging"), subtopics: indexmap! { s!("SUB-1") => Topic { name: s!("File Monitoring"), requirements: indexmap! { s!("REQ-1") => Requirement { name: s!("Continuous Monitoring"), description: s!(r#"The tool must continuously monitor a designated directory."#), depends: indexmap! {} } }, subtopics: indexmap! {} }, }, requirements: indexmap! {}, } }, definitions: vec![ Definition { name: s!("Default Journal Directory"), value: s!("/run/log/journal/"), additional_info: vec![s!("Machine ID can be found at /etc/machine-id")], }, Definition { name: s!("Default Output Directory"), value: s!("/run/log/filtered-journal"), additional_info: vec![], }, ], config_defaults: vec![ ConfigDefault { name: s!("Journal Directory"), typ: s!("Path"), unit: None, valid_values: vec![], default_value: None, hint: None, }, ConfigDefault { name: s!("Output Directory"), typ: s!("Path"), unit: None, valid_values: vec![], default_value: None, hint: None, }, ConfigDefault { name: s!("Trigger Priority"), typ: s!("Enum"), unit: None, valid_values: vec![ s!("Emergency"), s!("Alert"), s!("Critical"), s!("Error"), s!("Warning"), s!("Notice"), s!("Info"), s!("Debug"), ], default_value: Some(s!("Warning")), hint: None, }, ConfigDefault { name: s!("Journal Context"), typ: s!("Integer"), unit: Some(s!("Seconds")), valid_values: vec![], default_value: Some(s!("15")), hint: None, }, ConfigDefault { name: s!("Max File Size"), typ: s!("Integer"), unit: Some(s!("Bytes")), valid_values: vec![], default_value: Some(s!("8388608")), hint: Some(s!("(8 MB)")), }, ConfigDefault { name: s!("Max Directory Size"), typ: s!("Integer"), unit: Some(s!("Bytes")), valid_values: vec![], default_value: Some(s!("75497472")), hint: Some(s!("(72 MB)")), }, ConfigDefault { name: s!("File Monitoring Interval"), typ: s!("Integer"), unit: Some(s!("Seconds")), valid_values: vec![], default_value: Some(s!("10")), hint: None, }, ], } }