Repository: serde-rs/json (language: rust)

Issue:
Add a RawValue type
It would be helpful to have a type similar to Go's [`json.RawMessage`](https://golang.org/pkg/encoding/json/#RawMessage) that is not tokenized during deserialization, but rather its raw contents stored as a `Vec<u8>` or `&'de [u8]`.

The following pseudo-code demonstrates the idea.
```rust
#[derive(Deserialize)]
struct Struct {
    /// Deserialized normally.
    core_data: Vec<i32>,

    /// Contents of `user_data` are copied / borrowed directly from the input
    /// with no modification.
    ///
    /// `RawValue<'static>` is akin to `Vec<u8>`.
    /// `RawValue<'a>` is akin to `&'a [u8]`.
    user_data: serde_json::RawValue<'static>,
}

fn main() {
    let json = r#"
    {
        "core_data": [1, 2, 3],
        "user_data": { "foo": {}, "bar": 123, "baz": "abc" }
    }
    "#;
    
    let s: Struct = serde_json::from_bytes(&json).unwrap();
    println!("{}", s.user_data); // "{ \"foo\": {}, \"bar\": 123, \"baz\": \"abc\" }"
}
```

The main advantage of this is would be to have 'lazily-deserialized' values.


Discussion / hints:
@dtolnay mentions that the work happening in #416 might lay some groundwork for such a change to take place.
Yeah, this sounds useful. Ideally we could get some of the building blocks for this sort of thing (custom 'built-in' types) integrated into serde itself, in time.
I need this for a project I'm working on, and would be happy to give it shot following the same approach as #416. Is this something that you'd accept a PR for?
Yes I would like a PR for this. When you say you need this feature, is it because deserializing to serde_json::Value is too slow in your project and you are expecting this to have better performance, or some other reason?
Yeah, I've got an http web server that's backed by a postgres database which stores JSONB values, and would like to shuffle data back and forth (and embed into other payloads) with as few allocations as possible.
As a first step, please put together a short benchmark that you trust as reasonably representative of the shuffling data back and forth piece of your application. Ideally it would depend on serde / serde_derive / serde_json but nothing else -- so no postgres or http stuff. Focus on the data structures so that they have the same ratio and pattern of raw vs meaningful content as your real use case. Write it using serde_json::Value for now, and then the goal will be to swap in a raw value once it's implemented and observe a speedup.
Wrote a small microbenchmark here: https://gist.github.com/srijs/7fe21b43c2cf5d2ceeb593ae4591c6f5

Please let me know if this is what you had in mind!
:+1: looks good, let's make it work.

Fix patch:
diff --git a/Cargo.toml b/Cargo.toml
index 2f8ebe5ca..0ccec383a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -26,6 +26,12 @@ compiletest_rs = "0.3"
 serde_bytes = "0.10"
 serde_derive = "1.0"
 
+[package.metadata.docs.rs]
+features = ["raw_value"]
+
+[package.metadata.playground]
+features = ["raw_value"]
+
 
 ### FEATURES #################################################################
 
@@ -41,3 +47,6 @@ preserve_order = ["indexmap"]
 # allows JSON numbers of arbitrary size/precision to be read into a Number and
 # written back to a JSON string without loss of precision.
 arbitrary_precision = []
+
+# Provide a RawValue type that can hold unprocessed JSON during deserialization.
+raw_value = []
diff --git a/src/de.rs b/src/de.rs
index f1c5c3cff..7e44968e2 100644
--- a/src/de.rs
+++ b/src/de.rs
@@ -946,6 +946,17 @@ impl<'de, R: Read<'de>> Deserializer<R> {
             }
         }
     }
+
+    #[cfg(feature = "raw_value")]
+    fn deserialize_raw_value<V>(&mut self, visitor: V) -> Result<V::Value>
+    where
+        V: de::Visitor<'de>,
+    {
+        self.parse_whitespace()?;
+        self.read.begin_raw_buffering();
+        self.ignore_value()?;
+        self.read.end_raw_buffering(visitor)
+    }
 }
 
 impl FromStr for Number {
@@ -1412,10 +1423,18 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer<R> {
 
     /// Parses a newtype struct as the underlying value.
     #[inline]
-    fn deserialize_newtype_struct<V>(self, _name: &str, visitor: V) -> Result<V::Value>
+    fn deserialize_newtype_struct<V>(self, name: &str, visitor: V) -> Result<V::Value>
     where
         V: de::Visitor<'de>,
     {
+        #[cfg(feature = "raw_value")]
+        {
+            if name == ::raw::TOKEN {
+                return self.deserialize_raw_value(visitor);
+            }
+        }
+
+        let _ = name;
         visitor.visit_newtype_struct(self)
     }
 
diff --git a/src/lib.rs b/src/lib.rs
index d9b79175e..79513b320 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -389,3 +389,6 @@ pub mod value;
 mod iter;
 mod number;
 mod read;
+
+#[cfg(feature = "raw_value")]
+mod raw;
diff --git a/src/number.rs b/src/number.rs
index cc6bccb6c..fcf98ee78 100644
--- a/src/number.rs
+++ b/src/number.rs
@@ -26,12 +26,7 @@ use error::ErrorCode;
 #[cfg(feature = "arbitrary_precision")]
 /// Not public API. Should be pub(crate).
 #[doc(hidden)]
-pub const SERDE_STRUCT_FIELD_NAME: &'static str = "$__serde_private_number";
-
-#[cfg(feature = "arbitrary_precision")]
-/// Not public API. Should be pub(crate).
-#[doc(hidden)]
-pub const SERDE_STRUCT_NAME: &'static str = "$__serde_private_Number";
+pub const TOKEN: &'static str = "$serde_json::private::Number";
 
 /// Represents a JSON number, whether integer or floating point.
 #[derive(Clone, PartialEq)]
@@ -346,8 +341,8 @@ impl Serialize for Number {
     {
         use serde::ser::SerializeStruct;
 
-        let mut s = serializer.serialize_struct(SERDE_STRUCT_NAME, 1)?;
-        s.serialize_field(SERDE_STRUCT_FIELD_NAME, &self.n)?;
+        let mut s = serializer.serialize_struct(TOKEN, 1)?;
+        s.serialize_field(TOKEN, &self.n)?;
         s.end()
     }
 }
@@ -426,7 +421,7 @@ impl<'de> de::Deserialize<'de> for NumberKey {
             where
                 E: de::Error,
             {
-                if s == SERDE_STRUCT_FIELD_NAME {
+                if s == TOKEN {
                     Ok(())
                 } else {
                     Err(de::Error::custom("expected field with custom name"))
@@ -638,7 +633,7 @@ impl<'de> Deserializer<'de> for NumberFieldDeserializer {
     where
         V: de::Visitor<'de>,
     {
-        visitor.visit_borrowed_str(SERDE_STRUCT_FIELD_NAME)
+        visitor.visit_borrowed_str(TOKEN)
     }
 
     forward_to_deserialize_any! {
diff --git a/src/raw.rs b/src/raw.rs
new file mode 100644
index 000000000..54b85c79c
--- /dev/null
+++ b/src/raw.rs
@@ -0,0 +1,445 @@
+use std::fmt::{self, Debug, Display};
+use std::mem;
+
+use serde::ser::{Serialize, Serializer, SerializeStruct};
+use serde::de::{self, Deserialize, Deserializer, DeserializeSeed, IntoDeserializer, MapAccess, Unexpected, Visitor};
+use serde::de::value::BorrowedStrDeserializer;
+
+use error::Error;
+
+/// Reference to a range of bytes encompassing a single valid JSON value in the
+/// input data.
+///
+/// A `RawValue` can be used to defer parsing parts of a payload until later,
+/// or to avoid parsing it at all in the case that part of the payload just
+/// needs to be transferred verbatim into a different output object.
+///
+/// When serializing, a value of this type will retain its original formatting
+/// and will not be minified or pretty-printed.
+///
+/// # Example
+///
+/// ```
+/// #[macro_use]
+/// extern crate serde_derive;
+/// extern crate serde_json;
+///
+/// use serde_json::{Result, value::RawValue};
+///
+/// #[derive(Deserialize)]
+/// struct Input<'a> {
+///     code: u32,
+///     #[serde(borrow)]
+///     payload: &'a RawValue,
+/// }
+///
+/// #[derive(Serialize)]
+/// struct Output<'a> {
+///     info: (u32, &'a RawValue),
+/// }
+///
+/// // Efficiently rearrange JSON input containing separate "code" and "payload"
+/// // keys into a single "info" key holding an array of code and payload.
+/// //
+/// // This could be done equivalently using serde_json::Value as the type for
+/// // payload, but &RawValue will perform netter because it does not require
+/// // memory allocation. The correct range of bytes is borrowed from the input
+/// // data and pasted verbatim into the output.
+/// fn rearrange(input: &str) -> Result<String> {
+///     let input: Input = serde_json::from_str(input)?;
+///
+///     let output = Output {
+///         info: (input.code, input.payload),
+///     };
+///
+///     serde_json::to_string(&output)
+/// }
+///
+/// fn main() -> Result<()> {
+///     let out = rearrange(r#" {"code": 200, "payload": {}} "#)?;
+///
+///     assert_eq!(out, r#"{"info":[200,{}]}"#);
+///
+///     Ok(())
+/// }
+/// ```
+///
+/// # Ownership
+///
+/// The typical usage of `RawValue` will be in the borrowed form:
+///
+/// ```
+/// # #[macro_use]
+/// # extern crate serde_derive;
+/// # extern crate serde_json;
+/// #
+/// # use serde_json::value::RawValue;
+/// #
+/// #[derive(Deserialize)]
+/// struct SomeStruct<'a> {
+///     #[serde(borrow)]
+///     raw_value: &'a RawValue,
+/// }
+/// #
+/// # fn main() {}
+/// ```
+///
+/// The borrowed form is suitable when deserializing through
+/// [`serde_json::from_str`] and [`serde_json::from_slice`] which support
+/// borrowing from the input data without memory allocation.
+///
+/// When deserializing through [`serde_json::from_reader`] you will need to use
+/// the boxed form of `RawValue` instead. This is almost as efficient but
+/// involves buffering the raw value from the I/O stream into memory.
+///
+/// [`serde_json::from_str`]: ../fn.from_str.html
+/// [`serde_json::from_slice`]: ../fn.from_slice.html
+/// [`serde_json::from_reader`]: ../fn.from_reader.html
+///
+/// ```
+/// # #[macro_use]
+/// # extern crate serde_derive;
+/// # extern crate serde_json;
+/// #
+/// # use serde_json::value::RawValue;
+/// #
+/// #[derive(Deserialize)]
+/// struct SomeStruct {
+///     raw_value: Box<RawValue>,
+/// }
+/// #
+/// # fn main() {}
+/// ```
+///
+/// # Note
+///
+/// `RawValue` is only available if serde\_json is built with the `"raw_value"`
+/// feature.
+///
+/// ```toml
+/// [dependencies]
+/// serde_json = { version = "1.0", features = ["raw_value"] }
+/// ```
+#[repr(C)]
+pub struct RawValue {
+    json: str,
+}
+
+impl RawValue {
+    fn from_borrowed(json: &str) -> &Self {
+        unsafe { mem::transmute::<&str, &RawValue>(json) }
+    }
+
+    fn from_owned(json: Box<str>) -> Box<Self> {
+        unsafe { mem::transmute::<Box<str>, Box<RawValue>>(json) }
+    }
+}
+
+impl Clone for Box<RawValue> {
+    fn clone(&self) -> Self {
+        (**self).to_owned()
+    }
+}
+
+impl ToOwned for RawValue {
+    type Owned = Box<RawValue>;
+
+    fn to_owned(&self) -> Self::Owned {
+        RawValue::from_owned(self.json.to_owned().into_boxed_str())
+    }
+}
+
+impl Debug for RawValue {
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        formatter
+            .debug_tuple("RawValue")
+            .field(&format_args!("{}", &self.json))
+            .finish()
+    }
+}
+
+impl Display for RawValue {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.write_str(&self.json)
+    }
+}
+
+impl RawValue {
+    /// Access the JSON text underlying a raw value.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// #[macro_use]
+    /// extern crate serde_derive;
+    /// extern crate serde_json;
+    ///
+    /// use serde_json::{Result, value::RawValue};
+    ///
+    /// #[derive(Deserialize)]
+    /// struct Response<'a> {
+    ///     code: u32,
+    ///     #[serde(borrow)]
+    ///     payload: &'a RawValue,
+    /// }
+    ///
+    /// fn process(input: &str) -> Result<()> {
+    ///     let response: Response = serde_json::from_str(input)?;
+    ///
+    ///     let payload = response.payload.get();
+    ///     if payload.starts_with('{') {
+    ///         // handle a payload which is a JSON map
+    ///     } else {
+    ///         // handle any other type
+    ///     }
+    ///
+    ///     Ok(())
+    /// }
+    ///
+    /// fn main() -> Result<()> {
+    ///     process(r#" {"code": 200, "payload": {}} "#)?;
+    ///     Ok(())
+    /// }
+    /// ```
+    pub fn get(&self) -> &str {
+        &self.json
+    }
+}
+
+pub const TOKEN: &'static str = "$serde_json::private::RawValue";
+
+impl Serialize for RawValue {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        let mut s = serializer.serialize_struct(TOKEN, 1)?;
+        s.serialize_field(TOKEN, &self.json)?;
+        s.end()
+    }
+}
+
+impl<'de: 'a, 'a> Deserialize<'de> for &'a RawValue {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        struct ReferenceVisitor;
+
+        impl<'de> Visitor<'de> for ReferenceVisitor {
+            type Value = &'de RawValue;
+
+            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+                write!(formatter, "any valid JSON value")
+            }
+
+            fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
+            where
+                V: MapAccess<'de>,
+            {
+                let value = visitor.next_key::<RawKey>()?;
+                if value.is_none() {
+                    return Err(de::Error::invalid_type(Unexpected::Map, &self));
+                }
+                visitor.next_value_seed(ReferenceFromString)
+            }
+        }
+
+        deserializer.deserialize_newtype_struct(TOKEN, ReferenceVisitor)
+    }
+}
+
+impl<'de> Deserialize<'de> for Box<RawValue> {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        struct BoxedVisitor;
+
+        impl<'de> Visitor<'de> for BoxedVisitor {
+            type Value = Box<RawValue>;
+
+            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+                write!(formatter, "any valid JSON value")
+            }
+
+            fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
+            where
+                V: MapAccess<'de>,
+            {
+                let value = visitor.next_key::<RawKey>()?;
+                if value.is_none() {
+                    return Err(de::Error::invalid_type(Unexpected::Map, &self));
+                }
+                visitor.next_value_seed(BoxedFromString)
+            }
+        }
+
+        deserializer.deserialize_newtype_struct(TOKEN, BoxedVisitor)
+    }
+}
+
+struct RawKey;
+
+impl<'de> Deserialize<'de> for RawKey {
+    fn deserialize<D>(deserializer: D) -> Result<RawKey, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        struct FieldVisitor;
+
+        impl<'de> Visitor<'de> for FieldVisitor {
+            type Value = ();
+
+            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+                formatter.write_str("raw value")
+            }
+
+            fn visit_str<E>(self, s: &str) -> Result<(), E>
+            where
+                E: de::Error,
+            {
+                if s == TOKEN {
+                    Ok(())
+                } else {
+                    Err(de::Error::custom("unexpected raw value"))
+                }
+            }
+        }
+
+        deserializer.deserialize_identifier(FieldVisitor)?;
+        Ok(RawKey)
+    }
+}
+
+pub struct ReferenceFromString;
+
+impl<'de> DeserializeSeed<'de> for ReferenceFromString {
+    type Value = &'de RawValue;
+
+    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        deserializer.deserialize_str(self)
+    }
+}
+
+impl<'de> Visitor<'de> for ReferenceFromString {
+    type Value = &'de RawValue;
+
+    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        formatter.write_str("raw value")
+    }
+
+    fn visit_borrowed_str<E>(self, s: &'de str) -> Result<Self::Value, E>
+    where
+        E: de::Error,
+    {
+        Ok(RawValue::from_borrowed(s))
+    }
+}
+
+pub struct BoxedFromString;
+
+impl<'de> DeserializeSeed<'de> for BoxedFromString {
+    type Value = Box<RawValue>;
+
+    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        deserializer.deserialize_str(self)
+    }
+}
+
+impl<'de> Visitor<'de> for BoxedFromString {
+    type Value = Box<RawValue>;
+
+    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        formatter.write_str("raw value")
+    }
+
+    fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
+    where
+        E: de::Error,
+    {
+        self.visit_string(s.to_owned())
+    }
+
+    fn visit_string<E>(self, s: String) -> Result<Self::Value, E>
+    where
+        E: de::Error,
+    {
+        Ok(RawValue::from_owned(s.into_boxed_str()))
+    }
+}
+
+struct RawKeyDeserializer;
+
+impl<'de> Deserializer<'de> for RawKeyDeserializer {
+    type Error = Error;
+
+    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
+    where
+        V: de::Visitor<'de>,
+    {
+        visitor.visit_borrowed_str(TOKEN)
+    }
+
+    forward_to_deserialize_any! {
+        bool u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 char str string seq
+        bytes byte_buf map struct option unit newtype_struct ignored_any
+        unit_struct tuple_struct tuple enum identifier
+    }
+}
+
+pub struct OwnedRawDeserializer {
+    pub raw_value: Option<String>,
+}
+
+impl<'de> MapAccess<'de> for OwnedRawDeserializer {
+    type Error = Error;
+
+    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
+    where
+        K: de::DeserializeSeed<'de>,
+    {
+        if self.raw_value.is_none() {
+            return Ok(None);
+        }
+        seed.deserialize(RawKeyDeserializer).map(Some)
+    }
+
+    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
+    where
+        V: de::DeserializeSeed<'de>,
+    {
+        seed.deserialize(self.raw_value.take().unwrap().into_deserializer())
+    }
+}
+
+pub struct BorrowedRawDeserializer<'de> {
+    pub raw_value: Option<&'de str>,
+}
+
+impl<'de> MapAccess<'de> for BorrowedRawDeserializer<'de> {
+    type Error = Error;
+
+    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
+    where
+        K: de::DeserializeSeed<'de>,
+    {
+        if self.raw_value.is_none() {
+            return Ok(None);
+        }
+        seed.deserialize(RawKeyDeserializer).map(Some)
+    }
+
+    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
+    where
+        V: de::DeserializeSeed<'de>,
+    {
+        seed.deserialize(BorrowedStrDeserializer::new(self.raw_value.take().unwrap()))
+    }
+}
diff --git a/src/read.rs b/src/read.rs
index f2cc9f93b..fba1dd9f9 100644
--- a/src/read.rs
+++ b/src/read.rs
@@ -9,9 +9,15 @@
 use std::ops::Deref;
 use std::{char, cmp, io, str};
 
+#[cfg(feature = "raw_value")]
+use serde::de::Visitor;
+
 use iter::LineColIterator;
 
-use super::error::{Error, ErrorCode, Result};
+use error::{Error, ErrorCode, Result};
+
+#[cfg(feature = "raw_value")]
+use raw::{BorrowedRawDeserializer, OwnedRawDeserializer};
 
 /// Trait used by the deserializer for iterating over input. This is manually
 /// "specialized" for iterating over &[u8]. Once feature(specialization) is
@@ -76,6 +82,21 @@ pub trait Read<'de>: private::Sealed {
     /// string until the next quotation mark but discards the data.
     #[doc(hidden)]
     fn ignore_str(&mut self) -> Result<()>;
+
+    /// Switch raw buffering mode on.
+    ///
+    /// This is used when deserializing `RawValue`.
+    #[cfg(feature = "raw_value")]
+    #[doc(hidden)]
+    fn begin_raw_buffering(&mut self);
+
+    /// Switch raw buffering mode off and provides the raw buffered data to the
+    /// given visitor.
+    #[cfg(feature = "raw_value")]
+    #[doc(hidden)]
+    fn end_raw_buffering<V>(&mut self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>;
 }
 
 pub struct Position {
@@ -107,6 +128,8 @@ where
     iter: LineColIterator<io::Bytes<R>>,
     /// Temporary storage of peeked byte.
     ch: Option<u8>,
+    #[cfg(feature = "raw_value")]
+    raw_buffer: Option<Vec<u8>>,
 }
 
 /// JSON input source that reads from a slice of bytes.
@@ -117,6 +140,8 @@ pub struct SliceRead<'a> {
     slice: &'a [u8],
     /// Index of the *next* byte that will be returned by next() or peek().
     index: usize,
+    #[cfg(feature = "raw_value")]
+    raw_buffering_start_index: usize,
 }
 
 /// JSON input source that reads from a UTF-8 string.
@@ -124,6 +149,8 @@ pub struct SliceRead<'a> {
 // Able to elide UTF-8 checks by assuming that the input is valid UTF-8.
 pub struct StrRead<'a> {
     delegate: SliceRead<'a>,
+    #[cfg(feature = "raw_value")]
+    data: &'a str,
 }
 
 // Prevent users from implementing the Read trait.
@@ -139,9 +166,20 @@ where
 {
     /// Create a JSON input source to read from a std::io input stream.
     pub fn new(reader: R) -> Self {
-        IoRead {
-            iter: LineColIterator::new(reader.bytes()),
-            ch: None,
+        #[cfg(not(feature = "raw_value"))]
+        {
+            IoRead {
+                iter: LineColIterator::new(reader.bytes()),
+                ch: None,
+            }
+        }
+        #[cfg(feature = "raw_value")]
+        {
+            IoRead {
+                iter: LineColIterator::new(reader.bytes()),
+                ch: None,
+                raw_buffer: None,
+            }
         }
     }
 }
@@ -193,10 +231,26 @@ where
     #[inline]
     fn next(&mut self) -> io::Result<Option<u8>> {
         match self.ch.take() {
-            Some(ch) => Ok(Some(ch)),
+            Some(ch) => {
+                #[cfg(feature = "raw_value")]
+                {
+                    if let Some(ref mut buf) = self.raw_buffer {
+                        buf.push(ch);
+                    }
+                }
+                Ok(Some(ch))
+            }
             None => match self.iter.next() {
                 Some(Err(err)) => Err(err),
-                Some(Ok(ch)) => Ok(Some(ch)),
+                Some(Ok(ch)) => {
+                    #[cfg(feature = "raw_value")]
+                    {
+                        if let Some(ref mut buf) = self.raw_buffer {
+                            buf.push(ch);
+                        }
+                    }
+                    Ok(Some(ch))
+                }
                 None => Ok(None),
             },
         }
@@ -217,11 +271,21 @@ where
         }
     }
 
+    #[cfg(not(feature = "raw_value"))]
     #[inline]
     fn discard(&mut self) {
         self.ch = None;
     }
 
+    #[cfg(feature = "raw_value")]
+    fn discard(&mut self) {
+        if let Some(ch) = self.ch.take() {
+            if let Some(ref mut buf) = self.raw_buffer {
+                buf.push(ch);
+            }
+        }
+    }
+
     fn position(&self) -> Position {
         Position {
             line: self.iter.line(),
@@ -274,6 +338,21 @@ where
             }
         }
     }
+
+    #[cfg(feature = "raw_value")]
+    fn begin_raw_buffering(&mut self) {
+        self.raw_buffer = Some(Vec::new());
+    }
+
+    #[cfg(feature = "raw_value")]
+    fn end_raw_buffering<V>(&mut self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        let raw = self.raw_buffer.take().unwrap();
+        let raw = String::from_utf8(raw).unwrap();
+        visitor.visit_map(OwnedRawDeserializer { raw_value: Some(raw) })
+    }
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -281,9 +360,20 @@ where
 impl<'a> SliceRead<'a> {
     /// Create a JSON input source to read from a slice of bytes.
     pub fn new(slice: &'a [u8]) -> Self {
-        SliceRead {
-            slice: slice,
-            index: 0,
+        #[cfg(not(feature = "raw_value"))]
+        {
+            SliceRead {
+                slice: slice,
+                index: 0,
+            }
+        }
+        #[cfg(feature = "raw_value")]
+        {
+            SliceRead {
+                slice: slice,
+                index: 0,
+                raw_buffering_start_index: 0,
+            }
         }
     }
 
@@ -437,6 +527,21 @@ impl<'a> Read<'a> for SliceRead<'a> {
             }
         }
     }
+
+    #[cfg(feature = "raw_value")]
+    fn begin_raw_buffering(&mut self) {
+        self.raw_buffering_start_index = self.index;
+    }
+
+    #[cfg(feature = "raw_value")]
+    fn end_raw_buffering<V>(&mut self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'a>,
+    {
+        let raw = &self.slice[self.raw_buffering_start_index..self.index];
+        let raw = str::from_utf8(raw).unwrap();
+        visitor.visit_map(BorrowedRawDeserializer { raw_value: Some(raw) })
+    }
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -444,8 +549,18 @@ impl<'a> Read<'a> for SliceRead<'a> {
 impl<'a> StrRead<'a> {
     /// Create a JSON input source to read from a UTF-8 string.
     pub fn new(s: &'a str) -> Self {
-        StrRead {
-            delegate: SliceRead::new(s.as_bytes()),
+        #[cfg(not(feature = "raw_value"))]
+        {
+            StrRead {
+                delegate: SliceRead::new(s.as_bytes()),
+            }
+        }
+        #[cfg(feature = "raw_value")]
+        {
+            StrRead {
+                delegate: SliceRead::new(s.as_bytes()),
+                data: s,
+            }
         }
     }
 }
@@ -498,6 +613,20 @@ impl<'a> Read<'a> for StrRead<'a> {
     fn ignore_str(&mut self) -> Result<()> {
         self.delegate.ignore_str()
     }
+
+    #[cfg(feature = "raw_value")]
+    fn begin_raw_buffering(&mut self) {
+        self.delegate.begin_raw_buffering()
+    }
+
+    #[cfg(feature = "raw_value")]
+    fn end_raw_buffering<V>(&mut self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'a>,
+    {
+        let raw = &self.data[self.delegate.raw_buffering_start_index..self.delegate.index];
+        visitor.visit_map(BorrowedRawDeserializer { raw_value: Some(raw) })
+    }
 }
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/src/ser.rs b/src/ser.rs
index ca9b637ee..eceb4e6b4 100644
--- a/src/ser.rs
+++ b/src/ser.rs
@@ -14,14 +14,11 @@ use std::num::FpCategory;
 use std::str;
 
 use super::error::{Error, ErrorCode, Result};
-use serde::ser::{self, Impossible};
+use serde::ser::{self, Impossible, Serialize};
 
 use itoa;
 use ryu;
 
-#[cfg(feature = "arbitrary_precision")]
-use serde::Serialize;
-
 /// A structure for serializing Rust values into JSON.
 pub struct Serializer<W, F = CompactFormatter> {
     writer: W,
@@ -288,7 +285,7 @@ where
     #[inline]
     fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T) -> Result<()>
     where
-        T: ser::Serialize,
+        T: Serialize,
     {
         value.serialize(self)
     }
@@ -302,7 +299,7 @@ where
         value: &T,
     ) -> Result<()>
     where
-        T: ser::Serialize,
+        T: Serialize,
     {
         try!(
             self.formatter
@@ -347,7 +344,7 @@ where
     #[inline]
     fn serialize_some<T: ?Sized>(self, value: &T) -> Result<()>
     where
-        T: ser::Serialize,
+        T: Serialize,
     {
         value.serialize(self)
     }
@@ -462,7 +459,9 @@ where
     fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
         match name {
             #[cfg(feature = "arbitrary_precision")]
-            ::number::SERDE_STRUCT_NAME => Ok(Compound::Number { ser: self }),
+            ::number::TOKEN => Ok(Compound::Number { ser: self }),
+            #[cfg(feature = "raw_value")]
+            ::raw::TOKEN => Ok(Compound::RawValue { ser: self }),
             _ => self.serialize_map(Some(len)),
         }
     }
@@ -573,6 +572,8 @@ pub enum Compound<'a, W: 'a, F: 'a> {
     },
     #[cfg(feature = "arbitrary_precision")]
     Number { ser: &'a mut Serializer<W, F> },
+    #[cfg(feature = "raw_value")]
+    RawValue { ser: &'a mut Serializer<W, F> },
 }
 
 impl<'a, W, F> ser::SerializeSeq for Compound<'a, W, F>
@@ -586,7 +587,7 @@ where
     #[inline]
     fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
     where
-        T: ser::Serialize,
+        T: Serialize,
     {
         match *self {
             Compound::Map {
@@ -609,6 +610,8 @@ where
             }
             #[cfg(feature = "arbitrary_precision")]
             Compound::Number { .. } => unreachable!(),
+            #[cfg(feature = "raw_value")]
+            Compound::RawValue { .. } => unreachable!(),
         }
     }
 
@@ -624,6 +627,8 @@ where
             }
             #[cfg(feature = "arbitrary_precision")]
             Compound::Number { .. } => unreachable!(),
+            #[cfg(feature = "raw_value")]
+            Compound::RawValue { .. } => unreachable!(),
         }
     }
 }
@@ -639,7 +644,7 @@ where
     #[inline]
     fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
     where
-        T: ser::Serialize,
+        T: Serialize,
     {
         ser::SerializeSeq::serialize_element(self, value)
     }
@@ -661,7 +666,7 @@ where
     #[inline]
     fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>
     where
-        T: ser::Serialize,
+        T: Serialize,
     {
         ser::SerializeSeq::serialize_element(self, value)
     }
@@ -683,7 +688,7 @@ where
     #[inline]
     fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>
     where
-        T: ser::Serialize,
+        T: Serialize,
     {
         ser::SerializeSeq::serialize_element(self, value)
     }
@@ -706,6 +711,8 @@ where
             }
             #[cfg(feature = "arbitrary_precision")]
             Compound::Number { .. } => unreachable!(),
+            #[cfg(feature = "raw_value")]
+            Compound::RawValue { .. } => unreachable!(),
         }
     }
 }
@@ -721,7 +728,7 @@ where
     #[inline]
     fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()>
     where
-        T: ser::Serialize,
+        T: Serialize,
     {
         match *self {
             Compound::Map {
@@ -746,13 +753,15 @@ where
             }
             #[cfg(feature = "arbitrary_precision")]
             Compound::Number { .. } => unreachable!(),
+            #[cfg(feature = "raw_value")]
+            Compound::RawValue { .. } => unreachable!(),
         }
     }
 
     #[inline]
     fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()>
     where
-        T: ser::Serialize,
+        T: Serialize,
     {
         match *self {
             Compound::Map { ref mut ser, .. } => {
@@ -771,6 +780,8 @@ where
             }
             #[cfg(feature = "arbitrary_precision")]
             Compound::Number { .. } => unreachable!(),
+            #[cfg(feature = "raw_value")]
+            Compound::RawValue { .. } => unreachable!(),
         }
     }
 
@@ -786,6 +797,8 @@ where
             }
             #[cfg(feature = "arbitrary_precision")]
             Compound::Number { .. } => unreachable!(),
+            #[cfg(feature = "raw_value")]
+            Compound::RawValue { .. } => unreachable!(),
         }
     }
 }
@@ -801,7 +814,7 @@ where
     #[inline]
     fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<()>
     where
-        T: ser::Serialize,
+        T: Serialize,
     {
         match *self {
             Compound::Map { .. } => {
@@ -810,13 +823,22 @@ where
             }
             #[cfg(feature = "arbitrary_precision")]
             Compound::Number { ref mut ser, .. } => {
-                if key == ::number::SERDE_STRUCT_FIELD_NAME {
+                if key == ::number::TOKEN {
                     try!(value.serialize(NumberStrEmitter(&mut *ser)));
                     Ok(())
                 } else {
                     Err(invalid_number())
                 }
             }
+            #[cfg(feature = "raw_value")]
+            Compound::RawValue { ref mut ser, .. } => {
+                if key == ::raw::TOKEN {
+                    try!(value.serialize(RawValueStrEmitter(&mut *ser)));
+                    Ok(())
+                } else {
+                    Err(invalid_raw_value())
+                }
+            }
         }
     }
 
@@ -826,6 +848,8 @@ where
             Compound::Map { .. } => ser::SerializeMap::end(self),
             #[cfg(feature = "arbitrary_precision")]
             Compound::Number { .. } => Ok(()),
+            #[cfg(feature = "raw_value")]
+            Compound::RawValue { .. } => Ok(()),
         }
     }
 }
@@ -841,12 +865,14 @@ where
     #[inline]
     fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<()>
     where
-        T: ser::Serialize,
+        T: Serialize,
     {
         match *self {
             Compound::Map { .. } => ser::SerializeStruct::serialize_field(self, key, value),
             #[cfg(feature = "arbitrary_precision")]
             Compound::Number { .. } => unreachable!(),
+            #[cfg(feature = "raw_value")]
+            Compound::RawValue { .. } => unreachable!(),
         }
     }
 
@@ -868,6 +894,8 @@ where
             }
             #[cfg(feature = "arbitrary_precision")]
             Compound::Number { .. } => unreachable!(),
+            #[cfg(feature = "raw_value")]
+            Compound::RawValue { .. } => unreachable!(),
         }
     }
 }
@@ -881,6 +909,11 @@ fn invalid_number() -> Error {
     Error::syntax(ErrorCode::InvalidNumber, 0, 0)
 }
 
+#[cfg(feature = "raw_value")]
+fn invalid_raw_value() -> Error {
+    Error::syntax(ErrorCode::ExpectedSomeValue, 0, 0)
+}
+
 fn key_must_be_a_string() -> Error {
     Error::syntax(ErrorCode::KeyMustBeAString, 0, 0)
 }
@@ -911,7 +944,7 @@ where
     #[inline]
     fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T) -> Result<()>
     where
-        T: ser::Serialize,
+        T: Serialize,
     {
         value.serialize(self)
     }
@@ -1154,7 +1187,7 @@ where
         _value: &T,
     ) -> Result<()>
     where
-        T: ser::Serialize,
+        T: Serialize,
     {
         Err(key_must_be_a_string())
     }
@@ -1165,7 +1198,7 @@ where
 
     fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<()>
     where
-        T: ser::Serialize,
+        T: Serialize,
     {
         Err(key_must_be_a_string())
     }
@@ -1400,6 +1433,191 @@ impl<'a, W: io::Write, F: Formatter> ser::Serializer for NumberStrEmitter<'a, W,
     }
 }
 
+#[cfg(feature = "raw_value")]
+struct RawValueStrEmitter<'a, W: 'a + io::Write, F: 'a + Formatter>(&'a mut Serializer<W, F>);
+
+#[cfg(feature = "raw_value")]
+impl<'a, W: io::Write, F: Formatter> ser::Serializer for RawValueStrEmitter<'a, W, F> {
+    type Ok = ();
+    type Error = Error;
+
+    type SerializeSeq = Impossible<(), Error>;
+    type SerializeTuple = Impossible<(), Error>;
+    type SerializeTupleStruct = Impossible<(), Error>;
+    type SerializeTupleVariant = Impossible<(), Error>;
+    type SerializeMap = Impossible<(), Error>;
+    type SerializeStruct = Impossible<(), Error>;
+    type SerializeStructVariant = Impossible<(), Error>;
+
+    fn serialize_bool(self, _v: bool) -> Result<Self::Ok> {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    fn serialize_i8(self, _v: i8) -> Result<Self::Ok> {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    fn serialize_i16(self, _v: i16) -> Result<Self::Ok> {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    fn serialize_i32(self, _v: i32) -> Result<Self::Ok> {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    fn serialize_i64(self, _v: i64) -> Result<Self::Ok> {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    serde_if_integer128! {
+        fn serialize_i128(self, _v: i128) -> Result<Self::Ok> {
+            Err(ser::Error::custom("expected RawValue"))
+        }
+    }
+
+    fn serialize_u8(self, _v: u8) -> Result<Self::Ok> {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    fn serialize_u16(self, _v: u16) -> Result<Self::Ok> {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    fn serialize_u32(self, _v: u32) -> Result<Self::Ok> {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    fn serialize_u64(self, _v: u64) -> Result<Self::Ok> {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    serde_if_integer128! {
+        fn serialize_u128(self, _v: u128) -> Result<Self::Ok> {
+            Err(ser::Error::custom("expected RawValue"))
+        }
+    }
+
+    fn serialize_f32(self, _v: f32) -> Result<Self::Ok> {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    fn serialize_f64(self, _v: f64) -> Result<Self::Ok> {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    fn serialize_char(self, _v: char) -> Result<Self::Ok> {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    fn serialize_str(self, value: &str) -> Result<Self::Ok> {
+        let RawValueStrEmitter(serializer) = self;
+        serializer
+            .formatter
+            .write_raw_fragment(&mut serializer.writer, value)
+            .map_err(Error::io)
+    }
+
+    fn serialize_bytes(self, _value: &[u8]) -> Result<Self::Ok> {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    fn serialize_none(self) -> Result<Self::Ok> {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<Self::Ok>
+    where
+        T: Serialize,
+    {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    fn serialize_unit(self) -> Result<Self::Ok> {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    fn serialize_unit_variant(
+        self,
+        _name: &'static str,
+        _variant_index: u32,
+        _variant: &'static str,
+    ) -> Result<Self::Ok> {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    fn serialize_newtype_struct<T: ?Sized>(
+        self,
+        _name: &'static str,
+        _value: &T,
+    ) -> Result<Self::Ok>
+    where
+        T: Serialize,
+    {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    fn serialize_newtype_variant<T: ?Sized>(
+        self,
+        _name: &'static str,
+        _variant_index: u32,
+        _variant: &'static str,
+        _value: &T,
+    ) -> Result<Self::Ok>
+    where
+        T: Serialize,
+    {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    fn serialize_tuple_struct(
+        self,
+        _name: &'static str,
+        _len: usize,
+    ) -> Result<Self::SerializeTupleStruct> {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    fn serialize_tuple_variant(
+        self,
+        _name: &'static str,
+        _variant_index: u32,
+        _variant: &'static str,
+        _len: usize,
+    ) -> Result<Self::SerializeTupleVariant> {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+
+    fn serialize_struct_variant(
+        self,
+        _name: &'static str,
+        _variant_index: u32,
+        _variant: &'static str,
+        _len: usize,
+    ) -> Result<Self::SerializeStructVariant> {
+        Err(ser::Error::custom("expected RawValue"))
+    }
+}
+
 /// Represents a character escape code in a type-safe manner.
 pub enum CharEscape {
     /// An escaped quote `"`
@@ -1743,6 +1961,16 @@ pub trait Formatter {
     {
         Ok(())
     }
+
+    /// Writes a raw JSON fragment that doesn't need any escaping to the
+    /// specified writer.
+    #[inline]
+    fn write_raw_fragment<W: ?Sized>(&mut self, writer: &mut W, fragment: &str) -> io::Result<()>
+    where
+        W: io::Write,
+    {
+        writer.write_all(fragment.as_bytes())
+    }
 }
 
 /// This structure compacts a JSON value with no extra whitespace.
@@ -1979,7 +2207,7 @@ static ESCAPE: [u8; 256] = [
 pub fn to_writer<W, T: ?Sized>(writer: W, value: &T) -> Result<()>
 where
     W: io::Write,
-    T: ser::Serialize,
+    T: Serialize,
 {
     let mut ser = Serializer::new(writer);
     try!(value.serialize(&mut ser));
@@ -1997,7 +2225,7 @@ where
 pub fn to_writer_pretty<W, T: ?Sized>(writer: W, value: &T) -> Result<()>
 where
     W: io::Write,
-    T: ser::Serialize,
+    T: Serialize,
 {
     let mut ser = Serializer::pretty(writer);
     try!(value.serialize(&mut ser));
@@ -2013,7 +2241,7 @@ where
 #[inline]
 pub fn to_vec<T: ?Sized>(value: &T) -> Result<Vec<u8>>
 where
-    T: ser::Serialize,
+    T: Serialize,
 {
     let mut writer = Vec::with_capacity(128);
     try!(to_writer(&mut writer, value));
@@ -2029,7 +2257,7 @@ where
 #[inline]
 pub fn to_vec_pretty<T: ?Sized>(value: &T) -> Result<Vec<u8>>
 where
-    T: ser::Serialize,
+    T: Serialize,
 {
     let mut writer = Vec::with_capacity(128);
     try!(to_writer_pretty(&mut writer, value));
@@ -2045,7 +2273,7 @@ where
 #[inline]
 pub fn to_string<T: ?Sized>(value: &T) -> Result<String>
 where
-    T: ser::Serialize,
+    T: Serialize,
 {
     let vec = try!(to_vec(value));
     let string = unsafe {
@@ -2064,7 +2292,7 @@ where
 #[inline]
 pub fn to_string_pretty<T: ?Sized>(value: &T) -> Result<String>
 where
-    T: ser::Serialize,
+    T: Serialize,
 {
     let vec = try!(to_vec_pretty(value));
     let string = unsafe {
diff --git a/src/value/de.rs b/src/value/de.rs
index dc8dbc6be..ba99840c5 100644
--- a/src/value/de.rs
+++ b/src/value/de.rs
@@ -116,7 +116,12 @@ impl<'de> Deserialize<'de> for Value {
                     #[cfg(feature = "arbitrary_precision")]
                     Some(KeyClass::Number) => {
                         let number: NumberFromString = visitor.next_value()?;
-                        return Ok(Value::Number(number.value));
+                        Ok(Value::Number(number.value))
+                    }
+                    #[cfg(feature = "raw_value")]
+                    Some(KeyClass::RawValue) => {
+                        let value = visitor.next_value_seed(::raw::BoxedFromString)?;
+                        ::from_str(value.get()).map_err(de::Error::custom)
                     }
                     Some(KeyClass::Map(first_key)) => {
                         let mut values = Map::new();
@@ -300,12 +305,22 @@ impl<'de> serde::Deserializer<'de> for Value {
     #[inline]
     fn deserialize_newtype_struct<V>(
         self,
-        _name: &'static str,
+        name: &'static str,
         visitor: V,
     ) -> Result<V::Value, Self::Error>
     where
         V: Visitor<'de>,
     {
+        #[cfg(feature = "raw_value")]
+        {
+            if name == ::raw::TOKEN {
+                return visitor.visit_map(::raw::OwnedRawDeserializer {
+                    raw_value: Some(self.to_string()),
+                });
+            }
+        }
+
+        let _ = name;
         visitor.visit_newtype_struct(self)
     }
 
@@ -829,12 +844,22 @@ impl<'de> serde::Deserializer<'de> for &'de Value {
     #[inline]
     fn deserialize_newtype_struct<V>(
         self,
-        _name: &'static str,
+        name: &'static str,
         visitor: V,
     ) -> Result<V::Value, Self::Error>
     where
         V: Visitor<'de>,
     {
+        #[cfg(feature = "raw_value")]
+        {
+            if name == ::raw::TOKEN {
+                return visitor.visit_map(::raw::OwnedRawDeserializer {
+                    raw_value: Some(self.to_string()),
+                });
+            }
+        }
+
+        let _ = name;
         visitor.visit_newtype_struct(self)
     }
 
@@ -1292,6 +1317,8 @@ enum KeyClass {
     Map(String),
     #[cfg(feature = "arbitrary_precision")]
     Number,
+    #[cfg(feature = "raw_value")]
+    RawValue,
 }
 
 impl<'de> DeserializeSeed<'de> for KeyClassifier {
@@ -1318,7 +1345,9 @@ impl<'de> Visitor<'de> for KeyClassifier {
     {
         match s {
             #[cfg(feature = "arbitrary_precision")]
-            ::number::SERDE_STRUCT_FIELD_NAME => Ok(KeyClass::Number),
+            ::number::TOKEN => Ok(KeyClass::Number),
+            #[cfg(feature = "raw_value")]
+            ::raw::TOKEN => Ok(KeyClass::RawValue),
             _ => Ok(KeyClass::Map(s.to_owned())),
         }
     }
@@ -1329,7 +1358,9 @@ impl<'de> Visitor<'de> for KeyClassifier {
     {
         match s.as_str() {
             #[cfg(feature = "arbitrary_precision")]
-            ::number::SERDE_STRUCT_FIELD_NAME => Ok(KeyClass::Number),
+            ::number::TOKEN => Ok(KeyClass::Number),
+            #[cfg(feature = "raw_value")]
+            ::raw::TOKEN => Ok(KeyClass::RawValue),
             _ => Ok(KeyClass::Map(s)),
         }
     }
diff --git a/src/value/mod.rs b/src/value/mod.rs
index f5e33b457..c976af501 100644
--- a/src/value/mod.rs
+++ b/src/value/mod.rs
@@ -119,6 +119,9 @@ use error::Error;
 pub use map::Map;
 pub use number::Number;
 
+#[cfg(feature = "raw_value")]
+pub use raw::RawValue;
+
 pub use self::index::Index;
 
 use self::ser::Serializer;
diff --git a/src/value/ser.rs b/src/value/ser.rs
index d3f71b373..172784cce 100644
--- a/src/value/ser.rs
+++ b/src/value/ser.rs
@@ -14,9 +14,6 @@ use map::Map;
 use number::Number;
 use value::{to_value, Value};
 
-#[cfg(feature = "arbitrary_precision")]
-use serde::ser;
-
 impl Serialize for Value {
     #[inline]
     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -232,7 +229,9 @@ impl serde::Serializer for Serializer {
     ) -> Result<Self::SerializeStruct, Error> {
         match name {
             #[cfg(feature = "arbitrary_precision")]
-            ::number::SERDE_STRUCT_NAME => Ok(SerializeMap::Number { out_value: None }),
+            ::number::TOKEN => Ok(SerializeMap::Number { out_value: None }),
+            #[cfg(feature = "raw_value")]
+            ::raw::TOKEN => Ok(SerializeMap::RawValue { out_value: None }),
             _ => self.serialize_map(Some(len)),
         }
     }
@@ -267,6 +266,8 @@ pub enum SerializeMap {
     },
     #[cfg(feature = "arbitrary_precision")]
     Number { out_value: Option<Value> },
+    #[cfg(feature = "raw_value")]
+    RawValue { out_value: Option<Value> },
 }
 
 pub struct SerializeStructVariant {
@@ -361,6 +362,8 @@ impl serde::ser::SerializeMap for SerializeMap {
             }
             #[cfg(feature = "arbitrary_precision")]
             SerializeMap::Number { .. } => unreachable!(),
+            #[cfg(feature = "raw_value")]
+            SerializeMap::RawValue { .. } => unreachable!(),
         }
     }
 
@@ -382,6 +385,8 @@ impl serde::ser::SerializeMap for SerializeMap {
             }
             #[cfg(feature = "arbitrary_precision")]
             SerializeMap::Number { .. } => unreachable!(),
+            #[cfg(feature = "raw_value")]
+            SerializeMap::RawValue { .. } => unreachable!(),
         }
     }
 
@@ -390,6 +395,8 @@ impl serde::ser::SerializeMap for SerializeMap {
             SerializeMap::Map { map, .. } => Ok(Value::Object(map)),
             #[cfg(feature = "arbitrary_precision")]
             SerializeMap::Number { .. } => unreachable!(),
+            #[cfg(feature = "raw_value")]
+            SerializeMap::RawValue { .. } => unreachable!(),
         }
     }
 }
@@ -592,13 +599,22 @@ impl serde::ser::SerializeStruct for SerializeMap {
             }
             #[cfg(feature = "arbitrary_precision")]
             SerializeMap::Number { ref mut out_value } => {
-                if key == ::number::SERDE_STRUCT_FIELD_NAME {
+                if key == ::number::TOKEN {
                     *out_value = Some(value.serialize(NumberValueEmitter)?);
                     Ok(())
                 } else {
                     Err(invalid_number())
                 }
             }
+            #[cfg(feature = "raw_value")]
+            SerializeMap::RawValue { ref mut out_value } => {
+                if key == ::raw::TOKEN {
+                    *out_value = Some(value.serialize(RawValueEmitter)?);
+                    Ok(())
+                } else {
+                    Err(invalid_raw_value())
+                }
+            }
         }
     }
 
@@ -609,6 +625,10 @@ impl serde::ser::SerializeStruct for SerializeMap {
             SerializeMap::Number { out_value, .. } => {
                 Ok(out_value.expect("number value was not emitted"))
             }
+            #[cfg(feature = "raw_value")]
+            SerializeMap::RawValue { out_value, .. } => {
+                Ok(out_value.expect("raw value was not emitted"))
+            }
         }
     }
 }
@@ -643,7 +663,7 @@ fn invalid_number() -> Error {
 }
 
 #[cfg(feature = "arbitrary_precision")]
-impl ser::Serializer for NumberValueEmitter {
+impl serde::ser::Serializer for NumberValueEmitter {
     type Ok = Value;
     type Error = Error;
 
@@ -812,3 +832,181 @@ impl ser::Serializer for NumberValueEmitter {
         Err(invalid_number())
     }
 }
+
+#[cfg(feature = "raw_value")]
+struct RawValueEmitter;
+
+#[cfg(feature = "raw_value")]
+fn invalid_raw_value() -> Error {
+    Error::syntax(ErrorCode::ExpectedSomeValue, 0, 0)
+}
+
+#[cfg(feature = "raw_value")]
+impl serde::ser::Serializer for RawValueEmitter {
+    type Ok = Value;
+    type Error = Error;
+
+    type SerializeSeq = Impossible<Value, Error>;
+    type SerializeTuple = Impossible<Value, Error>;
+    type SerializeTupleStruct = Impossible<Value, Error>;
+    type SerializeTupleVariant = Impossible<Value, Error>;
+    type SerializeMap = Impossible<Value, Error>;
+    type SerializeStruct = Impossible<Value, Error>;
+    type SerializeStructVariant = Impossible<Value, Error>;
+
+    fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_str(self, value: &str) -> Result<Self::Ok, Self::Error> {
+        ::from_str(value)
+    }
+
+    fn serialize_bytes(self, _value: &[u8]) -> Result<Self::Ok, Self::Error> {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<Self::Ok, Self::Error>
+    where
+        T: Serialize,
+    {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_unit_variant(
+        self,
+        _name: &'static str,
+        _variant_index: u32,
+        _variant: &'static str,
+    ) -> Result<Self::Ok, Self::Error> {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_newtype_struct<T: ?Sized>(
+        self,
+        _name: &'static str,
+        _value: &T,
+    ) -> Result<Self::Ok, Self::Error>
+    where
+        T: Serialize,
+    {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_newtype_variant<T: ?Sized>(
+        self,
+        _name: &'static str,
+        _variant_index: u32,
+        _variant: &'static str,
+        _value: &T,
+    ) -> Result<Self::Ok, Self::Error>
+    where
+        T: Serialize,
+    {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_tuple_struct(
+        self,
+        _name: &'static str,
+        _len: usize,
+    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_tuple_variant(
+        self,
+        _name: &'static str,
+        _variant_index: u32,
+        _variant: &'static str,
+        _len: usize,
+    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_struct(
+        self,
+        _name: &'static str,
+        _len: usize,
+    ) -> Result<Self::SerializeStruct, Self::Error> {
+        Err(invalid_raw_value())
+    }
+
+    fn serialize_struct_variant(
+        self,
+        _name: &'static str,
+        _variant_index: u32,
+        _variant: &'static str,
+        _len: usize,
+    ) -> Result<Self::SerializeStructVariant, Self::Error> {
+        Err(invalid_raw_value())
+    }
+}


Test patch:
diff --git a/tests/test.rs b/tests/test.rs
index 08d038837..ec2de425e 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -938,9 +938,9 @@ fn test_serialize_char() {
 #[test]
 fn test_malicious_number() {
     #[derive(Serialize)]
-    #[serde(rename = "$__serde_private_Number")]
+    #[serde(rename = "$serde_json::private::Number")]
     struct S {
-        #[serde(rename = "$__serde_private_number")]
+        #[serde(rename = "$serde_json::private::Number")]
         f: &'static str,
     }
 
@@ -2039,3 +2039,88 @@ fn test_integer128() {
         ),
     ]);
 }
+
+#[cfg(feature = "raw_value")]
+#[test]
+fn test_borrowed_raw_value() {
+    use serde_json::value::RawValue;
+
+    #[derive(Serialize, Deserialize)]
+    struct Wrapper<'a> {
+        a: i8,
+        #[serde(borrow)]
+        b: &'a RawValue,
+        c: i8,
+    };
+
+    let wrapper_from_str: Wrapper =
+        serde_json::from_str(r#"{"a": 1, "b": {"foo": 2}, "c": 3}"#).unwrap();
+    assert_eq!(r#"{"foo": 2}"#, wrapper_from_str.b.get());
+
+    let wrapper_to_string = serde_json::to_string(&wrapper_from_str).unwrap();
+    assert_eq!(r#"{"a":1,"b":{"foo": 2},"c":3}"#, wrapper_to_string);
+
+    let wrapper_to_value = serde_json::to_value(&wrapper_from_str).unwrap();
+    assert_eq!(json!({"a": 1, "b": {"foo": 2}, "c": 3}), wrapper_to_value);
+
+    let array_from_str: Vec<&RawValue> =
+        serde_json::from_str(r#"["a", 42, {"foo": "bar"}, null]"#).unwrap();
+    assert_eq!(r#""a""#, array_from_str[0].get());
+    assert_eq!(r#"42"#, array_from_str[1].get());
+    assert_eq!(r#"{"foo": "bar"}"#, array_from_str[2].get());
+    assert_eq!(r#"null"#, array_from_str[3].get());
+
+    let array_to_string = serde_json::to_string(&array_from_str).unwrap();
+    assert_eq!(r#"["a",42,{"foo": "bar"},null]"#, array_to_string);
+}
+
+#[cfg(feature = "raw_value")]
+#[test]
+fn test_boxed_raw_value() {
+    use serde_json::value::RawValue;
+
+    #[derive(Serialize, Deserialize)]
+    struct Wrapper {
+        a: i8,
+        b: Box<RawValue>,
+        c: i8,
+    };
+
+    let wrapper_from_str: Wrapper =
+        serde_json::from_str(r#"{"a": 1, "b": {"foo": 2}, "c": 3}"#).unwrap();
+    assert_eq!(r#"{"foo": 2}"#, wrapper_from_str.b.get());
+
+    let wrapper_from_reader: Wrapper = serde_json::from_reader(
+        br#"{"a": 1, "b": {"foo": 2}, "c": 3}"#.as_ref(),
+    ).unwrap();
+    assert_eq!(r#"{"foo": 2}"#, wrapper_from_reader.b.get());
+
+    let wrapper_from_value: Wrapper =
+        serde_json::from_value(json!({"a": 1, "b": {"foo": 2}, "c": 3}))
+            .unwrap();
+    assert_eq!(r#"{"foo":2}"#, wrapper_from_value.b.get());
+
+    let wrapper_to_string = serde_json::to_string(&wrapper_from_str).unwrap();
+    assert_eq!(r#"{"a":1,"b":{"foo": 2},"c":3}"#, wrapper_to_string);
+
+    let wrapper_to_value = serde_json::to_value(&wrapper_from_str).unwrap();
+    assert_eq!(json!({"a": 1, "b": {"foo": 2}, "c": 3}), wrapper_to_value);
+
+    let array_from_str: Vec<Box<RawValue>> =
+        serde_json::from_str(r#"["a", 42, {"foo": "bar"}, null]"#).unwrap();
+    assert_eq!(r#""a""#, array_from_str[0].get());
+    assert_eq!(r#"42"#, array_from_str[1].get());
+    assert_eq!(r#"{"foo": "bar"}"#, array_from_str[2].get());
+    assert_eq!(r#"null"#, array_from_str[3].get());
+
+    let array_from_reader: Vec<Box<RawValue>> = serde_json::from_reader(
+        br#"["a", 42, {"foo": "bar"}, null]"#.as_ref(),
+    ).unwrap();
+    assert_eq!(r#""a""#, array_from_reader[0].get());
+    assert_eq!(r#"42"#, array_from_reader[1].get());
+    assert_eq!(r#"{"foo": "bar"}"#, array_from_reader[2].get());
+    assert_eq!(r#"null"#, array_from_reader[3].get());
+
+    let array_to_string = serde_json::to_string(&array_from_str).unwrap();
+    assert_eq!(r#"["a",42,{"foo": "bar"},null]"#, array_to_string);
+}