additional error handling; use path buffers; improve logic
This commit is contained in:
76
src/specs.rs
76
src/specs.rs
@@ -1,11 +1,11 @@
|
||||
use crate::{dbug, info, verb, LogLevel};
|
||||
use crate::{LogLevel, info, verb};
|
||||
use regex::Regex;
|
||||
use serde_json::{json, Map, Value};
|
||||
use serde_yml;
|
||||
use serde_json::{Map, Value, json};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
use std::{env, fmt, fs};
|
||||
use walkdir::WalkDir;
|
||||
use yaml_serde;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Specification {
|
||||
@@ -19,37 +19,25 @@ pub struct Specification {
|
||||
|
||||
impl Specification {
|
||||
pub fn build(
|
||||
partitional: &str,
|
||||
regional: &str,
|
||||
common: &str,
|
||||
zonal: &str,
|
||||
device: &str,
|
||||
partitional: String,
|
||||
regional: String,
|
||||
common: String,
|
||||
zonal: String,
|
||||
device: String,
|
||||
) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
// Read all YAML files
|
||||
let yaml_contents: Vec<String> = [partitional, regional, common, zonal, device]
|
||||
let json_values: Vec<Value> = [&partitional, ®ional, &common, &zonal, &device]
|
||||
.iter()
|
||||
.filter_map(|path| fs::read_to_string(path).ok())
|
||||
.collect();
|
||||
|
||||
// Convert each YAML to JSON Value and collect them
|
||||
let json_values: Vec<Value> = yaml_contents
|
||||
.iter()
|
||||
.map(|content| serde_yml::from_str(content))
|
||||
.map(|content| yaml_serde::from_str::<Value>(&content))
|
||||
.collect::<Result<Vec<Value>, _>>()?;
|
||||
|
||||
// Merge all objects under a single key
|
||||
let mut merged_map = Map::new();
|
||||
for value in json_values {
|
||||
if let Some(obj) = value.as_object() {
|
||||
for (_key, value) in obj {
|
||||
if let Some(inner_obj) = value.as_object() {
|
||||
for (k, v) in inner_obj {
|
||||
merged_map.insert(k.clone(), v.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let merged_map: Map<String, Value> = json_values
|
||||
.into_iter()
|
||||
.filter_map(|v| v.as_object().cloned())
|
||||
.flat_map(|obj| obj.into_values().filter_map(|v| v.as_object().cloned()))
|
||||
.flatten()
|
||||
.collect();
|
||||
|
||||
// Create the final merged object
|
||||
let compiled = json!({"data": merged_map});
|
||||
@@ -75,27 +63,13 @@ impl Specification {
|
||||
.filter(|c| !c.is_numeric())
|
||||
.collect::<String>()
|
||||
}
|
||||
|
||||
pub fn get_hostname(&self) -> String {
|
||||
PathBuf::from(&self.device)
|
||||
.file_name()
|
||||
.unwrap()
|
||||
.to_string_lossy()
|
||||
.into_owned()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Specification {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"Specification:\n\
|
||||
Partitional: {}\n\
|
||||
Regional: {}\n\
|
||||
Common: {}\n\
|
||||
Zonal: {}\n\
|
||||
Device: {}\n\
|
||||
Compiled:\n{}",
|
||||
"Specification:\nPartitional: {}\nRegional: {}\nCommon: {}\nZonal: {}\nDevice: {}\nCompiled:\n{}",
|
||||
self.partitional, self.regional, self.common, self.zonal, self.device, self.compiled
|
||||
)
|
||||
}
|
||||
@@ -119,20 +93,8 @@ pub fn compile(pattern: &Regex, spec_path: &String, dbg: LogLevel) -> Vec<Specif
|
||||
let regional: String = get_regional(&spec);
|
||||
let partitional: String = get_partional(&common, ®ional);
|
||||
specifications.push(
|
||||
match Specification::build(&partitional, ®ional, &common, &zonal, &spec) {
|
||||
Ok(compiled_spec) => {
|
||||
dbug!(
|
||||
dbg,
|
||||
"Compiled Spec for '{}'\n | {}\n | {}\n | {}\n | {}\n | {}",
|
||||
compiled_spec.get_hostname(),
|
||||
compiled_spec.partitional,
|
||||
compiled_spec.regional,
|
||||
compiled_spec.common,
|
||||
compiled_spec.zonal,
|
||||
compiled_spec.device
|
||||
);
|
||||
compiled_spec
|
||||
}
|
||||
match Specification::build(partitional, regional, common, zonal, spec) {
|
||||
Ok(compiled_spec) => compiled_spec,
|
||||
Err(e) => panic!("failed to build Specification: {}", e),
|
||||
},
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user