78 lines
3.1 KiB
Rust
78 lines
3.1 KiB
Rust
use std::path::Path;
|
|
use std::fs::File;
|
|
use serde_yaml;
|
|
use super::{Host, HostKind};
|
|
|
|
/** parsing funktioniert zweischrittig
|
|
zunächst wird in from_file die yaml-datei ausgelesen, das resultat ist ein struct, dass in seinem aufbau der datei entspricht
|
|
danach wird in parse dieses in ein struct verwandelt, das dem logischen aufbau entspricht.
|
|
um das programm zu erweitern ist es am besten dinge zu Host/HostKind hinzuzufügen und dann den fehlern zu folgen.
|
|
*/
|
|
#[derive(Deserialize,Debug)]
|
|
pub struct RawHost {
|
|
ansible_host: String,
|
|
#[serde(rename = "type")]
|
|
kind: String,
|
|
mac: Option<String>,
|
|
client_of: Option<String>,
|
|
coordinate: Option<[f64;2]>,
|
|
subnet: Option<String>,
|
|
link_ssid: Option<String>,
|
|
}
|
|
|
|
impl RawHost {
|
|
/** wandelt mehr oder weniger magisch eine yaml-datei in ein RawHost um.
|
|
die magie wird von dem (de)serialisierungsframework serde bereitgestellt */
|
|
pub fn from_file(path: &Path) -> (Self, String) {
|
|
//TODO use methods .is_file and .is_dir on path and read path or path/vars depending on result
|
|
let filename = path.file_stem().expect("weird path");
|
|
let hostname = filename.to_str()
|
|
.expect(&format!("filename '{:?}' is not valid utf-8", filename)).into();
|
|
let fd = if path.is_file() {
|
|
File::open(path)
|
|
.unwrap_or_else(|err| panic!("{} in file {}", err, hostname))
|
|
} else if path.is_dir() {
|
|
let mut buf = path.to_path_buf();
|
|
buf.push("vars");
|
|
File::open(buf)
|
|
.unwrap_or_else(|err| panic!("{} in file {}", err, hostname))
|
|
} else {
|
|
panic!("{:?} does not point to either a file or a directory", path)
|
|
};
|
|
let antenna : Self = serde_yaml::from_reader(&fd)
|
|
.unwrap_or_else(|err| panic!("{} in file {}", err, hostname));
|
|
(antenna, hostname)
|
|
}
|
|
|
|
/** nimmt eine geparste datei und versucht daraus die logische struktur zu extrahieren */
|
|
pub fn parse(self, name: String) -> Host {
|
|
// sobald ein felhender eintrag bei allen gefixt ist, bitte unten missingwarn("name") durch
|
|
// missingpanic ersetzen
|
|
let missingpanic= |attr: &'static str| panic!("{} does not have the required attribute {}", name, attr);
|
|
let missingwarn = |attr: &'static str| {
|
|
eprintln!("{} does not have the required attribute {}", name, attr);
|
|
"MISSING".to_string()
|
|
};
|
|
Host
|
|
{ name: name.clone()
|
|
, ip: self.ansible_host
|
|
, kind: match self.kind.as_ref()
|
|
{ "wlan-ap" => HostKind::AccessPoint
|
|
{ mac: self.mac.unwrap_or_else(|| missingpanic("mac"))
|
|
, ssid: self.link_ssid.unwrap_or_else(|| missingwarn("link_ssid"))
|
|
, parent: self.client_of.unwrap_or_else(|| missingwarn("client_of"))
|
|
}
|
|
, "client" => HostKind::Client
|
|
{ subnet: self.subnet.unwrap_or_else(|| missingpanic("subnet"))
|
|
, coordinates: self.coordinate
|
|
, parent: self.client_of.unwrap_or_else(|| missingwarn("client_of"))
|
|
, mac: self.mac.unwrap_or_else(|| missingpanic("mac"))
|
|
, ssid: self.link_ssid.unwrap_or_else(|| missingwarn("link_ssid"))
|
|
}
|
|
, "service" => HostKind::Service
|
|
, _ => HostKind::Other
|
|
}
|
|
}
|
|
}
|
|
}
|