Streamline configuration

Fixes triggermulti deserialization
Add 'generate-dhall' argument, which generates dhall for the config
enums.
This commit is contained in:
2022-07-11 14:03:13 +00:00
parent b0c1c7d966
commit 7b2a92012b
6 changed files with 136 additions and 14 deletions
+33 -12
View File
@@ -1,5 +1,7 @@
use crate::StdError;
use chrono::Utc;
use serde::Deserialize;
use serde_dhall::StaticType;
use serde_dhall::{SimpleType, StaticType};
use std::collections::HashMap;
use std::error::Error;
use std::fmt;
@@ -24,7 +26,11 @@ impl fmt::Display for Action {
}
}
#[derive(Deserialize, StaticType, Debug)]
// Newtype wrapper around a Vec of actions.
// serde(transparent) and the imp StaticType below ensures we ignore the outer struct and
// transparently deserialize into the inner vec.
#[derive(Deserialize, Debug)]
#[serde(transparent)]
pub struct Actions(Vec<Action>);
impl Actions {
@@ -40,6 +46,12 @@ impl fmt::Display for Actions {
}
}
impl StaticType for Actions {
fn static_type() -> SimpleType {
SimpleType::List(Box::new(Action::static_type()))
}
}
#[derive(Deserialize, StaticType, Debug)]
pub enum Mapping {
NOP, // Do nothing.
@@ -87,16 +99,25 @@ pub struct Config {
impl Config {
pub fn from_file(p: &Path) -> Result<Self, Box<dyn Error>> {
match serde_dhall::from_file(p)
.with_builtin_type("Mapping".to_string(), Mapping::static_type())
.with_builtin_type("Action".to_string(), Action::static_type())
serde_dhall::from_file(p)
.parse::<Self>()
{
Ok(c) => Ok(c),
Err(e) => {
println!("{}", e);
Err(Box::new(e))
}
}
.map_err(|e| e.into())
}
pub fn generate_prelude() -> StdError<()> {
let mut m = HashMap::new();
m.insert("Action".to_string(), Action::static_type());
m.insert("Mapping".to_string(), Mapping::static_type());
println!(
"-- Sampad Dhall types, autogenerated by git#{} on {}",
option_env!("VERSION").unwrap_or("unknown"),
Utc::now(),
);
println!(
"{{ Action = {}, Mapping = {} }}",
Action::static_type(),
Mapping::static_type()
);
Ok(())
}
}
+16 -1
View File
@@ -5,11 +5,14 @@ use config::{Action, Config, Mapping};
use hidapi::HidApi;
use rumqttc::{Client, MqttOptions, QoS};
use std::collections::HashMap;
use std::env;
use std::error::Error;
use std::path::Path;
use std::thread;
use tracing::{event, Level};
type StdError<T> = Result<T, Box<dyn Error>>;
struct State<'a> {
mqtt_servers: HashMap<String, Client>,
conf: &'a Config,
@@ -107,7 +110,19 @@ impl<'a> State<'a> {
}
}
fn main() -> Result<(), Box<dyn Error>> {
fn main() -> StdError<()> {
let args: Vec<_> = env::args().collect();
if let [prog, args @ ..] = &args[..] {
if args == ["generate-dhall"] {
return Config::generate_prelude();
} else if args.len() > 0 {
eprintln!("Usage: {} [generate-dhall]", prog);
return Err("Invalid usage".into());
}
} else {
unreachable!();
}
tracing_subscriber::fmt::init();
event!(Level::INFO, "Starting...");
let conf = Config::from_file(Path::new("./config.dhall"))?;