diff options
author | Profpatsch <mail@profpatsch.de> | 2021-01-29T14·55+0100 |
---|---|---|
committer | Profpatsch <mail@profpatsch.de> | 2021-01-31T11·10+0000 |
commit | 38772432118cfc6818f9fac1f6d1e424c075e527 (patch) | |
tree | ae08e92a95fb9049a417c57bdc1b6d6a764e6b36 | |
parent | 06f4b75a183d0a4d2ebdac275c7fb097a6526efa (diff) |
feat(users/Profpatsch/netencode): add decoder module r/2172
Decoders are implemented not directly on output types, but on trivial proxy types, so that we can easily combine those into a decoder, and then the associated type is the actual return value of the decoder. Change-Id: Ibce98fa09fc944e02ab327112ec7ffbc09815830 Reviewed-on: https://cl.tvl.fyi/c/depot/+/2455 Tested-by: BuildkiteCI Reviewed-by: Profpatsch <mail@profpatsch.de>
-rw-r--r-- | users/Profpatsch/netencode/netencode.rs | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/users/Profpatsch/netencode/netencode.rs b/users/Profpatsch/netencode/netencode.rs index 3c6c113df589..66f3245fcf99 100644 --- a/users/Profpatsch/netencode/netencode.rs +++ b/users/Profpatsch/netencode/netencode.rs @@ -563,3 +563,49 @@ pub mod parse { } } + +pub mod dec { + use super::*; + use std::collections::HashMap; + + pub struct DecodeError(pub String); + + pub trait Decoder { + type A; + fn dec(T) -> Result<Self::A, DecodeError>; + } + + pub struct ScalarAsBytes; + + impl Decoder for ScalarAsBytes { + type A = Vec<u8>; + fn dec(t: T) -> Result<Self::A, DecodeError> { + match t { + T::N3(u) => Ok(format!("{}", u).into_bytes()), + T::N6(u) => Ok(format!("{}", u).into_bytes()), + T::N7(u) => Ok(format!("{}", u).into_bytes()), + T::I3(i) => Ok(format!("{}", i).into_bytes()), + T::I6(i) => Ok(format!("{}", i).into_bytes()), + T::I7(i) => Ok(format!("{}", i).into_bytes()), + T::Text(t) => Ok(t.into_bytes()), + T::Binary(b) => Ok(b), + o => Err(DecodeError(format!("Cannot decode {:?} into scalar", o))), + } + } + } + + pub struct Record<T>(pub T); + + impl<Inner: Decoder> Decoder for Record<Inner> { + type A = HashMap<String, Inner::A>; + fn dec(t: T) -> Result<Self::A, DecodeError> { + match t { + T::Record(map) => + map.into_iter() + .map(|(k, v)| Inner::dec(v).map(|v2| (k, v2))) + .collect::<Result<Self::A, _>>(), + o => Err(DecodeError(format!("Cannot decode {:?} into record", o))) + } + } + } +} |