chiark / gitweb /
wip subst more
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 26 Dec 2020 17:19:45 +0000 (17:19 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 26 Dec 2020 17:19:45 +0000 (17:19 +0000)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Cargo.lock.example
wdriver.rs
wdriver/Cargo.toml

index 20c168d1beb1b31fa9881c252e80b38c5a482488..ee1719c824b3909ea77322f2b3d58a6f02b5a3ec 100644 (file)
@@ -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",
index bdb514bc5c722fc2b63e80cfd29cb012d84f4c43..8525dc7e848f394721bfda22fc0d32822497a50c 100644 (file)
@@ -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<T,E> {
   fn always_context(self, msg: &'static str) -> anyhow::Result<T>;
 }
@@ -102,40 +119,80 @@ pub struct DirSubst {
   pub src: String,
 }
 
+struct RawSubst(HashMap<String,String>);
+
+struct ExtendedSubst<'b, B: Subst, X: Subst>(&'b B, X);
+
+impl<T: AsRef<str>,
+     U: AsRef<str>,
+     L: Iterator<Item=(T,U)>>
+  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<String>;
+  fn also<L: Into<RawSubst>>(&self, xl: &L) -> ExtendedSubst<Self, RawSubst> {
+    ExtendedSubst(self, Box::new(xl.into()));
+  }
+  fn subst(&self, s: &dyn AsRef<str>) -> Result<String,AE> {
+    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: &regex::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<String> {
+    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<S:AsRef<str>>(&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: &regex::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)]
index b0c2d6f77079d2fb16bce53cb1a6455003528fd9..d622ce299f914245e7c97e39427ad14ef46bbe9d 100644 (file)
@@ -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"