From 8fefaa56bcffc045039e3773f045abc8ceb7052a Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sat, 26 Dec 2020 17:19:45 +0000 Subject: [PATCH] wip subst more Signed-off-by: Ian Jackson --- Cargo.lock.example | 3 ++ wdriver.rs | 124 ++++++++++++++++++++++++++++++++++----------- wdriver/Cargo.toml | 3 ++ 3 files changed, 100 insertions(+), 30 deletions(-) diff --git a/Cargo.lock.example b/Cargo.lock.example index 20c168d1..ee1719c8 100644 --- a/Cargo.lock.example +++ b/Cargo.lock.example @@ -1581,9 +1581,12 @@ dependencies = [ "libc", "log 0.4.11", "nix 0.19.1", + "num-derive", + "num-traits", "otter", "regex", "structopt", + "strum", "thirtyfour_sync", "void", "x11rb", diff --git a/wdriver.rs b/wdriver.rs index bdb514bc..8525dc7e 100644 --- a/wdriver.rs +++ b/wdriver.rs @@ -7,8 +7,10 @@ pub use fehler::{throw, throws}; pub use log::{debug, error, info, trace, warn}; pub use log::{log, log_enabled}; pub use nix::unistd::LinkatFlags; +pub use num_derive::FromPrimitive; pub use regex::{Captures, Regex}; pub use structopt::StructOpt; +pub use strum::{EnumIter,IntoStaticStr}; pub use thirtyfour_sync as t4; pub use void::Void; @@ -38,6 +40,21 @@ pub const URL : &str = "http://localhost:8000"; const CONFIG : &str = "server-config.toml"; +#[derive(Copy,Clone,Debug,Eq,PartialEq,Ord,PartialOrd)] +#[derive(FromPrimitive,EnumIter,IntoStaticStr)] +#[strum(serialize_all = "snake_case")] +pub enum StaticUser { + Alice, + Bob, +} + +use StaticUser::*; + +const FIXED_TOKENS : (&str, &str) = [ + (Alice, "kmqAKPwK4TfReFjMor8MJhdRPBcwIBpe"), + (Bob , "ccg9kzoTh758QrVE1xMY7BQWB36dNJTx"), +]; + pub trait AlwaysContext { fn always_context(self, msg: &'static str) -> anyhow::Result; } @@ -102,40 +119,80 @@ pub struct DirSubst { pub src: String, } +struct RawSubst(HashMap); + +struct ExtendedSubst<'b, B: Subst, X: Subst>(&'b B, X); + +impl, + U: AsRef, + L: Iterator> + From<&L> for RawSubst +{ + fn from(l: &L) -> RawSubst { + let map = l.map(|(k,v)| (k.to_owned(), v.to_owned())).collect(); + RawSubst(map) + } +} + +trait Subst : Sized { + fn get(&self, kw: &str) -> Option; + fn also>(&self, xl: &L) -> ExtendedSubst { + ExtendedSubst(self, Box::new(xl.into())); + } + fn subst(&self, s: &dyn AsRef) -> Result { + let s = s.as_ref(); + let re = Regex::new(r"@(\w+)@").expect("bad re!"); + let mut errs = vec![]; + let out = re.replace_all(s, |caps: ®ex::Captures| { + let n = caps.get(1).expect("$1 missing!").as_str(); + if n == "" { return &"" } + self.lookup(n).unwrap_or_else(||{ + errs.push(n.to_owned()); + &"" + }) + }); + if ! errs.is_empty() { + throw!(anyhow!("bad substitution(s) {:?} in {:?}", + &errs, s)); + } + out.into() + } +} + +impl Subst for RawSubst { + #[throws(AE)] + fn get(&self, kw: &str) -> String { + self.0.get(kw).to_owned() + } +} + +impl<'b, B:Subst, X:Subst> Subst for ExtendedSubst<'b, B, X> { + #[throws(AE)] + fn get(&self, kw: &str) -> Option<&str> { + self.1.get(kw).or_else(|| self.0.get(kw)) + } +} + +impl Subst for DirSubst { + #[throws(AE)] + fn get(&self, kw: &str) -> Option { + Some(match kw { + "src" => self.src.clone(), + "build" => self.start_dir.clone(), + "target" => format!("{}/target", &self.start_dir), + "specs" => format!("{}/specs" , &self.src ), + _ => return None, + }) + } +} + impl DirSubst { #[throws(AE)] fn subst>(&self, s:S) -> String { - #[throws(AE)] - fn inner(ds: &DirSubst, s: &str) -> String { - - let build = &ds.start_dir; - let target = format!("{}/target", &ds.start_dir); - let specs = format!("{}/specs" , &ds.src ); - let map : HashMap<_,_> = [ - ("", "@"), - ("src" , &ds.src), - ("build" , build), - ("target", &target), - ("specs", &specs), - ].iter().map(|(k,v)| (k.to_owned(), *v)).collect(); - let re = Regex::new(r"@(\w+)@").expect("bad re!"); - - let mut errs = vec![]; - let out = re.replace_all(s, |caps: ®ex::Captures| { - let n = caps.get(1).expect("$1 missing!").as_str(); - map.get(n).unwrap_or_else(||{ - errs.push(n.to_owned()); - &"" - }) - }); - if ! errs.is_empty() { - throw!(anyhow!("bad substitution(s) {:?} in {:?}", - &errs, s)); - } + + + - out.into() - } - inner(self, s.as_ref())? } #[throws(AE)] @@ -501,6 +558,13 @@ pub fn prepare_game(ds: &DirSubst) { --reset-table @specs@/test.table.toml \ server::dummy @specs@/demo.game.toml \ ")?).context("reset table")?; +/* + for u in StaticUser::iter() { + ds.otter(&ds.ss( + } + +# USER=rustcargo target/debug/otter --config ~ian/Rustup/Game/server/server-test-zealot.toml --super --fixed-token --account server:alice join-game server::dummy +*/ } #[throws(AE)] diff --git a/wdriver/Cargo.toml b/wdriver/Cargo.toml index b0c2d6f7..d622ce29 100644 --- a/wdriver/Cargo.toml +++ b/wdriver/Cargo.toml @@ -20,8 +20,11 @@ humantime = "2" log = "0.4" libc = "0.2" nix = "0.19" +num-derive = "0.3" +num-traits = "0.2" regex = "1" structopt = "0.3" +strum = { version = "0.20", features = ['derive'] } thirtyfour_sync = "0.21" void = "1" x11rb = "0.7" -- 2.30.2