Initial commit

Change-Id: I2b916ff0acd2a88aeef709cf4f900503e823d44d
diff --git a/client/src/transports/codec.rs b/client/src/transports/codec.rs
new file mode 100644
index 0000000..6e69571
--- /dev/null
+++ b/client/src/transports/codec.rs
@@ -0,0 +1,37 @@
+use bytes::{BufMut, BytesMut};
+use serde_json::Value;
+use std::io;
+use tokio_util::codec::{Decoder, Encoder};
+
+pub struct JsonCodec;
+
+impl Encoder<BytesMut> for JsonCodec {
+    type Error = io::Error;
+
+    fn encode(&mut self, data: BytesMut, buf: &mut BytesMut) -> Result<(), io::Error> {
+        buf.reserve(data.len());
+        buf.put(data);
+        Ok(())
+    }
+}
+
+impl Decoder for JsonCodec {
+    type Item = Value;
+    type Error = io::Error;
+
+    fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Value>, io::Error> {
+        if src.is_empty() {
+            return Ok(None);
+        }
+
+        match serde_json::from_slice::<Value>(src) {
+            Ok(val) => {
+                src.clear();
+
+                Ok(Some(val))
+            }
+            Err(ref e) if e.is_eof() => Ok(None),
+            Err(e) => Err(e.into()),
+        }
+    }
+}