From 38772432118cfc6818f9fac1f6d1e424c075e527 Mon Sep 17 00:00:00 2001 From: Profpatsch Date: Fri, 29 Jan 2021 15:55:11 +0100 Subject: [PATCH] feat(users/Profpatsch/netencode): add decoder module 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 --- users/Profpatsch/netencode/netencode.rs | 46 +++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/users/Profpatsch/netencode/netencode.rs b/users/Profpatsch/netencode/netencode.rs index 3c6c113df..66f3245fc 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; + } + + pub struct ScalarAsBytes; + + impl Decoder for ScalarAsBytes { + type A = Vec; + fn dec(t: T) -> Result { + 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(pub T); + + impl Decoder for Record { + type A = HashMap; + fn dec(t: T) -> Result { + match t { + T::Record(map) => + map.into_iter() + .map(|(k, v)| Inner::dec(v).map(|v2| (k, v2))) + .collect::>(), + o => Err(DecodeError(format!("Cannot decode {:?} into record", o))) + } + } + } +}