diff --git a/rust/flexbuffers/src/reader/de.rs b/rust/flexbuffers/src/reader/de.rs
new file mode 100644
index 0000000..8cc3b6e
--- /dev/null
+++ b/rust/flexbuffers/src/reader/de.rs
@@ -0,0 +1,254 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use super::Error;
+use crate::{FlexBufferType, Reader, ReaderIterator};
+use serde::de::{
+    DeserializeSeed, Deserializer, EnumAccess, IntoDeserializer, MapAccess, SeqAccess,
+    VariantAccess, Visitor,
+};
+
+/// Errors that may happen when deserializing a flexbuffer with serde.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub enum DeserializationError {
+    Reader(Error),
+    Serde(String),
+}
+
+impl std::error::Error for DeserializationError {}
+impl std::fmt::Display for DeserializationError {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
+        match self {
+            Self::Reader(r) => write!(f, "Flexbuffer Read Error: {:?}", r),
+            Self::Serde(s) => write!(f, "Serde Error: {}", s),
+        }
+    }
+}
+impl serde::de::Error for DeserializationError {
+    fn custom<T>(msg: T) -> Self
+    where
+        T: std::fmt::Display,
+    {
+        Self::Serde(format!("{}", msg))
+    }
+}
+impl std::convert::From<super::Error> for DeserializationError {
+    fn from(e: super::Error) -> Self {
+        Self::Reader(e)
+    }
+}
+
+impl<'de> SeqAccess<'de> for ReaderIterator<'de> {
+    type Error = DeserializationError;
+    fn next_element_seed<T>(
+        &mut self,
+        seed: T,
+    ) -> Result<Option<<T as DeserializeSeed<'de>>::Value>, Self::Error>
+    where
+        T: DeserializeSeed<'de>,
+    {
+        if let Some(elem) = self.next() {
+            seed.deserialize(elem).map(Some)
+        } else {
+            Ok(None)
+        }
+    }
+    fn size_hint(&self) -> Option<usize> {
+        Some(self.len())
+    }
+}
+
+struct EnumReader<'de> {
+    variant: &'de str,
+    value: Option<Reader<'de>>,
+}
+
+impl<'de> EnumAccess<'de> for EnumReader<'de> {
+    type Error = DeserializationError;
+    type Variant = Reader<'de>;
+    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
+    where
+        V: DeserializeSeed<'de>,
+    {
+        seed.deserialize(self.variant.into_deserializer())
+            .map(|v| (v, self.value.unwrap_or_default()))
+    }
+}
+
+struct MapAccessor<'de> {
+    keys: ReaderIterator<'de>,
+    vals: ReaderIterator<'de>,
+}
+impl<'de> MapAccess<'de> for MapAccessor<'de> {
+    type Error = DeserializationError;
+
+    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
+    where
+        K: DeserializeSeed<'de>,
+    {
+        if let Some(k) = self.keys.next() {
+            seed.deserialize(k).map(Some)
+        } else {
+            Ok(None)
+        }
+    }
+    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
+    where
+        V: DeserializeSeed<'de>,
+    {
+        let val = self.vals.next().ok_or(Error::IndexOutOfBounds)?;
+        seed.deserialize(val)
+    }
+}
+
+impl<'de> VariantAccess<'de> for Reader<'de> {
+    type Error = DeserializationError;
+    fn unit_variant(self) -> Result<(), Self::Error> {
+        Ok(())
+    }
+    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
+    where
+        T: DeserializeSeed<'de>,
+    {
+        seed.deserialize(self)
+    }
+    // Tuple variants have an internally tagged representation. They are vectors where Index 0 is
+    // the discriminant and index N is field N-1.
+    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_seq(self.as_vector().iter())
+    }
+    // Struct variants have an internally tagged representation. They are vectors where Index 0 is
+    // the discriminant and index N is field N-1.
+    fn struct_variant<V>(
+        self,
+        _fields: &'static [&'static str],
+        visitor: V,
+    ) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        let m = self.get_map()?;
+        visitor.visit_map(MapAccessor {
+            keys: m.keys_vector().iter(),
+            vals: m.iter_values(),
+        })
+    }
+}
+
+impl<'de> Deserializer<'de> for crate::Reader<'de> {
+    type Error = DeserializationError;
+    fn is_human_readable(&self) -> bool {
+        cfg!(deserialize_human_readable)
+    }
+
+    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        use crate::BitWidth::*;
+        use crate::FlexBufferType::*;
+        match (self.flexbuffer_type(), self.bitwidth()) {
+            (Bool, _) => visitor.visit_bool(self.as_bool()),
+            (UInt, W8) => visitor.visit_u8(self.as_u8()),
+            (UInt, W16) => visitor.visit_u16(self.as_u16()),
+            (UInt, W32) => visitor.visit_u32(self.as_u32()),
+            (UInt, W64) => visitor.visit_u64(self.as_u64()),
+            (Int, W8) => visitor.visit_i8(self.as_i8()),
+            (Int, W16) => visitor.visit_i16(self.as_i16()),
+            (Int, W32) => visitor.visit_i32(self.as_i32()),
+            (Int, W64) => visitor.visit_i64(self.as_i64()),
+            (Float, W32) => visitor.visit_f32(self.as_f32()),
+            (Float, W64) => visitor.visit_f64(self.as_f64()),
+            (Float, _) => Err(Error::InvalidPackedType.into()), // f8 and f16 are not supported.
+            (Null, _) => visitor.visit_unit(),
+            (String, _) | (Key, _) => visitor.visit_borrowed_str(self.as_str()),
+            (Blob, _) => visitor.visit_borrowed_bytes(self.get_blob()?.0),
+            (Map, _) => {
+                let m = self.get_map()?;
+                visitor.visit_map(MapAccessor {
+                    keys: m.keys_vector().iter(),
+                    vals: m.iter_values(),
+                })
+            }
+            (ty, _) if ty.is_vector() => visitor.visit_seq(self.as_vector().iter()),
+            (ty, bw) => unreachable!("TODO deserialize_any {:?} {:?}.", ty, bw),
+        }
+    }
+    serde::forward_to_deserialize_any! {
+        bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 str unit unit_struct bytes
+        ignored_any map identifier struct tuple tuple_struct seq string
+    }
+    fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_char(self.as_u8() as char)
+    }
+    fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_byte_buf(self.get_blob()?.0.to_vec())
+    }
+    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        if self.flexbuffer_type() == FlexBufferType::Null {
+            visitor.visit_none()
+        } else {
+            visitor.visit_some(self)
+        }
+    }
+    fn deserialize_newtype_struct<V>(
+        self,
+        _name: &'static str,
+        visitor: V,
+    ) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_newtype_struct(self)
+    }
+    fn deserialize_enum<V>(
+        self,
+        _name: &'static str,
+        _variants: &'static [&'static str],
+        visitor: V,
+    ) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        let (variant, value) = match self.fxb_type {
+            FlexBufferType::String => (self.as_str(), None),
+            FlexBufferType::Map => {
+                let m = self.get_map()?;
+                let variant = m.keys_vector().idx(0).get_key()?;
+                let value = Some(m.idx(0));
+                (variant, value)
+            }
+            _ => {
+                return Err(Error::UnexpectedFlexbufferType {
+                    expected: FlexBufferType::Map,
+                    actual: self.fxb_type,
+                }
+                .into());
+            }
+        };
+        visitor.visit_enum(EnumReader { variant, value })
+    }
+}
diff --git a/rust/flexbuffers/src/reader/iter.rs b/rust/flexbuffers/src/reader/iter.rs
new file mode 100644
index 0000000..8e06171
--- /dev/null
+++ b/rust/flexbuffers/src/reader/iter.rs
@@ -0,0 +1,63 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use super::{Reader, VectorReader};
+use std::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator};
+
+/// Iterates over a flexbuffer vector, typed vector, or map. Yields [Readers](struct.Reader.html).
+///
+/// If any error occurs, the Reader is defaulted to a Null flexbuffer Reader.
+pub struct ReaderIterator<'de> {
+    pub(super) reader: VectorReader<'de>,
+    pub(super) front: usize,
+    end: usize,
+}
+impl<'de> ReaderIterator<'de> {
+    pub(super) fn new(reader: VectorReader<'de>) -> Self {
+        let end = reader.len();
+        ReaderIterator {
+            reader,
+            front: 0,
+            end,
+        }
+    }
+}
+impl<'de> Iterator for ReaderIterator<'de> {
+    type Item = Reader<'de>;
+    fn next(&mut self) -> Option<Self::Item> {
+        if self.front < self.end {
+            let r = self.reader.idx(self.front);
+            self.front += 1;
+            Some(r)
+        } else {
+            None
+        }
+    }
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let remaining = self.end - self.front;
+        (remaining, Some(remaining))
+    }
+}
+impl<'de> DoubleEndedIterator for ReaderIterator<'de> {
+    fn next_back(&mut self) -> Option<Self::Item> {
+        if self.front < self.end {
+            self.end -= 1;
+            Some(self.reader.idx(self.end))
+        } else {
+            None
+        }
+    }
+}
+impl<'de> ExactSizeIterator for ReaderIterator<'de> {}
+impl<'de> FusedIterator for ReaderIterator<'de> {}
diff --git a/rust/flexbuffers/src/reader/map.rs b/rust/flexbuffers/src/reader/map.rs
new file mode 100644
index 0000000..cdf59e0
--- /dev/null
+++ b/rust/flexbuffers/src/reader/map.rs
@@ -0,0 +1,157 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use super::{deref_offset, unpack_type, Error, Reader, ReaderIterator, VectorReader};
+use crate::BitWidth;
+use std::cmp::Ordering;
+use std::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator};
+
+/// Allows indexing on a flexbuffer map.
+///
+/// MapReaders may be indexed with strings or usizes. `index` returns a result type,
+/// which may indicate failure due to a missing key or bad data, `idx` returns an Null Reader in
+/// cases of error.
+#[derive(Default, Clone)]
+pub struct MapReader<'de> {
+    pub(super) buffer: &'de [u8],
+    pub(super) values_address: usize,
+    pub(super) keys_address: usize,
+    pub(super) values_width: BitWidth,
+    pub(super) keys_width: BitWidth,
+    pub(super) length: usize,
+}
+
+// manual implementation of Debug because buffer slice can't be automatically displayed
+impl<'de> std::fmt::Debug for MapReader<'de> {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        // skips buffer field
+        f.debug_struct("MapReader")
+            .field("values_address", &self.values_address)
+            .field("keys_address", &self.keys_address)
+            .field("values_width", &self.values_width)
+            .field("keys_width", &self.keys_width)
+            .field("length", &self.length)
+            .finish()
+    }
+}
+
+impl<'de> MapReader<'de> {
+    /// Returns the number of key/value pairs are in the map.
+    pub fn len(&self) -> usize {
+        self.length
+    }
+    /// Returns true if the map has zero key/value pairs.
+    pub fn is_empty(&self) -> bool {
+        self.length == 0
+    }
+    // Using &CStr will eagerly compute the length of the key. &str needs length info AND utf8
+    // validation. This version is faster than both.
+    fn lazy_strcmp(&self, key_addr: usize, key: &str) -> Ordering {
+        // TODO: Can we know this won't OOB and panic?
+        let k = self.buffer[key_addr..].iter().take_while(|&&b| b != b'\0');
+        k.cmp(key.as_bytes().iter())
+    }
+    /// Returns the index of a given key in the map.
+    pub fn index_key(&self, key: &str) -> Option<usize> {
+        let (mut low, mut high) = (0, self.length);
+        while low < high {
+            let i = (low + high) / 2;
+            let key_offset_address = self.keys_address + i * self.keys_width.n_bytes();
+            let key_address =
+                deref_offset(self.buffer, key_offset_address, self.keys_width).ok()?;
+            match self.lazy_strcmp(key_address, key) {
+                Ordering::Equal => return Some(i),
+                Ordering::Less => low = if i == low { i + 1 } else { i },
+                Ordering::Greater => high = i,
+            }
+        }
+        None
+    }
+    /// Index into a map with a key or usize.
+    pub fn index<I: MapReaderIndexer>(&self, i: I) -> Result<Reader<'de>, Error> {
+        i.index_map_reader(self)
+    }
+    /// Index into a map with a key or usize. If any errors occur a Null reader is returned.
+    pub fn idx<I: MapReaderIndexer>(&self, i: I) -> Reader<'de> {
+        i.index_map_reader(self).unwrap_or_default()
+    }
+    fn usize_index(&self, i: usize) -> Result<Reader<'de>, Error> {
+        if i >= self.length {
+            return Err(Error::IndexOutOfBounds);
+        }
+        let data_address = self.values_address + self.values_width.n_bytes() * i;
+        let type_address = self.values_address + self.values_width.n_bytes() * self.length + i;
+        let (fxb_type, width) = self
+            .buffer
+            .get(type_address)
+            .ok_or(Error::FlexbufferOutOfBounds)
+            .and_then(|&b| unpack_type(b))?;
+        Reader::new(
+            &self.buffer,
+            data_address,
+            fxb_type,
+            width,
+            self.values_width,
+        )
+    }
+    fn key_index(&self, k: &str) -> Result<Reader<'de>, Error> {
+        let i = self.index_key(k).ok_or(Error::KeyNotFound)?;
+        self.usize_index(i)
+    }
+    /// Iterate over the values of the map.
+    pub fn iter_values(&self) -> ReaderIterator<'de> {
+        ReaderIterator::new(VectorReader {
+            reader: Reader {
+                buffer: self.buffer,
+                fxb_type: crate::FlexBufferType::Map,
+                width: self.values_width,
+                address: self.values_address,
+            },
+            length: self.length,
+        })
+    }
+    /// Iterate over the keys of the map.
+    pub fn iter_keys(
+        &self,
+    ) -> impl Iterator<Item = &'de str> + DoubleEndedIterator + ExactSizeIterator + FusedIterator
+    {
+        self.keys_vector().iter().map(|k| k.as_str())
+    }
+    pub fn keys_vector(&self) -> VectorReader<'de> {
+        VectorReader {
+            reader: Reader {
+                buffer: self.buffer,
+                fxb_type: crate::FlexBufferType::VectorKey,
+                width: self.keys_width,
+                address: self.keys_address,
+            },
+            length: self.length,
+        }
+    }
+}
+pub trait MapReaderIndexer {
+    fn index_map_reader<'de>(self, r: &MapReader<'de>) -> Result<Reader<'de>, Error>;
+}
+impl MapReaderIndexer for usize {
+    #[inline]
+    fn index_map_reader<'de>(self, r: &MapReader<'de>) -> Result<Reader<'de>, Error> {
+        r.usize_index(self)
+    }
+}
+impl MapReaderIndexer for &str {
+    #[inline]
+    fn index_map_reader<'de>(self, r: &MapReader<'de>) -> Result<Reader<'de>, Error> {
+        r.key_index(self)
+    }
+}
diff --git a/rust/flexbuffers/src/reader/mod.rs b/rust/flexbuffers/src/reader/mod.rs
new file mode 100644
index 0000000..4a3f472
--- /dev/null
+++ b/rust/flexbuffers/src/reader/mod.rs
@@ -0,0 +1,604 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use crate::bitwidth::BitWidth;
+use crate::flexbuffer_type::FlexBufferType;
+use crate::Blob;
+use std::convert::{TryFrom, TryInto};
+use std::fmt;
+use std::ops::Rem;
+use std::str::FromStr;
+mod de;
+mod iter;
+mod map;
+mod vector;
+pub use de::DeserializationError;
+pub use iter::ReaderIterator;
+pub use map::{MapReader, MapReaderIndexer};
+pub use vector::VectorReader;
+
+/// All the possible errors when reading a flexbuffer.
+#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
+pub enum Error {
+    /// One of the following data errors occured:
+    ///
+    /// *    The read flexbuffer had an offset that pointed outside the flexbuffer.
+    /// *    The 'negative indicies' where length and map keys are stored were out of bounds
+    /// *    The buffer was too small to contain a flexbuffer root.
+    FlexbufferOutOfBounds,
+    /// Failed to parse a valid FlexbufferType and Bitwidth from a type byte.
+    InvalidPackedType,
+    /// Flexbuffer type of the read data does not match function used.
+    UnexpectedFlexbufferType {
+        expected: FlexBufferType,
+        actual: FlexBufferType,
+    },
+    /// BitWidth type of the read data does not match function used.
+    UnexpectedBitWidth {
+        expected: BitWidth,
+        actual: BitWidth,
+    },
+    /// Read a flexbuffer offset or length that overflowed usize.
+    ReadUsizeOverflowed,
+    /// Tried to index a type that's not one of the Flexbuffer vector types.
+    CannotIndexAsVector,
+    /// Tried to index a Flexbuffer vector or map out of bounds.
+    IndexOutOfBounds,
+    /// A Map was indexed with a key that it did not contain.
+    KeyNotFound,
+    /// Failed to parse a Utf8 string.
+    /// The Option will be `None` if and only if this Error was deserialized.
+    // NOTE: std::str::Utf8Error does not implement Serialize, Deserialize, nor Default. We tell
+    // serde to skip the field and default to None. We prefer to have the boxed error so it can be
+    // used with std::error::Error::source, though another (worse) option could be to drop that
+    // information.
+    Utf8Error(#[serde(skip)] Option<Box<std::str::Utf8Error>>),
+    /// get_slice failed because the given data buffer is misaligned.
+    AlignmentError,
+    InvalidRootWidth,
+    InvalidMapKeysVectorWidth,
+}
+impl std::convert::From<std::str::Utf8Error> for Error {
+    fn from(e: std::str::Utf8Error) -> Self {
+        Self::Utf8Error(Some(Box::new(e)))
+    }
+}
+impl fmt::Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Self::UnexpectedBitWidth { expected, actual } => write!(
+                f,
+                "Error reading flexbuffer: Expected bitwidth: {:?}, found bitwidth: {:?}",
+                expected, actual
+            ),
+            Self::UnexpectedFlexbufferType { expected, actual } => write!(
+                f,
+                "Error reading flexbuffer: Expected type: {:?}, found type: {:?}",
+                expected, actual
+            ),
+            _ => write!(f, "Error reading flexbuffer: {:?}", self),
+        }
+    }
+}
+impl std::error::Error for Error {
+    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+        if let Self::Utf8Error(Some(e)) = self {
+            Some(e)
+        } else {
+            None
+        }
+    }
+}
+
+pub trait ReadLE: crate::private::Sealed + std::marker::Sized {
+    const VECTOR_TYPE: FlexBufferType;
+    const WIDTH: BitWidth;
+}
+macro_rules! rle {
+    ($T: ty, $VECTOR_TYPE: ident, $WIDTH: ident) => {
+        impl ReadLE for $T {
+            const VECTOR_TYPE: FlexBufferType = FlexBufferType::$VECTOR_TYPE;
+            const WIDTH: BitWidth = BitWidth::$WIDTH;
+        }
+    };
+}
+rle!(u8, VectorUInt, W8);
+rle!(u16, VectorUInt, W16);
+rle!(u32, VectorUInt, W32);
+rle!(u64, VectorUInt, W64);
+rle!(i8, VectorInt, W8);
+rle!(i16, VectorInt, W16);
+rle!(i32, VectorInt, W32);
+rle!(i64, VectorInt, W64);
+rle!(f32, VectorFloat, W32);
+rle!(f64, VectorFloat, W64);
+
+macro_rules! as_default {
+    ($as: ident, $get: ident, $T: ty) => {
+        pub fn $as(&self) -> $T {
+            self.$get().unwrap_or_default()
+        }
+    };
+}
+
+/// `Reader`s allow access to data stored in a Flexbuffer.
+///
+/// Each reader represents a single address in the buffer so data is read lazily. Start a reader
+/// by calling `get_root` on your flexbuffer `&[u8]`.
+///
+/// - The `get_T` methods return a `Result<T, Error>`. They return an OK value if and only if the
+/// flexbuffer type matches `T`. This is analogous to the behavior of Rust's json library, though
+/// with Result instead of Option.
+/// - The `as_T` methods will try their best to return to a value of type `T`
+/// (by casting or even parsing a string if necessary) but ultimately returns `T::default` if it
+/// fails. This behavior is analogous to that of flexbuffers C++.
+#[derive(Default, Clone)]
+pub struct Reader<'de> {
+    fxb_type: FlexBufferType,
+    width: BitWidth,
+    address: usize,
+    buffer: &'de [u8],
+}
+
+// manual implementation of Debug because buffer slice can't be automatically displayed
+impl<'de> std::fmt::Debug for Reader<'de> {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        // skips buffer field
+        f.debug_struct("Reader")
+            .field("fxb_type", &self.fxb_type)
+            .field("width", &self.width)
+            .field("address", &self.address)
+            .finish()
+    }
+}
+
+
+macro_rules! try_cast_fn {
+    ($name: ident, $full_width: ident, $Ty: ident) => {
+        pub fn $name(&self) -> $Ty {
+            self.$full_width().try_into().unwrap_or_default()
+        }
+    }
+}
+
+fn safe_sub(a: usize, b: usize) -> Result<usize, Error> {
+    a.checked_sub(b).ok_or(Error::FlexbufferOutOfBounds)
+}
+
+fn deref_offset(buffer: &[u8], address: usize, width: BitWidth) -> Result<usize, Error> {
+    let off = read_usize(buffer, address, width);
+    safe_sub(address, off)
+}
+
+impl<'de> Reader<'de> {
+    fn new(
+        buffer: &'de [u8],
+        mut address: usize,
+        mut fxb_type: FlexBufferType,
+        width: BitWidth,
+        parent_width: BitWidth,
+    ) -> Result<Self, Error> {
+        if fxb_type.is_reference() {
+            address = deref_offset(buffer, address, parent_width)?;
+            // Indirects were dereferenced.
+            if let Some(t) = fxb_type.to_direct() {
+                fxb_type = t;
+            }
+        }
+        Ok(Reader {
+            address,
+            fxb_type,
+            width,
+            buffer,
+        })
+    }
+    /// Parses the flexbuffer from the given buffer. Assumes the flexbuffer root is the last byte
+    /// of the buffer.
+    pub fn get_root(buffer: &'de [u8]) -> Result<Self, Error> {
+        let end = buffer.len();
+        if end < 3 {
+            return Err(Error::FlexbufferOutOfBounds);
+        }
+        // Last byte is the root width.
+        let root_width = BitWidth::from_nbytes(buffer[end - 1]).ok_or(Error::InvalidRootWidth)?;
+        // Second last byte is root type.
+        let (fxb_type, width) = unpack_type(buffer[end - 2])?;
+        // Location of root data. (BitWidth bits before root type)
+        let address = safe_sub(end - 2, root_width.n_bytes())?;
+        Self::new(buffer, address, fxb_type, width, root_width)
+    }
+    /// Returns the FlexBufferType of this Reader.
+    pub fn flexbuffer_type(&self) -> FlexBufferType {
+        self.fxb_type
+    }
+    /// Returns the bitwidth of this Reader.
+    pub fn bitwidth(&self) -> BitWidth {
+        self.width
+    }
+    /// Returns the length of the Flexbuffer. If the type has no length, or if an error occurs,
+    /// 0 is returned.
+    pub fn length(&self) -> usize {
+        if let Some(len) = self.fxb_type.fixed_length_vector_length() {
+            len
+        } else if self.fxb_type.has_length_slot() && self.address >= self.width.n_bytes() {
+            read_usize(self.buffer, self.address - self.width.n_bytes(), self.width)
+        } else {
+            0
+        }
+    }
+    /// Returns true if the flexbuffer is aligned to 8 bytes. This guarantees, for valid
+    /// flexbuffers, that the data is correctly aligned in memory and slices can be read directly
+    /// e.g. with `get_f64s` or `get_i16s`.
+    pub fn is_aligned(&self) -> bool {
+        (self.buffer.as_ptr() as usize).rem(8) == 0
+    }
+    as_default!(as_vector, get_vector, VectorReader<'de>);
+    as_default!(as_map, get_map, MapReader<'de>);
+
+    fn expect_type(&self, ty: FlexBufferType) -> Result<(), Error> {
+        if self.fxb_type == ty {
+            Ok(())
+        } else {
+            Err(Error::UnexpectedFlexbufferType {
+                expected: ty,
+                actual: self.fxb_type,
+            })
+        }
+    }
+    fn expect_bw(&self, bw: BitWidth) -> Result<(), Error> {
+        if self.width == bw {
+            Ok(())
+        } else {
+            Err(Error::UnexpectedBitWidth {
+                expected: bw,
+                actual: self.width,
+            })
+        }
+    }
+    /// Directly reads a slice of type `T`where `T` is one of `u8,u16,u32,u64,i8,i16,i32,i64,f32,f64`.
+    /// Returns Err if the type, bitwidth, or memory alignment does not match. Since the bitwidth is
+    /// dynamic, its better to use a VectorReader unless you know your data and performance is critical.
+    #[cfg(target_endian = "little")]
+    pub fn get_slice<T: ReadLE>(&self) -> Result<&'de [T], Error> {
+        if self.flexbuffer_type().typed_vector_type() != T::VECTOR_TYPE.typed_vector_type() {
+            self.expect_type(T::VECTOR_TYPE)?;
+        }
+        if self.bitwidth().n_bytes() != std::mem::size_of::<T>() {
+            self.expect_bw(T::WIDTH)?;
+        }
+        let end = self.address + self.length() * std::mem::size_of::<T>();
+        let slice = &self
+            .buffer
+            .get(self.address..end)
+            .ok_or(Error::FlexbufferOutOfBounds)?;
+        // `align_to` is required because the point of this function is to directly hand back a
+        // slice of scalars. This can fail because Rust's default allocator is not 16byte aligned
+        // (though in practice this only happens for small buffers).
+        let (pre, mid, suf) = unsafe { slice.align_to::<T>() };
+        if pre.is_empty() && suf.is_empty() {
+            Ok(mid)
+        } else {
+            Err(Error::AlignmentError)
+        }
+    }
+
+    pub fn get_bool(&self) -> Result<bool, Error> {
+        self.expect_type(FlexBufferType::Bool)?;
+        Ok(
+            self.buffer[self.address..self.address + self.width.n_bytes()]
+                .iter()
+                .any(|&b| b != 0),
+        )
+    }
+    pub fn get_key(&self) -> Result<&'de str, Error> {
+        self.expect_type(FlexBufferType::Key)?;
+        let (length, _) = self.buffer[self.address..]
+            .iter()
+            .enumerate()
+            .find(|(_, &b)| b == b'\0')
+            .unwrap_or((0, &0));
+        let bytes = &self.buffer[self.address..self.address + length];
+        Ok(std::str::from_utf8(bytes)?)
+    }
+    pub fn get_blob(&self) -> Result<Blob<'de>, Error> {
+        self.expect_type(FlexBufferType::Blob)?;
+        Ok(Blob(
+            &self.buffer[self.address..self.address + self.length()],
+        ))
+    }
+    pub fn as_blob(&self) -> Blob<'de> {
+        self.get_blob().unwrap_or(Blob(&[]))
+    }
+    pub fn get_str(&self) -> Result<&'de str, Error> {
+        self.expect_type(FlexBufferType::String)?;
+        let bytes = &self.buffer[self.address..self.address + self.length()];
+        Ok(std::str::from_utf8(bytes)?)
+    }
+    fn get_map_info(&self) -> Result<(usize, BitWidth), Error> {
+        self.expect_type(FlexBufferType::Map)?;
+        if 3 * self.width.n_bytes() >= self.address {
+            return Err(Error::FlexbufferOutOfBounds);
+        }
+        let keys_offset_address = self.address - 3 * self.width.n_bytes();
+        let keys_width = {
+            let kw_addr = self.address - 2 * self.width.n_bytes();
+            let kw = read_usize(self.buffer, kw_addr, self.width);
+            BitWidth::from_nbytes(kw).ok_or(Error::InvalidMapKeysVectorWidth)
+        }?;
+        Ok((keys_offset_address, keys_width))
+    }
+    pub fn get_map(&self) -> Result<MapReader<'de>, Error> {
+        let (keys_offset_address, keys_width) = self.get_map_info()?;
+        let keys_address = deref_offset(self.buffer, keys_offset_address, self.width)?;
+        // TODO(cneo): Check that vectors length equals keys length.
+        Ok(MapReader {
+            buffer: self.buffer,
+            values_address: self.address,
+            values_width: self.width,
+            keys_address,
+            keys_width,
+            length: self.length(),
+        })
+    }
+    /// Tries to read a FlexBufferType::UInt. Returns Err if the type is not a UInt or if the
+    /// address is out of bounds.
+    pub fn get_u64(&self) -> Result<u64, Error> {
+        self.expect_type(FlexBufferType::UInt)?;
+        let cursor = self
+            .buffer
+            .get(self.address..self.address + self.width.n_bytes());
+        match self.width {
+            BitWidth::W8 => cursor.map(|s| s[0] as u8).map(Into::into),
+            BitWidth::W16 => cursor
+                .and_then(|s| s.try_into().ok())
+                .map(<u16>::from_le_bytes)
+                .map(Into::into),
+            BitWidth::W32 => cursor
+                .and_then(|s| s.try_into().ok())
+                .map(<u32>::from_le_bytes)
+                .map(Into::into),
+            BitWidth::W64 => cursor
+                .and_then(|s| s.try_into().ok())
+                .map(<u64>::from_le_bytes),
+        }
+        .ok_or(Error::FlexbufferOutOfBounds)
+    }
+    /// Tries to read a FlexBufferType::Int. Returns Err if the type is not a UInt or if the
+    /// address is out of bounds.
+    pub fn get_i64(&self) -> Result<i64, Error> {
+        self.expect_type(FlexBufferType::Int)?;
+        let cursor = self
+            .buffer
+            .get(self.address..self.address + self.width.n_bytes());
+        match self.width {
+            BitWidth::W8 => cursor.map(|s| s[0] as i8).map(Into::into),
+            BitWidth::W16 => cursor
+                .and_then(|s| s.try_into().ok())
+                .map(<i16>::from_le_bytes)
+                .map(Into::into),
+            BitWidth::W32 => cursor
+                .and_then(|s| s.try_into().ok())
+                .map(<i32>::from_le_bytes)
+                .map(Into::into),
+            BitWidth::W64 => cursor
+                .and_then(|s| s.try_into().ok())
+                .map(<i64>::from_le_bytes),
+        }
+        .ok_or(Error::FlexbufferOutOfBounds)
+    }
+    /// Tries to read a FlexBufferType::Float. Returns Err if the type is not a UInt, if the
+    /// address is out of bounds, or if its a f16 or f8 (not currently supported).
+    pub fn get_f64(&self) -> Result<f64, Error> {
+        self.expect_type(FlexBufferType::Float)?;
+        let cursor = self
+            .buffer
+            .get(self.address..self.address + self.width.n_bytes());
+        match self.width {
+            BitWidth::W8 | BitWidth::W16 => return Err(Error::InvalidPackedType),
+            BitWidth::W32 => cursor
+                .and_then(|s| s.try_into().ok())
+                .map(f32_from_le_bytes)
+                .map(Into::into),
+            BitWidth::W64 => cursor
+                .and_then(|s| s.try_into().ok())
+                .map(f64_from_le_bytes),
+        }
+        .ok_or(Error::FlexbufferOutOfBounds)
+    }
+    pub fn as_bool(&self) -> bool {
+        use FlexBufferType::*;
+        match self.fxb_type {
+            Bool => self.get_bool().unwrap_or_default(),
+            UInt => self.as_u64() != 0,
+            Int => self.as_i64() != 0,
+            Float => self.as_f64().abs() > std::f64::EPSILON,
+            String | Key => !self.as_str().is_empty(),
+            Null => false,
+            Blob => self.length() != 0,
+            ty if ty.is_vector() => self.length() != 0,
+            _ => unreachable!(),
+        }
+    }
+    /// Returns a u64, casting if necessary. For Maps and Vectors, their length is
+    /// returned. If anything fails, 0 is returned.
+    pub fn as_u64(&self) -> u64 {
+        match self.fxb_type {
+            FlexBufferType::UInt => self.get_u64().unwrap_or_default(),
+            FlexBufferType::Int => self
+                .get_i64()
+                .unwrap_or_default()
+                .try_into()
+                .unwrap_or_default(),
+            FlexBufferType::Float => self.get_f64().unwrap_or_default() as u64,
+            FlexBufferType::String => {
+                if let Ok(s) = self.get_str() {
+                    if let Ok(f) = u64::from_str(s) {
+                        return f;
+                    }
+                }
+                0
+            }
+            _ if self.fxb_type.is_vector() => self.length() as u64,
+            _ => 0,
+        }
+    }
+    try_cast_fn!(as_u32, as_u64, u32);
+    try_cast_fn!(as_u16, as_u64, u16);
+    try_cast_fn!(as_u8, as_u64, u8);
+
+    /// Returns an i64, casting if necessary. For Maps and Vectors, their length is
+    /// returned. If anything fails, 0 is returned.
+    pub fn as_i64(&self) -> i64 {
+        match self.fxb_type {
+            FlexBufferType::Int => self.get_i64().unwrap_or_default(),
+            FlexBufferType::UInt => self
+                .get_u64()
+                .unwrap_or_default()
+                .try_into()
+                .unwrap_or_default(),
+            FlexBufferType::Float => self.get_f64().unwrap_or_default() as i64,
+            FlexBufferType::String => {
+                if let Ok(s) = self.get_str() {
+                    if let Ok(f) = i64::from_str(s) {
+                        return f;
+                    }
+                }
+                0
+            }
+            _ if self.fxb_type.is_vector() => self.length() as i64,
+            _ => 0,
+        }
+    }
+    try_cast_fn!(as_i32, as_i64, i32);
+    try_cast_fn!(as_i16, as_i64, i16);
+    try_cast_fn!(as_i8, as_i64, i8);
+
+    /// Returns an f64, casting if necessary. For Maps and Vectors, their length is
+    /// returned. If anything fails, 0 is returned.
+    pub fn as_f64(&self) -> f64 {
+        match self.fxb_type {
+            FlexBufferType::Int => self.get_i64().unwrap_or_default() as f64,
+            FlexBufferType::UInt => self.get_u64().unwrap_or_default() as f64,
+            FlexBufferType::Float => self.get_f64().unwrap_or_default(),
+            FlexBufferType::String => {
+                if let Ok(s) = self.get_str() {
+                    if let Ok(f) = f64::from_str(s) {
+                        return f;
+                    }
+                }
+                0.0
+            }
+            _ if self.fxb_type.is_vector() => self.length() as f64,
+            _ => 0.0,
+        }
+    }
+    pub fn as_f32(&self) -> f32 {
+        self.as_f64() as f32
+    }
+
+    /// Returns empty string if you're not trying to read a string.
+    pub fn as_str(&self) -> &'de str {
+        match self.fxb_type {
+            FlexBufferType::String => self.get_str().unwrap_or_default(),
+            FlexBufferType::Key => self.get_key().unwrap_or_default(),
+            _ => "",
+        }
+    }
+    pub fn get_vector(&self) -> Result<VectorReader<'de>, Error> {
+        if !self.fxb_type.is_vector() {
+            self.expect_type(FlexBufferType::Vector)?;
+        };
+        Ok(VectorReader {
+            reader: self.clone(),
+            length: self.length(),
+        })
+    }
+}
+
+impl<'de> fmt::Display for Reader<'de> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        use FlexBufferType::*;
+        match self.flexbuffer_type() {
+            Null => write!(f, "null"),
+            UInt => write!(f, "{}", self.as_u64()),
+            Int => write!(f, "{}", self.as_i64()),
+            Float => write!(f, "{}", self.as_f64()),
+            Key | String => write!(f, "{:?}", self.as_str()),
+            Bool => write!(f, "{}", self.as_bool()),
+            Blob => write!(f, "blob"),
+            Map => {
+                write!(f, "{{")?;
+                let m = self.as_map();
+                let mut pairs = m.iter_keys().zip(m.iter_values());
+                if let Some((k, v)) = pairs.next() {
+                    write!(f, "{:?}: {}", k, v)?;
+                    for (k, v) in pairs {
+                        write!(f, ", {:?}: {}", k, v)?;
+                    }
+                }
+                write!(f, "}}")
+            }
+            t if t.is_vector() => {
+                write!(f, "[")?;
+                let mut elems = self.as_vector().iter();
+                if let Some(first) = elems.next() {
+                    write!(f, "{}", first)?;
+                    for e in elems {
+                        write!(f, ", {}", e)?;
+                    }
+                }
+                write!(f, "]")
+            }
+            _ => unreachable!("Display not implemented for {:?}", self),
+        }
+    }
+}
+
+// TODO(cneo): Use <f..>::from_le_bytes when we move past rustc 1.39.
+fn f32_from_le_bytes(bytes: [u8; 4]) -> f32 {
+    let bits = <u32>::from_le_bytes(bytes);
+    <f32>::from_bits(bits)
+}
+fn f64_from_le_bytes(bytes: [u8; 8]) -> f64 {
+    let bits = <u64>::from_le_bytes(bytes);
+    <f64>::from_bits(bits)
+}
+
+fn read_usize(buffer: &[u8], address: usize, width: BitWidth) -> usize {
+    let cursor = &buffer[address..];
+    match width {
+        BitWidth::W8 => cursor[0] as usize,
+        BitWidth::W16 => cursor
+            .get(0..2)
+            .and_then(|s| s.try_into().ok())
+            .map(<u16>::from_le_bytes)
+            .unwrap_or_default() as usize,
+        BitWidth::W32 => cursor
+            .get(0..4)
+            .and_then(|s| s.try_into().ok())
+            .map(<u32>::from_le_bytes)
+            .unwrap_or_default() as usize,
+        BitWidth::W64 => cursor
+            .get(0..8)
+            .and_then(|s| s.try_into().ok())
+            .map(<u64>::from_le_bytes)
+            .unwrap_or_default() as usize,
+    }
+}
+
+fn unpack_type(ty: u8) -> Result<(FlexBufferType, BitWidth), Error> {
+    let w = BitWidth::try_from(ty & 3u8).map_err(|_| Error::InvalidPackedType)?;
+    let t = FlexBufferType::try_from(ty >> 2).map_err(|_| Error::InvalidPackedType)?;
+    Ok((t, w))
+}
diff --git a/rust/flexbuffers/src/reader/vector.rs b/rust/flexbuffers/src/reader/vector.rs
new file mode 100644
index 0000000..8ba8fe5
--- /dev/null
+++ b/rust/flexbuffers/src/reader/vector.rs
@@ -0,0 +1,74 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use super::{unpack_type, Error, Reader, ReaderIterator};
+use crate::{BitWidth, FlexBufferType};
+
+#[derive(Default, Clone)]
+/// Allows indexing on any flexbuffer vector type, (heterogenous vector, typed vector, or fixed
+/// length typed vector).
+///
+/// VectorReaders may be indexed with usize, `index` returns a result type
+/// which may indicate failure due to indexing out of bounds or bad data. `idx` returns a
+/// Null Reader in the event of any failure.
+pub struct VectorReader<'de> {
+    pub(super) reader: Reader<'de>,
+    // Cache the length because read_usize can be slow.
+    pub(super) length: usize,
+}
+
+impl<'de> VectorReader<'de> {
+    /// Returns the number of elements in the vector.
+    pub fn len(&self) -> usize {
+        self.length
+    }
+    /// Returns true if there are 0 elements in the vector.
+    pub fn is_empty(&self) -> bool {
+        self.length == 0
+    }
+    fn get_elem_type(&self, i: usize) -> Result<(FlexBufferType, BitWidth), Error> {
+        if let Some(ty) = self.reader.fxb_type.typed_vector_type() {
+            Ok((ty, self.reader.width))
+        } else {
+            let types_addr = self.reader.address + self.length * self.reader.width.n_bytes();
+            self.reader
+                .buffer
+                .get(types_addr + i)
+                .ok_or(Error::FlexbufferOutOfBounds)
+                .and_then(|&t| unpack_type(t))
+        }
+    }
+    /// Index into a flexbuffer vector. Any errors are defaulted to Null Readers.
+    pub fn idx(&self, i: usize) -> Reader<'de> {
+        self.index(i).unwrap_or_default()
+    }
+    /// Index into a flexbuffer.
+    pub fn index(&self, i: usize) -> Result<Reader<'de>, Error> {
+        if i >= self.length {
+            return Err(Error::IndexOutOfBounds);
+        }
+        let (fxb_type, bw) = self.get_elem_type(i)?;
+        let data_address = self.reader.address + self.reader.width.n_bytes() * i;
+        Reader::new(
+            self.reader.buffer,
+            data_address,
+            fxb_type,
+            bw,
+            self.reader.width,
+        )
+    }
+    pub fn iter(&self) -> ReaderIterator<'de> {
+        ReaderIterator::new(self.clone())
+    }
+}
