Got Config parsed from yaml file

This commit is contained in:
AlexanderHD27
2025-05-20 01:59:41 +02:00
commit 877cf71413
6 changed files with 369 additions and 0 deletions

123
src/main.rs Normal file
View File

@@ -0,0 +1,123 @@
use serde::{Deserialize, Serialize};
use serde_yml;
use std::fs;
use pad::PadStr;
#[derive(Deserialize, Serialize, Debug)]
enum UserConfigItem {
String {
name: String,
max_length: u64
},
IPv4 {
name: String,
},
Boolean {
name: String
},
Number {
name: String,
max: Option<i32>,
min: Option<i32>
},
Submenu(UserConfigData)
}
#[derive(Deserialize, Serialize, Debug)]
struct UserConfigData {
name: String,
config_items: Vec<UserConfigItem>
}
#[derive(thiserror::Error, Debug)]
pub enum ConfigotronError {
#[error("IO Operation failed: {}", ._0.to_string())]
IoError(#[from] std::io::Error),
#[error("Failed to parse YAML File: {}", ._0.to_string())]
YamlParsingError(#[from] serde_yml::Error),
#[error("Missing field {} (line {} col {}) {}", .missing_filed, .line, .col, .context)]
MissingFieldError{
col: i32,
line: i32,
missing_filed: Box<str>,
context: Box<str>
}
}
fn read_and_parse_yaml_file(input_file: &str) -> Result<UserConfigData, ConfigotronError> {
let file_content = fs::read_to_string(&input_file)?;
let config: UserConfigData = serde_yml::from_str(&file_content)?;
return Ok(config);
}
fn generate_text_report_from_item(item: &UserConfigItem) -> Vec<String> {
return match item {
UserConfigItem::Boolean {name} => vec![String::from(name), String::from("[y/n]")] ,
UserConfigItem::IPv4 { name } => vec![String::from(name), format!("[ipv4]")],
UserConfigItem::String { name, max_length } => vec![String::from(name), format!("[text, max length {}]", max_length)],
UserConfigItem::Number { name, min, max } => match (min, max) {
(None, None) => vec![String::from(name), String::from("[number]")],
(None, Some(maximum)) => vec![String::from(name), format!("[number, ..{}]", maximum)],
(Some(minmum), None) => vec![String::from(name), format!("[number, {}..]", minmum)],
(Some(minmum), Some(maximum)) => vec![String::from(name), format!("[number, {}..{}]", minmum, maximum)],
},
UserConfigItem::Submenu(c) => generate_text_report(c)
}
}
fn generate_text_report(config: &UserConfigData) -> Vec<String> {
let lines: Vec<Vec<String>> = config.config_items
.iter()
.map(|i| generate_text_report_from_item(i))
.collect();
let block_width = lines
.iter()
.map(|l: &Vec<String>|
l
.iter()
.map(|s: &String| s.chars().count())
.max().unwrap_or(0)
)
.max().unwrap_or(0);
let line_seperator = format!("+{}+", "-".repeat(block_width + 2));
let config_name_width = config.name.chars().count() + 2;
let mut lines_flattend: Vec<String> = lines
.iter()
.map(|i| i
.iter()
.map(|s| format!("| {} |", s.pad_to_width(block_width)))
.collect::<Vec<String>>()
)
.flat_map(|seg| [seg, vec![String::from(&line_seperator)]])
.flatten()
.into_iter()
.map(|e| format!("{}{}", " ".repeat(config_name_width), e))
.collect();
lines_flattend.insert(0, format!("{}{}", config.name.pad_to_width(config_name_width), line_seperator));
return lines_flattend;
}
fn main() {
let data = match read_and_parse_yaml_file("example.yml") {
Ok(d) => d,
Err(error) => {
println!("{}", error);
return;
}
};
let res = generate_text_report(&data).join("\n");
println!("{}", res);
println!("Hello, world!");
}