Got Config parsed from yaml file
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/target
|
||||
21
.vscode/tasks.json
vendored
Normal file
21
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "cargo",
|
||||
"command": "run",
|
||||
"problemMatcher": [
|
||||
"$rustc"
|
||||
],
|
||||
"label": "rust: cargo run",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": true,
|
||||
"panel": "dedicated",
|
||||
"showReuseMessage": true,
|
||||
"clear": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
180
Cargo.lock
generated
Normal file
180
Cargo.lock
generated
Normal file
@@ -0,0 +1,180 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.98"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
|
||||
|
||||
[[package]]
|
||||
name = "configotron"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"pad",
|
||||
"serde",
|
||||
"serde_yml",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||
|
||||
[[package]]
|
||||
name = "libyml"
|
||||
version = "0.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3302702afa434ffa30847a83305f0a69d6abd74293b6554c18ec85c7ef30c980"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "pad"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2ad9b889f1b12e0b9ee24db044b5129150d5eada288edc800f789928dc8c0e3"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.219"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.219"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_yml"
|
||||
version = "0.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59e2dd588bf1597a252c3b920e0143eb99b0f76e4e082f4c92ce34fbc9e71ddd"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"itoa",
|
||||
"libyml",
|
||||
"memchr",
|
||||
"ryu",
|
||||
"serde",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
10
Cargo.toml
Normal file
10
Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "configotron"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
pad = "0.1.6"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_yml = "0.0.12"
|
||||
thiserror = "1"
|
||||
34
example.yml
Normal file
34
example.yml
Normal file
@@ -0,0 +1,34 @@
|
||||
name: ssbc_remote
|
||||
config_items:
|
||||
- !Submenu
|
||||
name: network settings
|
||||
config_items:
|
||||
- !IPv4
|
||||
name: ip
|
||||
|
||||
- !IPv4
|
||||
name: subnet_mask
|
||||
|
||||
- !IPv4
|
||||
name: gateway
|
||||
|
||||
- !String
|
||||
name: wifi_ssid
|
||||
description: The SSID of the Wi-Fi network.
|
||||
max_length: 64
|
||||
|
||||
- !String
|
||||
name: wifi_password
|
||||
description: The password for the Wi-Fi network.
|
||||
max_length: 64
|
||||
|
||||
- !Boolean
|
||||
name: dhcp_enabled
|
||||
|
||||
- !IPv4
|
||||
name: hub_ip
|
||||
|
||||
- !Number
|
||||
name: hub_port
|
||||
max: 65535
|
||||
min: 1
|
||||
123
src/main.rs
Normal file
123
src/main.rs
Normal 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!");
|
||||
}
|
||||
Reference in New Issue
Block a user