rust to add uuid support
diff --git a/lib/rs/Cargo.toml b/lib/rs/Cargo.toml
index 38c277d..a6e8533 100644
--- a/lib/rs/Cargo.toml
+++ b/lib/rs/Cargo.toml
@@ -15,6 +15,7 @@
 [dependencies]
 byteorder = "1.3"
 integer-encoding = "3.0.3"
+uuid = "1"
 log = {version = "0.4", optional = true}
 ordered-float = "3.0"
 threadpool = {version = "1.7", optional = true}
@@ -22,3 +23,6 @@
 [features]
 default = ["server"]
 server = ["threadpool", "log"]
+
+[dev-dependencies]
+uuid = { version = "*", features = ["v4"] }
diff --git a/lib/rs/src/errors.rs b/lib/rs/src/errors.rs
index fc26330..3cd77e5 100644
--- a/lib/rs/src/errors.rs
+++ b/lib/rs/src/errors.rs
@@ -441,6 +441,15 @@
     }
 }
 
+impl From<uuid::Error> for Error {
+    fn from(err: uuid::Error) -> Self {
+        Error::Protocol(ProtocolError {
+            kind: ProtocolErrorKind::InvalidData,
+            message: err.to_string(), // FIXME: use fmt::Error's debug string
+        })
+    }
+}
+
 impl From<string::FromUtf8Error> for Error {
     fn from(err: string::FromUtf8Error) -> Self {
         Error::Protocol(ProtocolError {
diff --git a/lib/rs/src/protocol/binary.rs b/lib/rs/src/protocol/binary.rs
index 9f8af43..5da8018 100644
--- a/lib/rs/src/protocol/binary.rs
+++ b/lib/rs/src/protocol/binary.rs
@@ -190,6 +190,14 @@
         self.transport.read_f64::<BigEndian>().map_err(From::from)
     }
 
+    fn read_uuid(&mut self) -> crate::Result<uuid::Uuid> {
+        let mut buf = [0u8; 16];
+        self.transport
+            .read_exact(&mut buf)
+            .map(|_| uuid::Uuid::from_bytes(buf))
+            .map_err(From::from)
+    }
+
     fn read_string(&mut self) -> crate::Result<String> {
         let bytes = self.read_bytes()?;
         String::from_utf8(bytes).map_err(From::from)
@@ -389,6 +397,12 @@
         self.write_bytes(s.as_bytes())
     }
 
+    fn write_uuid(&mut self, uuid: &uuid::Uuid) -> crate::Result<()> {
+        self.transport
+            .write_all(uuid.as_bytes())
+            .map_err(From::from)
+    }
+
     fn write_list_begin(&mut self, identifier: &TListIdentifier) -> crate::Result<()> {
         self.write_byte(field_type_to_u8(identifier.element_type))?;
         self.write_i32(identifier.size)
@@ -470,8 +484,7 @@
         TType::Map => 0x0D,
         TType::Set => 0x0E,
         TType::List => 0x0F,
-        TType::Utf8 => 0x10,
-        TType::Utf16 => 0x11,
+        TType::Uuid => 0x10,
     }
 }
 
@@ -490,8 +503,7 @@
         0x0D => Ok(TType::Map),
         0x0E => Ok(TType::Set),
         0x0F => Ok(TType::List),
-        0x10 => Ok(TType::Utf8),
-        0x11 => Ok(TType::Utf16),
+        0x10 => Ok(TType::Uuid),
         unkn => Err(crate::Error::Protocol(ProtocolError {
             kind: ProtocolErrorKind::InvalidData,
             message: format!("cannot convert {} to TType", unkn),
@@ -886,6 +898,25 @@
     }
 
     #[test]
+    fn must_write_uuid() {
+        let (_, mut o_prot) = test_objects(true);
+        let uuid = uuid::Uuid::new_v4();
+        assert!(o_prot.write_uuid(&uuid).is_ok());
+        let buf = o_prot.transport.write_bytes();
+        assert_eq!(&buf, uuid.as_bytes());
+    }
+
+    #[test]
+    fn must_round_trip_uuid() {
+        let (mut i_prot, mut o_prot) = test_objects(true);
+        let uuid = uuid::uuid!("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4");
+        assert!(o_prot.write_uuid(&uuid).is_ok());
+        copy_write_buffer_to_read_buffer!(o_prot);
+        let received_uuid = assert_success!(i_prot.read_uuid());
+        assert_eq!(&received_uuid, &uuid);
+    }
+
+    #[test]
     fn must_round_trip_bytes() {
         let (mut i_prot, mut o_prot) = test_objects(true);
 
diff --git a/lib/rs/src/protocol/compact.rs b/lib/rs/src/protocol/compact.rs
index 87cfbfc..a1aa253 100644
--- a/lib/rs/src/protocol/compact.rs
+++ b/lib/rs/src/protocol/compact.rs
@@ -252,6 +252,10 @@
             .map_err(From::from)
     }
 
+    fn read_uuid(&mut self) -> crate::Result<uuid::Uuid> {
+        uuid::Uuid::from_slice(&self.read_bytes()?).map_err(From::from)
+    }
+
     fn read_string(&mut self) -> crate::Result<String> {
         let bytes = self.read_bytes()?;
         String::from_utf8(bytes).map_err(From::from)
@@ -538,6 +542,10 @@
             .map_err(From::from)
     }
 
+    fn write_uuid(&mut self, uuid: &uuid::Uuid) -> crate::Result<()> {
+        self.write_bytes(uuid.as_bytes())
+    }
+
     fn write_string(&mut self, s: &str) -> crate::Result<()> {
         self.write_bytes(s.as_bytes())
     }
@@ -637,6 +645,7 @@
         TType::Set => 0x0A,
         TType::Map => 0x0B,
         TType::Struct => 0x0C,
+        TType::Uuid => 0x0D,
         _ => panic!("should not have attempted to convert {} to u8", field_type),
     }
 }
@@ -661,6 +670,7 @@
         0x0A => Ok(TType::Set),
         0x0B => Ok(TType::Map),
         0x0C => Ok(TType::Struct),
+        0x0D => Ok(TType::Uuid),
         unkn => Err(crate::Error::Protocol(crate::ProtocolError {
             kind: crate::ProtocolErrorKind::InvalidData,
             message: format!("cannot convert {} into TType", unkn),
diff --git a/lib/rs/src/protocol/mod.rs b/lib/rs/src/protocol/mod.rs
index 019f717..0e47795 100644
--- a/lib/rs/src/protocol/mod.rs
+++ b/lib/rs/src/protocol/mod.rs
@@ -171,6 +171,8 @@
     fn read_i64(&mut self) -> crate::Result<i64>;
     /// Read a 64-bit float.
     fn read_double(&mut self) -> crate::Result<f64>;
+    /// Read a UUID.
+    fn read_uuid(&mut self) -> crate::Result<uuid::Uuid>;
     /// Read a fixed-length string (not null terminated).
     fn read_string(&mut self) -> crate::Result<String>;
     /// Read the beginning of a list.
@@ -323,6 +325,8 @@
     fn write_i64(&mut self, i: i64) -> crate::Result<()>;
     /// Write a 64-bit float.
     fn write_double(&mut self, d: f64) -> crate::Result<()>;
+    /// Write a UUID
+    fn write_uuid(&mut self, uuid: &uuid::Uuid) -> crate::Result<()>;
     /// Write a fixed-length string.
     fn write_string(&mut self, s: &str) -> crate::Result<()>;
     /// Write the beginning of a list.
@@ -405,6 +409,10 @@
         (**self).read_double()
     }
 
+    fn read_uuid(&mut self) -> crate::Result<uuid::Uuid> {
+        (**self).read_uuid()
+    }
+
     fn read_string(&mut self) -> crate::Result<String> {
         (**self).read_string()
     }
@@ -498,6 +506,10 @@
         (**self).write_double(d)
     }
 
+    fn write_uuid(&mut self, uuid: &uuid::Uuid) -> crate::Result<()> {
+        (**self).write_uuid(uuid)
+    }
+
     fn write_string(&mut self, s: &str) -> crate::Result<()> {
         (**self).write_string(s)
     }
@@ -823,8 +835,8 @@
     List,
     /// UTF-8 string.
     Utf8,
-    /// UTF-16 string. *Unsupported*.
-    Utf16,
+    /// Uuid.
+    Uuid,
 }
 
 impl Display for TType {
@@ -845,7 +857,7 @@
             TType::Set => write!(f, "set"),
             TType::List => write!(f, "list"),
             TType::Utf8 => write!(f, "UTF8"),
-            TType::Utf16 => write!(f, "UTF16"),
+            TType::Uuid => write!(f, "UUID"),
         }
     }
 }
diff --git a/lib/rs/src/protocol/multiplexed.rs b/lib/rs/src/protocol/multiplexed.rs
index 697b7e6..48d4989 100644
--- a/lib/rs/src/protocol/multiplexed.rs
+++ b/lib/rs/src/protocol/multiplexed.rs
@@ -152,6 +152,10 @@
         self.inner.write_string(s)
     }
 
+    fn write_uuid(&mut self, uuid: &uuid::Uuid) -> crate::Result<()> {
+        self.inner.write_uuid(uuid)
+    }
+
     fn write_list_begin(&mut self, identifier: &TListIdentifier) -> crate::Result<()> {
         self.inner.write_list_begin(identifier)
     }
diff --git a/lib/rs/src/protocol/stored.rs b/lib/rs/src/protocol/stored.rs
index 179ae07..f4bdfb1 100644
--- a/lib/rs/src/protocol/stored.rs
+++ b/lib/rs/src/protocol/stored.rs
@@ -158,6 +158,10 @@
         self.inner.read_double()
     }
 
+    fn read_uuid(&mut self) -> crate::Result<uuid::Uuid> {
+        self.inner.read_uuid()
+    }
+
     fn read_string(&mut self) -> crate::Result<String> {
         self.inner.read_string()
     }
diff --git a/lib/rs/test/Cargo.toml b/lib/rs/test/Cargo.toml
index a1c6836..4c64f38 100644
--- a/lib/rs/test/Cargo.toml
+++ b/lib/rs/test/Cargo.toml
@@ -10,6 +10,7 @@
 clap = "~2.33"
 bitflags = "=1.2"
 log = "0.4"
+uuid = "1"
 
 [dependencies.thrift]
 path = "../"
diff --git a/lib/rs/test/thrifts/Base_One.thrift b/lib/rs/test/thrifts/Base_One.thrift
index c5fa6c2..f1214c9 100644
--- a/lib/rs/test/thrifts/Base_One.thrift
+++ b/lib/rs/test/thrifts/Base_One.thrift
@@ -74,6 +74,7 @@
   1: string recipeName
   2: string cuisine
   3: i8 page
+  4: uuid recipeId
 }
 
 union CookingTools {