diff options
-rw-r--r-- | users/Profpatsch/netencode/default.nix | 2 | ||||
-rw-r--r-- | users/Profpatsch/netencode/netencode.rs | 33 |
2 files changed, 29 insertions, 6 deletions
diff --git a/users/Profpatsch/netencode/default.nix b/users/Profpatsch/netencode/default.nix index 31cd822061b6..3b62c8aaac59 100644 --- a/users/Profpatsch/netencode/default.nix +++ b/users/Profpatsch/netencode/default.nix @@ -108,7 +108,7 @@ let let mut buf = vec![]; let u = netencode::u_from_stdin_or_die_user_error("record-splice-env", &mut buf); let (_, prog) = exec_helpers::args_for_exec("record-splice-env", 0); - match Record::<ScalarAsBytes>::dec(u) { + match Record(ScalarAsBytes).dec(u) { Ok(map) => { exec_helpers::exec_into_args("record-splice-env", prog, map); }, diff --git a/users/Profpatsch/netencode/netencode.rs b/users/Profpatsch/netencode/netencode.rs index e15cd8b38327..7099506f6df2 100644 --- a/users/Profpatsch/netencode/netencode.rs +++ b/users/Profpatsch/netencode/netencode.rs @@ -601,10 +601,12 @@ pub mod dec { pub trait Decoder<'a> { type A; - fn dec(u: U<'a>) -> Result<Self::A, DecodeError>; + fn dec(&self, u: U<'a>) -> Result<Self::A, DecodeError>; } + #[derive(Clone, Copy)] pub struct AnyT; + #[derive(Clone, Copy)] pub struct AnyU; // impl Decoder for AnyT { @@ -617,16 +619,17 @@ pub mod dec { impl<'a> Decoder<'a> for AnyU { type A = U<'a>; - fn dec(u: U<'a>) -> Result<Self::A, DecodeError> { + fn dec(&self, u: U<'a>) -> Result<Self::A, DecodeError> { Ok(u) } } + #[derive(Clone, Copy)] pub struct ScalarAsBytes; impl<'a> Decoder<'a> for ScalarAsBytes { type A = Vec<u8>; - fn dec(u: U<'a>) -> Result<Self::A, DecodeError> { + fn dec(&self, u: U<'a>) -> Result<Self::A, DecodeError> { match u { U::N3(u) => Ok(format!("{}", u).into_bytes()), U::N6(u) => Ok(format!("{}", u).into_bytes()), @@ -641,21 +644,41 @@ pub mod dec { } } + #[derive(Clone, Copy)] pub struct Record<T>(pub T); impl<'a, Inner: Decoder<'a>> Decoder<'a> for Record<Inner> { type A = HashMap<&'a str, Inner::A>; - fn dec(u: U<'a>) -> Result<Self::A, DecodeError> { + fn dec(&self, u: U<'a>) -> Result<Self::A, DecodeError> { match u { U::Record(map) => map.into_iter() - .map(|(k, v)| Inner::dec(v).map(|v2| (k, v2))) + .map(|(k, v)| self.0.dec(v).map(|v2| (k, v2))) .collect::<Result<Self::A, _>>(), o => Err(DecodeError(format!("Cannot decode {:?} into record", o))) } } } + #[derive(Clone, Copy)] + pub struct RecordDot<'a, T> { + field: &'a str, + inner: T + } + + impl <'a, Inner: Decoder<'a> + Copy> Decoder<'a> for RecordDot<'_, Inner> { + type A = Inner::A; + fn dec(&self, u: U<'a>) -> Result<Self::A, DecodeError> { + match Record(self.inner).dec(u) { + Ok(mut map) => match map.remove(self.field) { + Some(inner) => Ok(inner), + None => Err(DecodeError(format!("Cannot find `{}` in record map", self.field))), + }, + Err(err) => Err(err), + } + } + } + fn dec_u(b: &[u8]) -> Result<U, DecodeError> { match parse::u_u(b) { Ok((b"", u)) => Ok(u), |