about summary refs log tree commit diff
path: root/users/Profpatsch/netencode
diff options
context:
space:
mode:
authorProfpatsch <mail@profpatsch.de>2021-02-06T21·43+0100
committerProfpatsch <mail@profpatsch.de>2021-02-06T22·29+0000
commit32a5312dd83bc24b990e43a655c70337f245b9a5 (patch)
tree23f0bfd69ac2aecd35f96c554b85b6a40d47c112 /users/Profpatsch/netencode
parente207785e1fc78d06381b369c3b71b7e6becdbf80 (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.rs49
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 {