diff options
author | Profpatsch <mail@profpatsch.de> | 2021-02-06T21·43+0100 |
---|---|---|
committer | Profpatsch <mail@profpatsch.de> | 2021-02-06T22·29+0000 |
commit | 32a5312dd83bc24b990e43a655c70337f245b9a5 (patch) | |
tree | 23f0bfd69ac2aecd35f96c554b85b6a40d47c112 /users/Profpatsch/netencode | |
parent | e207785e1fc78d06381b369c3b71b7e6becdbf80 (diff) |
feat(users/Profpatsch/netencode): `encode()` impl for T and U r/2187
Also change the toplevel `encode()` to take a `&U` instead of an owned `U`. Change-Id: I8e51540cc531e70ae1c94e3676f4dd88da7a924d Reviewed-on: https://cl.tvl.fyi/c/depot/+/2491 Tested-by: BuildkiteCI Reviewed-by: Profpatsch <mail@profpatsch.de>
Diffstat (limited to 'users/Profpatsch/netencode')
-rw-r--r-- | users/Profpatsch/netencode/netencode.rs | 49 |
1 files changed, 45 insertions, 4 deletions
diff --git a/users/Profpatsch/netencode/netencode.rs b/users/Profpatsch/netencode/netencode.rs index 09f347b78690..a1ee60452e59 100644 --- a/users/Profpatsch/netencode/netencode.rs +++ b/users/Profpatsch/netencode/netencode.rs @@ -30,6 +30,39 @@ pub enum T { List(Vec<T>), } +impl T { + fn to_u<'a>(&'a self) -> U<'a> { + match self { + T::Unit => U::Unit, + T::N1(b) => U::N1(*b), + T::N3(u) => U::N3(*u), + T::N6(u) => U::N6(*u), + T::N7(u) => U::N7(*u), + T::I3(i) => U::I3(*i), + T::I6(i) => U::I6(*i), + T::I7(i) => U::I7(*i), + T::Text(t) => U::Text(t.as_str()), + T::Binary(v) => U::Binary(v), + T::Sum(Tag { tag, val }) => U::Sum( + Tag { tag: tag.as_str(), val: Box::new(val.to_u()) } + ), + T::Record(map) => U::Record( + map.iter().map(|(k, v)| (k.as_str(), v.to_u())).collect() + ), + T::List(l) => U::List( + l.iter().map(|v| v.to_u()).collect::<Vec<U<'a>>>() + ), + } + } + + pub fn encode<'a>(&'a self) -> Vec<u8> { + match self { + // TODO: don’t go via U, inefficient + o => o.to_u().encode() + } + } +} + #[derive(Debug, PartialEq, Eq, Clone)] pub enum U<'a> { Unit, @@ -52,6 +85,14 @@ pub enum U<'a> { List(Vec<U<'a>>), } +impl<'a> U<'a> { + pub fn encode(&self) -> Vec<u8> { + let mut c = std::io::Cursor::new(vec![]); + encode(&mut c, self); + c.into_inner() + } +} + #[derive(Debug, PartialEq, Eq, Clone)] pub struct Tag<S, A> { // TODO: make into &str @@ -69,16 +110,16 @@ impl<S, A> Tag<S, A> { } } -fn encode_tag<W: Write>(w: &mut W, tag: &str, val: U) -> std::io::Result<()> { +fn encode_tag<W: Write>(w: &mut W, tag: &str, val: &U) -> std::io::Result<()> { write!(w, "<{}:{}|", tag.len(), tag)?; encode(w, val)?; Ok(()) } -pub fn encode<W: Write>(w: &mut W, u: U) -> std::io::Result<()> { +pub fn encode<W: Write>(w: &mut W, u: &U) -> std::io::Result<()> { match u { U::Unit => write!(w, "u,"), - U::N1(b) => if b { write!(w, "n1:1,") } else { write!(w, "n1:0,") }, + U::N1(b) => if *b { write!(w, "n1:1,") } else { write!(w, "n1:0,") }, U::N3(n) => write!(w, "n3:{},", n), U::N6(n) => write!(w, "n6:{},", n), U::N7(n) => write!(w, "n7:{},", n), @@ -95,7 +136,7 @@ pub fn encode<W: Write>(w: &mut W, u: U) -> std::io::Result<()> { w.write(&s); write!(w, ",") }, - U::Sum(Tag{tag, val}) => encode_tag(w, tag, *val), + U::Sum(Tag{tag, val}) => encode_tag(w, tag, val), U::Record(m) => { let mut c = std::io::Cursor::new(vec![]); for (k, v) in m { |