use crate::{Error, ErrorKind, Event, JsonNum, Lexer, Parser, ValueKind};
pub fn parse<'input, T: FromJson<'input>>(input: &'input [u8]) -> Result<T, Error> {
let mut p: Parser<'input> = Parser::new(input);
let lex = p.lexer();
let value = T::from_lex(lex)?;
lex.finish()?;
Ok(value)
}
pub fn parse_str<'input, T: FromJson<'input>>(input: &'input str) -> Result<T, Error> {
parse(input.as_bytes())
}
pub trait FromJson<'input>: Sized {
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error>;
#[cfg(feature = "alloc")]
#[doc(hidden)]
fn vec_from_lex(lex: &mut Lexer<'input>) -> Result<alloc::vec::Vec<Self>, Error> {
let mut out = alloc::vec::Vec::new();
if lex.array_start()? {
return Ok(out);
}
out.push(Self::from_lex(lex)?);
while !lex.array_continue(b']')? {
out.push(Self::from_lex(lex)?);
}
Ok(out)
}
}
#[inline]
const fn type_error(lex: &Lexer<'_>, kind: ErrorKind) -> Error {
Error::new(kind, lex.position())
}
impl<'input> FromJson<'input> for bool {
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
match lex.read_value()? {
Event::Bool(b) => Ok(b),
_ => Err(type_error(lex, ErrorKind::ExpectedBool)),
}
}
}
impl<'input> FromJson<'input> for () {
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
match lex.read_value()? {
Event::Null => Ok(()),
_ => Err(type_error(lex, ErrorKind::ExpectedNull)),
}
}
}
impl<'input> FromJson<'input> for &'input str {
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
match lex.peek_value_kind()? {
ValueKind::String => lex.parse_str_value(),
_ => Err(type_error(lex, ErrorKind::ExpectedString)),
}
}
#[cfg(feature = "alloc")]
fn vec_from_lex(lex: &mut Lexer<'input>) -> Result<alloc::vec::Vec<Self>, Error> {
let mut out: alloc::vec::Vec<&'input str> = alloc::vec::Vec::new();
if lex.array_start()? {
return Ok(out);
}
out.push(lex.parse_str_value()?);
while !lex.array_continue(b']')? {
out.push(lex.parse_str_value()?);
}
Ok(out)
}
}
macro_rules! impl_int {
($($t:ty => $accessor:ident),* $(,)?) => {
$(
impl<'input> FromJson<'input> for $t {
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
match lex.peek_value_kind()? {
ValueKind::Number => {
let n: JsonNum = lex.read_number()?;
let big = n.$accessor(lex.input())
.map_err(|kind| Error::new(kind, lex.position()))?;
<$t>::try_from(big).map_err(|_| {
Error::new(ErrorKind::NumberOutOfRange, lex.position())
})
}
_ => Err(type_error(lex, ErrorKind::ExpectedNumber)),
}
}
#[cfg(feature = "alloc")]
fn vec_from_lex(lex: &mut Lexer<'input>) -> Result<alloc::vec::Vec<Self>, Error> {
let mut out: alloc::vec::Vec<Self> = alloc::vec::Vec::new();
if lex.array_start()? {
return Ok(out);
}
let v = lex.parse_i64_value()?;
out.push(<$t>::try_from(v).map_err(|_| {
Error::new(ErrorKind::NumberOutOfRange, lex.position())
})?);
while !lex.array_continue(b']')? {
let v = lex.parse_i64_value()?;
out.push(<$t>::try_from(v).map_err(|_| {
Error::new(ErrorKind::NumberOutOfRange, lex.position())
})?);
}
Ok(out)
}
}
)*
};
}
impl_int!(i8 => as_i64, i16 => as_i64, i32 => as_i64, i64 => as_i64, isize => as_i64);
impl_int!(u8 => as_u64, u16 => as_u64, u32 => as_u64, u64 => as_u64, usize => as_u64);
macro_rules! impl_int_wide {
($($t:ty => $parse_fn:ident),* $(,)?) => {
$(
impl<'input> FromJson<'input> for $t {
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
match lex.peek_value_kind()? {
ValueKind::Number => lex.$parse_fn(),
_ => Err(type_error(lex, ErrorKind::ExpectedNumber)),
}
}
#[cfg(feature = "alloc")]
fn vec_from_lex(lex: &mut Lexer<'input>) -> Result<alloc::vec::Vec<Self>, Error> {
let mut out: alloc::vec::Vec<Self> = alloc::vec::Vec::new();
if lex.array_start()? {
return Ok(out);
}
out.push(lex.$parse_fn()?);
while !lex.array_continue(b']')? {
out.push(lex.$parse_fn()?);
}
Ok(out)
}
}
)*
};
}
impl_int_wide!(i128 => parse_i128_value, u128 => parse_u128_value);
impl<'input> FromJson<'input> for f64 {
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
match lex.peek_value_kind()? {
ValueKind::Number => lex.parse_f64_value(),
_ => Err(type_error(lex, ErrorKind::ExpectedNumber)),
}
}
#[cfg(feature = "alloc")]
fn vec_from_lex(lex: &mut Lexer<'input>) -> Result<alloc::vec::Vec<Self>, Error> {
let mut out: alloc::vec::Vec<Self> = alloc::vec::Vec::new();
if lex.array_start()? {
return Ok(out);
}
out.push(lex.parse_f64_value()?);
while !lex.array_continue(b']')? {
out.push(lex.parse_f64_value()?);
}
Ok(out)
}
}
impl<'input> FromJson<'input> for f32 {
#[allow(clippy::cast_possible_truncation)]
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
let v = f64::from_lex(lex)?;
let narrowed = v as Self;
if narrowed.is_finite() {
Ok(narrowed)
} else {
Err(Error::new(ErrorKind::NumberOutOfRange, lex.position()))
}
}
}
impl<'input, T: FromJson<'input>> FromJson<'input> for Option<T> {
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
match lex.peek_value_kind()? {
ValueKind::Null => {
let _ = lex.read_value()?;
Ok(None)
}
_ => Ok(Some(T::from_lex(lex)?)),
}
}
}
impl<'input, T: FromJson<'input>, const N: usize> FromJson<'input> for [T; N] {
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
let mut slots: [Option<T>; N] = core::array::from_fn(|_| None);
let empty = lex.array_start()?;
if empty {
if N == 0 {
return Ok(core::array::from_fn(|i| {
slots[i].take().expect("slot filled")
}));
}
return Err(type_error(lex, ErrorKind::TypeMismatch));
}
for (i, slot) in slots.iter_mut().enumerate() {
*slot = Some(T::from_lex(lex)?);
let closed = lex.array_continue(b']')?;
if closed {
if i + 1 == N {
return Ok(core::array::from_fn(|i| {
slots[i].take().expect("slot filled")
}));
}
return Err(type_error(lex, ErrorKind::TypeMismatch));
}
}
Err(type_error(lex, ErrorKind::TypeMismatch))
}
}
macro_rules! impl_tuple {
($last:tt: $LAST:ident $(, $idx:tt: $T:ident)*) => {
impl<'input, $LAST: FromJson<'input> $(, $T: FromJson<'input>)*>
FromJson<'input> for ($LAST, $($T,)*)
{
#[allow(non_snake_case)]
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
if lex.array_start()? {
return Err(type_error(lex, ErrorKind::TypeMismatch));
}
let $LAST = <$LAST>::from_lex(lex)?;
$(
if lex.array_continue(b']')? {
return Err(type_error(lex, ErrorKind::TypeMismatch));
}
let $T = <$T>::from_lex(lex)?;
)*
if !lex.array_continue(b']')? {
return Err(type_error(lex, ErrorKind::TypeMismatch));
}
let _ = ($last $(, $idx)*); Ok(($LAST, $($T,)*))
}
}
};
}
impl_tuple!(0: A);
impl_tuple!(0: A, 1: B);
impl_tuple!(0: A, 1: B, 2: C);
impl_tuple!(0: A, 1: B, 2: C, 3: D);
impl_tuple!(0: A, 1: B, 2: C, 3: D, 4: E);
impl_tuple!(0: A, 1: B, 2: C, 3: D, 4: E, 5: F);
#[cfg(feature = "alloc")]
pub use alloc_impls::{MapKey, key_to_cow};
#[cfg(feature = "alloc")]
mod alloc_impls {
extern crate alloc;
use super::{FromJson, type_error};
use crate::{Error, ErrorKind, JsonStr, Lexer, ValueKind};
use alloc::borrow::Cow;
use alloc::string::String;
use alloc::vec::Vec;
impl<'input> FromJson<'input> for String {
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
match lex.peek_value_kind()? {
ValueKind::String => {
let js = lex.read_string_no_validate()?;
decode_string(js, lex)
}
_ => Err(type_error(lex, ErrorKind::ExpectedString)),
}
}
}
impl<'input> FromJson<'input> for Cow<'input, str> {
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
match lex.peek_value_kind()? {
ValueKind::String => {
let js = lex.read_string_no_validate()?;
if let Some(borrowed) = js.as_str(lex.input()) {
return Ok(Cow::Borrowed(borrowed));
}
Ok(Cow::Owned(decode_owned(js, lex)?))
}
_ => Err(type_error(lex, ErrorKind::ExpectedString)),
}
}
}
impl<'input> FromJson<'input> for char {
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
match lex.peek_value_kind()? {
ValueKind::String => {
let js = lex.read_string_no_validate()?;
if let Some(borrowed) = js.as_str(lex.input()) {
return single_char(borrowed)
.ok_or_else(|| type_error(lex, ErrorKind::TypeMismatch));
}
let decoded = decode_owned(js, lex)?;
single_char(&decoded).ok_or_else(|| type_error(lex, ErrorKind::TypeMismatch))
}
_ => Err(type_error(lex, ErrorKind::ExpectedString)),
}
}
}
pub fn key_to_cow<'input>(js: JsonStr, lex: &Lexer<'input>) -> Result<Cow<'input, str>, Error> {
if let Some(borrowed) = js.as_str(lex.input()) {
return Ok(Cow::Borrowed(borrowed));
}
Ok(Cow::Owned(decode_owned(js, lex)?))
}
pub trait MapKey<'input>: Sized {
fn from_key(key: Cow<'input, str>, lex: &Lexer<'input>) -> Result<Self, Error>;
}
impl<'input> MapKey<'input> for String {
#[inline]
fn from_key(key: Cow<'input, str>, _lex: &Lexer<'input>) -> Result<Self, Error> {
Ok(key.into_owned())
}
}
impl<'input> MapKey<'input> for Cow<'input, str> {
#[inline]
fn from_key(key: Self, _lex: &Lexer<'input>) -> Result<Self, Error> {
Ok(key)
}
}
impl<'input> MapKey<'input> for &'input str {
#[inline]
fn from_key(key: Cow<'input, str>, lex: &Lexer<'input>) -> Result<Self, Error> {
match key {
Cow::Borrowed(s) => Ok(s),
Cow::Owned(_) => Err(type_error(lex, ErrorKind::InvalidEscape)),
}
}
}
trait DupMap<K, V> {
fn new_empty() -> Self;
fn try_insert(&mut self, k: K, v: V) -> bool;
}
impl<K: Ord, V> DupMap<K, V> for alloc::collections::BTreeMap<K, V> {
fn new_empty() -> Self {
Self::new()
}
fn try_insert(&mut self, k: K, v: V) -> bool {
self.insert(k, v).is_none()
}
}
#[cfg(feature = "std")]
impl<K, V, S> DupMap<K, V> for std::collections::HashMap<K, V, S>
where
K: ::core::hash::Hash + Eq,
S: ::core::hash::BuildHasher + Default,
{
fn new_empty() -> Self {
Self::with_hasher(S::default())
}
fn try_insert(&mut self, k: K, v: V) -> bool {
self.insert(k, v).is_none()
}
}
#[cfg(feature = "indexmap")]
impl<K, V, S> DupMap<K, V> for indexmap::IndexMap<K, V, S>
where
K: ::core::hash::Hash + Eq,
S: ::core::hash::BuildHasher + Default,
{
fn new_empty() -> Self {
Self::with_hasher(S::default())
}
fn try_insert(&mut self, k: K, v: V) -> bool {
self.insert(k, v).is_none()
}
}
fn parse_map<'input, K, V, M>(lex: &mut Lexer<'input>) -> Result<M, Error>
where
K: MapKey<'input>,
V: FromJson<'input>,
M: DupMap<K, V>,
{
if !matches!(lex.peek_value_kind()?, ValueKind::Object) {
return Err(type_error(lex, ErrorKind::TypeMismatch));
}
lex.object_start()?;
let mut out = M::new_empty();
let mut maybe_key = lex.object_first_key_lex()?;
while let Some(js) = maybe_key {
let key_cow = key_to_cow(js, lex)?;
let key = K::from_key(key_cow, lex)?;
let v = V::from_lex(lex)?;
if !out.try_insert(key, v) {
return Err(Error::new(ErrorKind::DuplicateKey, lex.position()));
}
maybe_key = lex.object_next_key_lex()?;
}
Ok(out)
}
impl<'input, K, V> FromJson<'input> for alloc::collections::BTreeMap<K, V>
where
K: MapKey<'input> + Ord,
V: FromJson<'input>,
{
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
parse_map(lex)
}
}
#[cfg(feature = "std")]
impl<'input, K, V, S> FromJson<'input> for std::collections::HashMap<K, V, S>
where
K: MapKey<'input> + ::core::hash::Hash + Eq,
V: FromJson<'input>,
S: ::core::hash::BuildHasher + Default,
{
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
parse_map(lex)
}
}
trait SetInsert<T> {
fn new_empty() -> Self;
fn push(&mut self, v: T);
}
impl<T: Ord> SetInsert<T> for alloc::collections::BTreeSet<T> {
fn new_empty() -> Self {
Self::new()
}
fn push(&mut self, v: T) {
self.insert(v);
}
}
#[cfg(feature = "std")]
impl<T, S> SetInsert<T> for std::collections::HashSet<T, S>
where
T: ::core::hash::Hash + Eq,
S: ::core::hash::BuildHasher + Default,
{
fn new_empty() -> Self {
Self::with_hasher(S::default())
}
fn push(&mut self, v: T) {
self.insert(v);
}
}
#[cfg(feature = "indexmap")]
impl<T, S> SetInsert<T> for indexmap::IndexSet<T, S>
where
T: ::core::hash::Hash + Eq,
S: ::core::hash::BuildHasher + Default,
{
fn new_empty() -> Self {
Self::with_hasher(S::default())
}
fn push(&mut self, v: T) {
self.insert(v);
}
}
fn parse_set<'input, T, C>(lex: &mut Lexer<'input>) -> Result<C, Error>
where
T: FromJson<'input>,
C: SetInsert<T>,
{
let mut out = C::new_empty();
if lex.array_start()? {
return Ok(out);
}
out.push(T::from_lex(lex)?);
while !lex.array_continue(b']')? {
out.push(T::from_lex(lex)?);
}
Ok(out)
}
impl<'input, T> FromJson<'input> for alloc::collections::BTreeSet<T>
where
T: FromJson<'input> + Ord,
{
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
parse_set(lex)
}
}
#[cfg(feature = "std")]
impl<'input, T, S> FromJson<'input> for std::collections::HashSet<T, S>
where
T: FromJson<'input> + ::core::hash::Hash + Eq,
S: ::core::hash::BuildHasher + Default,
{
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
parse_set(lex)
}
}
#[cfg(feature = "std")]
impl<'input> FromJson<'input> for std::time::Duration {
#[allow(clippy::cast_precision_loss)]
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
let secs_f = match lex.peek_value_kind()? {
ValueKind::Number => lex.parse_f64_value()?,
_ => return Err(type_error(lex, ErrorKind::ExpectedNumber)),
};
if !secs_f.is_finite() || secs_f < 0.0 || secs_f >= (u64::MAX as f64) {
return Err(type_error(lex, ErrorKind::NumberOutOfRange));
}
Ok(Self::from_secs_f64(secs_f))
}
#[cfg(feature = "alloc")]
#[allow(clippy::cast_precision_loss)]
fn vec_from_lex(lex: &mut Lexer<'input>) -> Result<alloc::vec::Vec<Self>, Error> {
#[inline]
fn convert(lex: &Lexer<'_>, secs_f: f64) -> Result<std::time::Duration, Error> {
if !secs_f.is_finite() || secs_f < 0.0 || secs_f >= (u64::MAX as f64) {
return Err(type_error(lex, ErrorKind::NumberOutOfRange));
}
Ok(std::time::Duration::from_secs_f64(secs_f))
}
let mut out: alloc::vec::Vec<Self> = alloc::vec::Vec::new();
if lex.array_start()? {
return Ok(out);
}
let secs_f = lex.parse_f64_value()?;
out.push(convert(lex, secs_f)?);
while !lex.array_continue(b']')? {
let secs_f = lex.parse_f64_value()?;
out.push(convert(lex, secs_f)?);
}
Ok(out)
}
}
#[cfg(feature = "std")]
impl<'input> FromJson<'input> for std::time::SystemTime {
#[allow(clippy::cast_precision_loss)]
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
let secs_f = match lex.peek_value_kind()? {
ValueKind::Number => lex.parse_f64_value()?,
_ => return Err(type_error(lex, ErrorKind::ExpectedNumber)),
};
if !secs_f.is_finite() || secs_f.abs() >= (u64::MAX as f64) {
return Err(type_error(lex, ErrorKind::NumberOutOfRange));
}
let abs = std::time::Duration::from_secs_f64(secs_f.abs());
let epoch = std::time::UNIX_EPOCH;
let st = if secs_f < 0.0 {
epoch.checked_sub(abs)
} else {
epoch.checked_add(abs)
};
st.ok_or_else(|| type_error(lex, ErrorKind::NumberOutOfRange))
}
}
#[cfg(feature = "std")]
fn parse_from_str<'input, T>(lex: &mut Lexer<'input>) -> Result<T, Error>
where
T: ::core::str::FromStr,
{
let cow: Cow<'input, str> = Cow::<'input, str>::from_lex(lex)?;
cow.parse::<T>()
.map_err(|_| type_error(lex, ErrorKind::TypeMismatch))
}
#[cfg(feature = "std")]
impl<'input> FromJson<'input> for std::net::IpAddr {
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
parse_from_str(lex)
}
}
#[cfg(feature = "std")]
impl<'input> FromJson<'input> for std::net::Ipv4Addr {
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
parse_from_str(lex)
}
}
#[cfg(feature = "std")]
impl<'input> FromJson<'input> for std::net::Ipv6Addr {
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
parse_from_str(lex)
}
}
#[cfg(feature = "std")]
impl<'input> FromJson<'input> for std::net::SocketAddr {
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
parse_from_str(lex)
}
}
#[cfg(feature = "std")]
impl<'input> FromJson<'input> for std::path::PathBuf {
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
let s: String = String::from_lex(lex)?;
Ok(Self::from(s))
}
}
impl<'input, T: FromJson<'input>> FromJson<'input> for alloc::boxed::Box<T> {
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
T::from_lex(lex).map(Self::new)
}
}
impl<'input, T: FromJson<'input>> FromJson<'input> for alloc::rc::Rc<T> {
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
T::from_lex(lex).map(Self::new)
}
}
impl<'input, T: FromJson<'input>> FromJson<'input> for alloc::sync::Arc<T> {
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
T::from_lex(lex).map(Self::new)
}
}
#[inline]
fn single_char(s: &str) -> Option<char> {
let mut it = s.chars();
let c = it.next()?;
if it.next().is_some() {
return None;
}
Some(c)
}
#[inline]
fn decode_string(js: JsonStr, lex: &Lexer<'_>) -> Result<String, Error> {
if let Some(borrowed) = js.as_str(lex.input()) {
return Ok(String::from(borrowed));
}
decode_owned(js, lex)
}
fn decode_owned(s: JsonStr, lex: &Lexer<'_>) -> Result<String, Error> {
let raw = s
.raw_bytes(lex.input())
.ok_or_else(|| Error::new(ErrorKind::InvalidEscape, lex.position()))?;
let mut out = String::with_capacity(raw.len());
decode_escapes(raw, &mut out).map_err(|kind| Error::new(kind, lex.position()))?;
Ok(out)
}
impl<'input, T: FromJson<'input>> FromJson<'input> for Vec<T> {
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
T::vec_from_lex(lex)
}
}
#[allow(unsafe_code)]
#[inline]
fn find_backslash(bytes: &[u8]) -> Option<usize> {
#[cfg(all(target_arch = "x86_64", not(bourne_no_simd)))]
{
find_backslash_sse2(bytes)
}
#[cfg(not(all(target_arch = "x86_64", not(bourne_no_simd))))]
{
bytes.iter().position(|&b| b == b'\\')
}
}
#[cfg(all(target_arch = "x86_64", not(bourne_no_simd)))]
#[allow(unsafe_code, clippy::cast_possible_wrap, clippy::cast_sign_loss)]
#[inline]
fn find_backslash_sse2(bytes: &[u8]) -> Option<usize> {
use core::arch::x86_64::{
_mm_cmpeq_epi8, _mm_loadu_si128, _mm_movemask_epi8, _mm_set1_epi8,
};
let n = bytes.len();
let mut i = 0;
unsafe {
let backslash = _mm_set1_epi8(b'\\' as i8);
while i + 16 <= n {
let chunk = _mm_loadu_si128(bytes.as_ptr().add(i).cast());
let m = _mm_cmpeq_epi8(chunk, backslash);
let bits = _mm_movemask_epi8(m) as u32;
if bits != 0 {
return Some(i + bits.trailing_zeros() as usize);
}
i += 16;
}
}
bytes[i..]
.iter()
.position(|&b| b == b'\\')
.map(|off| i + off)
}
#[allow(unsafe_code)]
fn decode_escapes(raw: &[u8], dst: &mut String) -> Result<(), ErrorKind> {
let mut i = 0;
while i < raw.len() {
if raw[i] != b'\\' {
let start = i;
i = find_backslash(&raw[i..]).map_or(raw.len(), |off| i + off);
let chunk = unsafe { core::str::from_utf8_unchecked(&raw[start..i]) };
dst.push_str(chunk);
continue;
}
i += 1;
if i >= raw.len() {
return Err(ErrorKind::InvalidEscape);
}
if raw[i] == b'u' {
i = decode_unicode_escape(raw, i, dst)?;
} else {
dst.push(decode_simple_escape(raw[i])?);
}
i += 1;
}
Ok(())
}
#[inline]
const fn decode_simple_escape(b: u8) -> Result<char, ErrorKind> {
Ok(match b {
b'"' => '"',
b'\\' => '\\',
b'/' => '/',
b'b' => '\u{0008}',
b'f' => '\u{000C}',
b'n' => '\n',
b'r' => '\r',
b't' => '\t',
_ => return Err(ErrorKind::InvalidEscape),
})
}
fn decode_unicode_escape(raw: &[u8], i: usize, dst: &mut String) -> Result<usize, ErrorKind> {
if i + 5 > raw.len() {
return Err(ErrorKind::InvalidUnicodeEscape);
}
let cp = parse_hex4(&raw[i + 1..i + 5])?;
let new_i = i + 4;
if (0xD800..=0xDBFF).contains(&cp) {
return decode_surrogate_pair(raw, new_i, cp, dst);
}
if (0xDC00..=0xDFFF).contains(&cp) {
return Err(ErrorKind::UnpairedSurrogate);
}
let ch = char::from_u32(cp).ok_or(ErrorKind::InvalidUnicodeEscape)?;
dst.push(ch);
Ok(new_i)
}
fn decode_surrogate_pair(
raw: &[u8],
i: usize,
cp: u32,
dst: &mut String,
) -> Result<usize, ErrorKind> {
if i + 7 > raw.len() || raw[i + 1] != b'\\' || raw[i + 2] != b'u' {
return Err(ErrorKind::UnpairedSurrogate);
}
let low = parse_hex4(&raw[i + 3..i + 7])?;
if !(0xDC00..=0xDFFF).contains(&low) {
return Err(ErrorKind::UnpairedSurrogate);
}
let high_off = cp - 0xD800;
let low_off = low - 0xDC00;
let scalar = 0x1_0000 + (high_off << 10) + low_off;
let ch = char::from_u32(scalar).ok_or(ErrorKind::InvalidUnicodeEscape)?;
dst.push(ch);
Ok(i + 6) }
fn parse_hex4(bytes: &[u8]) -> Result<u32, ErrorKind> {
let mut v: u32 = 0;
for &b in bytes {
let d = match b {
b'0'..=b'9' => b - b'0',
b'a'..=b'f' => b - b'a' + 10,
b'A'..=b'F' => b - b'A' + 10,
_ => return Err(ErrorKind::InvalidUnicodeEscape),
};
v = (v << 4) | u32::from(d);
}
Ok(v)
}
#[allow(dead_code)]
type _UseJsonStr = JsonStr;
#[cfg(feature = "indexmap")]
impl<'input, K, V, S> FromJson<'input> for indexmap::IndexMap<K, V, S>
where
K: MapKey<'input> + ::core::hash::Hash + Eq,
V: FromJson<'input>,
S: ::core::hash::BuildHasher + Default,
{
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
parse_map(lex)
}
}
#[cfg(feature = "indexmap")]
impl<'input, T, S> FromJson<'input> for indexmap::IndexSet<T, S>
where
T: FromJson<'input> + ::core::hash::Hash + Eq,
S: ::core::hash::BuildHasher + Default,
{
fn from_lex(lex: &mut Lexer<'input>) -> Result<Self, Error> {
parse_set(lex)
}
}
}