2020-11-22 01:37:16 +01:00
//! Hjson Deserialization
//!
//! This module provides for Hjson deserialization with the type `Deserializer`.
use std ::char ;
use std ::io ;
use std ::marker ::PhantomData ;
use std ::str ;
use serde ::de ;
use super ::error ::{ Error , ErrorCode , Result } ;
use super ::util ::StringReader ;
use super ::util ::{ Number , ParseNumber } ;
enum State {
Normal ,
Root ,
Keyname ,
}
/// A structure that deserializes Hjson into Rust values.
pub struct Deserializer < Iter : Iterator < Item = u8 > > {
rdr : StringReader < Iter > ,
str_buf : Vec < u8 > ,
state : State ,
}
// macro_rules! try_or_invalid {
// ($self_:expr, $e:expr) => {
// match $e {
// Some(v) => v,
// None => { return Err($self_.error(ErrorCode::InvalidNumber)); }
// }
// }
// }
impl < Iter > Deserializer < Iter >
where
Iter : Iterator < Item = u8 > ,
{
/// Creates the Hjson parser from an `std::iter::Iterator`.
#[ inline ]
pub fn new ( rdr : Iter ) -> Deserializer < Iter > {
Deserializer {
rdr : StringReader ::new ( rdr ) ,
str_buf : Vec ::with_capacity ( 128 ) ,
state : State ::Normal ,
}
}
/// Creates the Hjson parser from an `std::iter::Iterator`.
#[ inline ]
pub fn new_for_root ( rdr : Iter ) -> Deserializer < Iter > {
let mut res = Deserializer ::new ( rdr ) ;
res . state = State ::Root ;
res
}
/// The `Deserializer::end` method should be called after a value has been fully deserialized.
/// This allows the `Deserializer` to validate that the input stream is at the end or that it
/// only has trailing whitespace.
#[ inline ]
pub fn end ( & mut self ) -> Result < ( ) > {
self . rdr . parse_whitespace ( ) ? ;
if self . rdr . eof ( ) ? {
Ok ( ( ) )
} else {
Err ( self . rdr . error ( ErrorCode ::TrailingCharacters ) )
}
}
fn is_punctuator_char ( & mut self , ch : u8 ) -> bool {
matches! ( ch , b '{' | b '}' | b '[' | b ']' | b ',' | b ':' )
}
2021-03-04 07:35:13 +01:00
fn parse_keyname < ' de , V > ( & mut self , visitor : V ) -> Result < V ::Value >
2020-11-22 01:37:16 +01:00
where
2021-03-04 07:35:13 +01:00
V : de ::Visitor < ' de > ,
2020-11-22 01:37:16 +01:00
{
// quotes for keys are optional in Hjson
// unless they include {}[],: or whitespace.
// assume whitespace was already eaten
self . str_buf . clear ( ) ;
let mut space : Option < usize > = None ;
loop {
let ch = self . rdr . next_char_or_null ( ) ? ;
if ch = = b ':' {
if self . str_buf . is_empty ( ) {
return Err ( self . rdr . error ( ErrorCode ::Custom (
" Found ':' but no key name (for an empty key name use quotes) " . to_string ( ) ,
) ) ) ;
} else if space . is_some ( )
& & space . expect ( " Internal error: json parsing " ) ! = self . str_buf . len ( )
{
return Err ( self . rdr . error ( ErrorCode ::Custom (
" Found whitespace in your key name (use quotes to include) " . to_string ( ) ,
) ) ) ;
}
self . rdr . uneat_char ( ch ) ;
let s = str ::from_utf8 ( & self . str_buf ) . expect ( " Internal error: json parsing " ) ;
return visitor . visit_str ( s ) ;
} else if ch < = b ' ' {
if ch = = 0 {
2021-03-26 09:26:57 +01:00
return Err ( self . rdr . error ( ErrorCode ::EofWhileParsingObject ) ) ;
2020-11-22 01:37:16 +01:00
} else if space . is_none ( ) {
space = Some ( self . str_buf . len ( ) ) ;
}
} else if self . is_punctuator_char ( ch ) {
return Err ( self . rdr . error ( ErrorCode ::Custom ( " Found a punctuator where a key name was expected (check your syntax or use quotes if the key name includes {}[],: or whitespace) " . to_string ( ) ) ) ) ;
} else {
self . str_buf . push ( ch ) ;
}
}
}
2021-03-04 07:35:13 +01:00
fn parse_value < ' de , V > ( & mut self , visitor : V ) -> Result < V ::Value >
2020-11-22 01:37:16 +01:00
where
2021-03-04 07:35:13 +01:00
V : de ::Visitor < ' de > ,
2020-11-22 01:37:16 +01:00
{
self . rdr . parse_whitespace ( ) ? ;
if self . rdr . eof ( ) ? {
2021-03-26 09:26:57 +01:00
return Err ( self . rdr . error ( ErrorCode ::EofWhileParsingValue ) ) ;
2020-11-22 01:37:16 +01:00
}
match self . state {
State ::Keyname = > {
self . state = State ::Normal ;
return self . parse_keyname ( visitor ) ;
}
State ::Root = > {
self . state = State ::Normal ;
2021-03-04 07:35:13 +01:00
return self . visit_map ( true , visitor ) ;
2020-11-22 01:37:16 +01:00
}
_ = > { }
}
2021-03-04 07:35:13 +01:00
match self . rdr . peek_or_null ( ) ? {
2020-11-22 01:37:16 +01:00
/*
b '-' = > {
self . rdr . eat_char ( ) ;
self . parse_integer ( false , visitor )
}
2021-03-04 07:35:13 +01:00
b '0' .. . b '9' = > {
2020-11-22 01:37:16 +01:00
self . parse_integer ( true , visitor )
}
* /
b '"' = > {
self . rdr . eat_char ( ) ;
self . parse_string ( ) ? ;
let s = str ::from_utf8 ( & self . str_buf ) . expect ( " Internal error: json parsing " ) ;
visitor . visit_str ( s )
}
b '[' = > {
self . rdr . eat_char ( ) ;
2021-03-04 07:35:13 +01:00
let ret = visitor . visit_seq ( SeqVisitor ::new ( self ) ) ? ;
self . rdr . parse_whitespace ( ) ? ;
match self . rdr . next_char ( ) ? {
Some ( b ']' ) = > Ok ( ret ) ,
Some ( _ ) = > Err ( self . rdr . error ( ErrorCode ::TrailingCharacters ) ) ,
2021-03-26 09:26:57 +01:00
None = > Err ( self . rdr . error ( ErrorCode ::EofWhileParsingList ) ) ,
2021-03-04 07:35:13 +01:00
}
2020-11-22 01:37:16 +01:00
}
b '{' = > {
self . rdr . eat_char ( ) ;
2021-03-04 07:35:13 +01:00
self . visit_map ( false , visitor )
2020-11-22 01:37:16 +01:00
}
b '\x00' = > Err ( self . rdr . error ( ErrorCode ::ExpectedSomeValue ) ) ,
_ = > self . parse_tfnns ( visitor ) ,
2021-03-04 07:35:13 +01:00
}
}
2020-11-22 01:37:16 +01:00
2021-03-04 07:35:13 +01:00
fn visit_map < ' de , V > ( & mut self , root : bool , visitor : V ) -> Result < V ::Value >
where
V : de ::Visitor < ' de > ,
{
let ret = visitor . visit_map ( MapVisitor ::new ( self , root ) ) ? ;
self . rdr . parse_whitespace ( ) ? ;
match self . rdr . next_char ( ) ? {
Some ( b '}' ) = > {
if ! root {
Ok ( ret )
} else {
Err ( self . rdr . error ( ErrorCode ::TrailingCharacters ) )
} // todo
}
Some ( _ ) = > Err ( self . rdr . error ( ErrorCode ::TrailingCharacters ) ) ,
None = > {
if root {
Ok ( ret )
} else {
2021-03-26 09:26:57 +01:00
Err ( self . rdr . error ( ErrorCode ::EofWhileParsingObject ) )
2021-03-04 07:35:13 +01:00
}
}
2020-11-22 01:37:16 +01:00
}
}
fn parse_ident ( & mut self , ident : & [ u8 ] ) -> Result < ( ) > {
for c in ident {
if Some ( * c ) ! = self . rdr . next_char ( ) ? {
return Err ( self . rdr . error ( ErrorCode ::ExpectedSomeIdent ) ) ;
}
}
Ok ( ( ) )
}
2021-03-04 07:35:13 +01:00
fn parse_tfnns < ' de , V > ( & mut self , visitor : V ) -> Result < V ::Value >
2020-11-22 01:37:16 +01:00
where
2021-03-04 07:35:13 +01:00
V : de ::Visitor < ' de > ,
2020-11-22 01:37:16 +01:00
{
// Hjson strings can be quoteless
// returns string, true, false, or null.
self . str_buf . clear ( ) ;
let first = self . rdr . peek ( ) ? . expect ( " Internal error: json parsing " ) ;
if self . is_punctuator_char ( first ) {
return Err ( self . rdr . error ( ErrorCode ::PunctuatorInQlString ) ) ;
}
loop {
let ch = self . rdr . next_char_or_null ( ) ? ;
let is_eol = ch = = b '\r' | | ch = = b '\n' | | ch = = b '\x00' ;
let is_comment = ch = = b '#'
| | if ch = = b '/' {
let next = self . rdr . peek_or_null ( ) ? ;
next = = b '/' | | next = = b '*'
} else {
false
} ;
if is_eol | | is_comment | | ch = = b ',' | | ch = = b '}' | | ch = = b ']' {
let chf = self . str_buf [ 0 ] ;
match chf {
b 'f' = > {
if str ::from_utf8 ( & self . str_buf )
. expect ( " Internal error: json parsing " )
. trim ( )
= = " false "
{
self . rdr . uneat_char ( ch ) ;
return visitor . visit_bool ( false ) ;
}
}
b 'n' = > {
if str ::from_utf8 ( & self . str_buf )
. expect ( " Internal error: json parsing " )
. trim ( )
= = " null "
{
self . rdr . uneat_char ( ch ) ;
return visitor . visit_unit ( ) ;
}
}
b 't' = > {
if str ::from_utf8 ( & self . str_buf )
. expect ( " Internal error: json parsing " )
. trim ( )
= = " true "
{
self . rdr . uneat_char ( ch ) ;
return visitor . visit_bool ( true ) ;
}
}
_ = > {
2021-01-01 03:13:59 +01:00
if chf = = b '-' | | ( b '0' ..= b '9' ) . contains ( & chf ) {
2021-03-04 07:35:13 +01:00
let mut pn = ParseNumber ::new ( self . str_buf . iter ( ) . copied ( ) ) ;
2020-11-22 01:37:16 +01:00
match pn . parse ( false ) {
Ok ( Number ::F64 ( v ) ) = > {
self . rdr . uneat_char ( ch ) ;
return visitor . visit_f64 ( v ) ;
}
Ok ( Number ::U64 ( v ) ) = > {
self . rdr . uneat_char ( ch ) ;
return visitor . visit_u64 ( v ) ;
}
Ok ( Number ::I64 ( v ) ) = > {
self . rdr . uneat_char ( ch ) ;
return visitor . visit_i64 ( v ) ;
}
Err ( _ ) = > { } // not a number, continue
}
}
}
}
if is_eol {
// remove any whitespace at the end (ignored in quoteless strings)
return visitor . visit_str (
str ::from_utf8 ( & self . str_buf )
. expect ( " Internal error: json parsing " )
. trim ( ) ,
) ;
}
}
self . str_buf . push ( ch ) ;
2021-03-04 07:35:13 +01:00
if self . str_buf = = b " ''' " {
2020-11-22 01:37:16 +01:00
return self . parse_ml_string ( visitor ) ;
}
}
}
fn decode_hex_escape ( & mut self ) -> Result < u16 > {
let mut i = 0 ;
let mut n = 0 u16 ;
2021-03-04 07:35:13 +01:00
while i < 4 & & ! self . rdr . eof ( ) ? {
2020-11-22 01:37:16 +01:00
n = match self . rdr . next_char_or_null ( ) ? {
c @ b '0' ..= b '9' = > n * 16_ u16 + ( ( c as u16 ) - ( b '0' as u16 ) ) ,
b 'a' | b 'A' = > n * 16_ u16 + 10_ u16 ,
b 'b' | b 'B' = > n * 16_ u16 + 11_ u16 ,
b 'c' | b 'C' = > n * 16_ u16 + 12_ u16 ,
b 'd' | b 'D' = > n * 16_ u16 + 13_ u16 ,
b 'e' | b 'E' = > n * 16_ u16 + 14_ u16 ,
b 'f' | b 'F' = > n * 16_ u16 + 15_ u16 ,
_ = > {
return Err ( self . rdr . error ( ErrorCode ::InvalidEscape ) ) ;
}
} ;
i + = 1 ;
}
// Error out if we didn't parse 4 digits.
if i ! = 4 {
return Err ( self . rdr . error ( ErrorCode ::InvalidEscape ) ) ;
}
Ok ( n )
}
fn ml_skip_white ( & mut self ) -> Result < bool > {
match self . rdr . peek_or_null ( ) ? {
b ' ' | b '\t' | b '\r' = > {
self . rdr . eat_char ( ) ;
Ok ( true )
}
_ = > Ok ( false ) ,
}
}
fn ml_skip_indent ( & mut self , indent : usize ) -> Result < ( ) > {
let mut skip = indent ;
while self . ml_skip_white ( ) ? & & skip > 0 {
skip - = 1 ;
}
Ok ( ( ) )
}
2021-03-04 07:35:13 +01:00
fn parse_ml_string < ' de , V > ( & mut self , visitor : V ) -> Result < V ::Value >
2020-11-22 01:37:16 +01:00
where
2021-03-04 07:35:13 +01:00
V : de ::Visitor < ' de > ,
2020-11-22 01:37:16 +01:00
{
self . str_buf . clear ( ) ;
// Parse a multiline string value.
let mut triple = 0 ;
// we are at ''' +1 - get indent
let ( _ , col ) = self . rdr . pos ( ) ;
let indent = col - 4 ;
// skip white/to (newline)
while self . ml_skip_white ( ) ? { }
if self . rdr . peek_or_null ( ) ? = = b '\n' {
self . rdr . eat_char ( ) ;
self . ml_skip_indent ( indent ) ? ;
}
// When parsing multiline string values, we must look for ' characters.
loop {
if self . rdr . eof ( ) ? {
2021-03-26 09:26:57 +01:00
return Err ( self . rdr . error ( ErrorCode ::EofWhileParsingString ) ) ;
2020-11-22 01:37:16 +01:00
} // todo error("Bad multiline string");
let ch = self . rdr . next_char_or_null ( ) ? ;
if ch = = b '\'' {
triple + = 1 ;
if triple = = 3 {
if self . str_buf . last ( ) = = Some ( & b '\n' ) {
self . str_buf . pop ( ) ;
}
let res = str ::from_utf8 ( & self . str_buf ) . expect ( " Internal error: json parsing " ) ;
//todo if (self.str_buf.slice(-1) === '\n') self.str_buf=self.str_buf.slice(0, -1); // remove last EOL
return visitor . visit_str ( res ) ;
} else {
continue ;
}
}
while triple > 0 {
self . str_buf . push ( b '\'' ) ;
triple - = 1 ;
}
if ch ! = b '\r' {
self . str_buf . push ( ch ) ;
}
if ch = = b '\n' {
self . ml_skip_indent ( indent ) ? ;
}
}
}
fn parse_string ( & mut self ) -> Result < ( ) > {
self . str_buf . clear ( ) ;
loop {
let ch = match self . rdr . next_char ( ) ? {
Some ( ch ) = > ch ,
None = > {
2021-03-26 09:26:57 +01:00
return Err ( self . rdr . error ( ErrorCode ::EofWhileParsingString ) ) ;
2020-11-22 01:37:16 +01:00
}
} ;
match ch {
b '"' = > {
return Ok ( ( ) ) ;
}
b '\\' = > {
let ch = match self . rdr . next_char ( ) ? {
Some ( ch ) = > ch ,
None = > {
2021-03-26 09:26:57 +01:00
return Err ( self . rdr . error ( ErrorCode ::EofWhileParsingString ) ) ;
2020-11-22 01:37:16 +01:00
}
} ;
match ch {
b '"' = > self . str_buf . push ( b '"' ) ,
b '\\' = > self . str_buf . push ( b '\\' ) ,
b '/' = > self . str_buf . push ( b '/' ) ,
b 'b' = > self . str_buf . push ( b '\x08' ) ,
b 'f' = > self . str_buf . push ( b '\x0c' ) ,
b 'n' = > self . str_buf . push ( b '\n' ) ,
b 'r' = > self . str_buf . push ( b '\r' ) ,
b 't' = > self . str_buf . push ( b '\t' ) ,
b 'u' = > {
let c = match self . decode_hex_escape ( ) ? {
0xDC00 ..= 0xDFFF = > {
return Err ( self
. rdr
. error ( ErrorCode ::LoneLeadingSurrogateInHexEscape ) ) ;
}
// Non-BMP characters are encoded as a sequence of
// two hex escapes, representing UTF-16 surrogates.
n1 @ 0xD800 ..= 0xDBFF = > {
match ( self . rdr . next_char ( ) ? , self . rdr . next_char ( ) ? ) {
( Some ( b '\\' ) , Some ( b 'u' ) ) = > ( ) ,
_ = > {
return Err ( self
. rdr
. error ( ErrorCode ::UnexpectedEndOfHexEscape ) ) ;
}
}
let n2 = self . decode_hex_escape ( ) ? ;
2021-01-01 03:13:59 +01:00
if ! ( 0xDC00 ..= 0xDFFF ) . contains ( & n2 ) {
2020-11-22 01:37:16 +01:00
return Err ( self
. rdr
. error ( ErrorCode ::LoneLeadingSurrogateInHexEscape ) ) ;
}
let n = ( ( ( n1 - 0xD800 ) as u32 ) < < 10 | ( n2 - 0xDC00 ) as u32 )
+ 0x1_0000 ;
match char ::from_u32 ( n as u32 ) {
Some ( c ) = > c ,
None = > {
return Err ( self
. rdr
. error ( ErrorCode ::InvalidUnicodeCodePoint ) ) ;
}
}
}
n = > match char ::from_u32 ( n as u32 ) {
Some ( c ) = > c ,
None = > {
return Err ( self
. rdr
. error ( ErrorCode ::InvalidUnicodeCodePoint ) ) ;
}
} ,
} ;
2021-03-04 07:35:13 +01:00
self . str_buf . extend ( c . encode_utf8 ( & mut [ 0 ; 4 ] ) . as_bytes ( ) ) ;
2020-11-22 01:37:16 +01:00
}
_ = > {
return Err ( self . rdr . error ( ErrorCode ::InvalidEscape ) ) ;
}
}
}
ch = > {
self . str_buf . push ( ch ) ;
}
}
}
}
fn parse_object_colon ( & mut self ) -> Result < ( ) > {
self . rdr . parse_whitespace ( ) ? ;
match self . rdr . next_char ( ) ? {
Some ( b ':' ) = > Ok ( ( ) ) ,
Some ( _ ) = > Err ( self . rdr . error ( ErrorCode ::ExpectedColon ) ) ,
2021-03-26 09:26:57 +01:00
None = > Err ( self . rdr . error ( ErrorCode ::EofWhileParsingObject ) ) ,
2020-11-22 01:37:16 +01:00
}
}
}
2021-03-04 07:35:13 +01:00
impl < ' de , ' a , Iter > de ::Deserializer < ' de > for & ' a mut Deserializer < Iter >
2020-11-22 01:37:16 +01:00
where
Iter : Iterator < Item = u8 > ,
{
type Error = Error ;
#[ inline ]
2021-03-04 07:35:13 +01:00
fn deserialize_any < V > ( self , visitor : V ) -> Result < V ::Value >
2020-11-22 01:37:16 +01:00
where
2021-03-04 07:35:13 +01:00
V : de ::Visitor < ' de > ,
2020-11-22 01:37:16 +01:00
{
2021-03-04 07:35:13 +01:00
if let State ::Root = self . state { }
2020-11-22 01:37:16 +01:00
self . parse_value ( visitor )
}
/// Parses a `null` as a None, and any other values as a `Some(...)`.
#[ inline ]
2021-03-04 07:35:13 +01:00
fn deserialize_option < V > ( self , visitor : V ) -> Result < V ::Value >
2020-11-22 01:37:16 +01:00
where
2021-03-04 07:35:13 +01:00
V : de ::Visitor < ' de > ,
2020-11-22 01:37:16 +01:00
{
self . rdr . parse_whitespace ( ) ? ;
match self . rdr . peek_or_null ( ) ? {
b 'n' = > {
self . rdr . eat_char ( ) ;
self . parse_ident ( b " ull " ) ? ;
visitor . visit_none ( )
}
_ = > visitor . visit_some ( self ) ,
}
}
/// Parses a newtype struct as the underlying value.
#[ inline ]
2021-03-04 07:35:13 +01:00
fn deserialize_newtype_struct < V > ( self , _name : & str , visitor : V ) -> Result < V ::Value >
2020-11-22 01:37:16 +01:00
where
2021-03-04 07:35:13 +01:00
V : de ::Visitor < ' de > ,
2020-11-22 01:37:16 +01:00
{
visitor . visit_newtype_struct ( self )
}
2021-03-04 07:35:13 +01:00
serde ::forward_to_deserialize_any! {
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
bytes byte_buf unit unit_struct seq tuple map
tuple_struct struct enum identifier ignored_any
2020-11-22 01:37:16 +01:00
}
}
struct SeqVisitor < ' a , Iter : ' a + Iterator < Item = u8 > > {
de : & ' a mut Deserializer < Iter > ,
}
impl < ' a , Iter : Iterator < Item = u8 > > SeqVisitor < ' a , Iter > {
fn new ( de : & ' a mut Deserializer < Iter > ) -> Self {
SeqVisitor { de }
}
}
2021-03-04 07:35:13 +01:00
impl < ' de , ' a , Iter > de ::SeqAccess < ' de > for SeqVisitor < ' a , Iter >
2020-11-22 01:37:16 +01:00
where
Iter : Iterator < Item = u8 > ,
{
type Error = Error ;
2021-03-04 07:35:13 +01:00
fn next_element_seed < T > ( & mut self , seed : T ) -> Result < Option < T ::Value > >
2020-11-22 01:37:16 +01:00
where
2021-03-04 07:35:13 +01:00
T : de ::DeserializeSeed < ' de > ,
2020-11-22 01:37:16 +01:00
{
self . de . rdr . parse_whitespace ( ) ? ;
match self . de . rdr . peek ( ) ? {
Some ( b ']' ) = > {
return Ok ( None ) ;
}
Some ( _ ) = > { }
None = > {
2021-03-26 09:26:57 +01:00
return Err ( self . de . rdr . error ( ErrorCode ::EofWhileParsingList ) ) ;
2020-11-22 01:37:16 +01:00
}
}
2021-03-04 07:35:13 +01:00
let value = seed . deserialize ( & mut * self . de ) ? ;
2020-11-22 01:37:16 +01:00
// in Hjson the comma is optional and trailing commas are allowed
self . de . rdr . parse_whitespace ( ) ? ;
if self . de . rdr . peek ( ) ? = = Some ( b ',' ) {
self . de . rdr . eat_char ( ) ;
self . de . rdr . parse_whitespace ( ) ? ;
}
Ok ( Some ( value ) )
}
}
struct MapVisitor < ' a , Iter : ' a + Iterator < Item = u8 > > {
de : & ' a mut Deserializer < Iter > ,
first : bool ,
root : bool ,
}
impl < ' a , Iter : Iterator < Item = u8 > > MapVisitor < ' a , Iter > {
fn new ( de : & ' a mut Deserializer < Iter > , root : bool ) -> Self {
MapVisitor {
de ,
first : true ,
root ,
}
}
}
2021-03-04 07:35:13 +01:00
impl < ' de , ' a , Iter > de ::MapAccess < ' de > for MapVisitor < ' a , Iter >
2020-11-22 01:37:16 +01:00
where
Iter : Iterator < Item = u8 > ,
{
type Error = Error ;
2021-03-04 07:35:13 +01:00
fn next_key_seed < K > ( & mut self , seed : K ) -> Result < Option < K ::Value > >
2020-11-22 01:37:16 +01:00
where
2021-03-04 07:35:13 +01:00
K : de ::DeserializeSeed < ' de > ,
2020-11-22 01:37:16 +01:00
{
self . de . rdr . parse_whitespace ( ) ? ;
if self . first {
self . first = false ;
} else if self . de . rdr . peek ( ) ? = = Some ( b ',' ) {
// in Hjson the comma is optional and trailing commas are allowed
self . de . rdr . eat_char ( ) ;
self . de . rdr . parse_whitespace ( ) ? ;
}
match self . de . rdr . peek ( ) ? {
Some ( b '}' ) = > return Ok ( None ) , // handled later for root
Some ( _ ) = > { }
None = > {
if self . root {
return Ok ( None ) ;
} else {
2021-03-26 09:26:57 +01:00
return Err ( self . de . rdr . error ( ErrorCode ::EofWhileParsingObject ) ) ;
2020-11-22 01:37:16 +01:00
}
}
}
match self . de . rdr . peek ( ) ? {
Some ( ch ) = > {
self . de . state = if ch = = b '"' {
State ::Normal
} else {
State ::Keyname
} ;
2021-03-04 07:35:13 +01:00
Ok ( Some ( seed . deserialize ( & mut * self . de ) ? ) )
2020-11-22 01:37:16 +01:00
}
2021-03-26 09:26:57 +01:00
None = > Err ( self . de . rdr . error ( ErrorCode ::EofWhileParsingValue ) ) ,
2020-11-22 01:37:16 +01:00
}
}
2021-03-04 07:35:13 +01:00
fn next_value_seed < V > ( & mut self , seed : V ) -> Result < V ::Value >
2020-11-22 01:37:16 +01:00
where
2021-03-04 07:35:13 +01:00
V : de ::DeserializeSeed < ' de > ,
2020-11-22 01:37:16 +01:00
{
self . de . parse_object_colon ( ) ? ;
2021-03-26 09:26:57 +01:00
seed . deserialize ( & mut * self . de )
2020-11-22 01:37:16 +01:00
}
}
2021-03-04 07:35:13 +01:00
impl < ' de , ' a , Iter > de ::VariantAccess < ' de > for & ' a mut Deserializer < Iter >
2020-11-22 01:37:16 +01:00
where
Iter : Iterator < Item = u8 > ,
{
type Error = Error ;
2021-03-04 07:35:13 +01:00
fn unit_variant ( self ) -> Result < ( ) > {
2020-11-22 01:37:16 +01:00
de ::Deserialize ::deserialize ( self )
}
2021-03-04 07:35:13 +01:00
fn newtype_variant_seed < T > ( self , seed : T ) -> Result < T ::Value >
2020-11-22 01:37:16 +01:00
where
2021-03-04 07:35:13 +01:00
T : de ::DeserializeSeed < ' de > ,
2020-11-22 01:37:16 +01:00
{
2021-03-04 07:35:13 +01:00
seed . deserialize ( self )
2020-11-22 01:37:16 +01:00
}
2021-03-04 07:35:13 +01:00
fn tuple_variant < V > ( self , _len : usize , visitor : V ) -> Result < V ::Value >
2020-11-22 01:37:16 +01:00
where
2021-03-04 07:35:13 +01:00
V : de ::Visitor < ' de > ,
2020-11-22 01:37:16 +01:00
{
2021-03-04 07:35:13 +01:00
de ::Deserializer ::deserialize_any ( self , visitor )
2020-11-22 01:37:16 +01:00
}
2021-03-04 07:35:13 +01:00
fn struct_variant < V > ( self , _fields : & 'static [ & 'static str ] , visitor : V ) -> Result < V ::Value >
2020-11-22 01:37:16 +01:00
where
2021-03-04 07:35:13 +01:00
V : de ::Visitor < ' de > ,
2020-11-22 01:37:16 +01:00
{
2021-03-04 07:35:13 +01:00
de ::Deserializer ::deserialize_any ( self , visitor )
2020-11-22 01:37:16 +01:00
}
}
//////////////////////////////////////////////////////////////////////////////
/// Iterator that deserializes a stream into multiple Hjson values.
pub struct StreamDeserializer < T , Iter >
where
Iter : Iterator < Item = u8 > ,
2021-03-04 07:35:13 +01:00
T : de ::DeserializeOwned ,
2020-11-22 01:37:16 +01:00
{
deser : Deserializer < Iter > ,
_marker : PhantomData < T > ,
}
impl < T , Iter > StreamDeserializer < T , Iter >
where
Iter : Iterator < Item = u8 > ,
2021-03-04 07:35:13 +01:00
T : de ::DeserializeOwned ,
2020-11-22 01:37:16 +01:00
{
/// Returns an `Iterator` of decoded Hjson values from an iterator over
/// `Iterator<Item=u8>`.
pub fn new ( iter : Iter ) -> StreamDeserializer < T , Iter > {
StreamDeserializer {
deser : Deserializer ::new ( iter ) ,
_marker : PhantomData ,
}
}
}
impl < T , Iter > Iterator for StreamDeserializer < T , Iter >
where
Iter : Iterator < Item = u8 > ,
2021-03-04 07:35:13 +01:00
T : de ::DeserializeOwned ,
2020-11-22 01:37:16 +01:00
{
type Item = Result < T > ;
fn next ( & mut self ) -> Option < Result < T > > {
// skip whitespaces, if any
// this helps with trailing whitespaces, since whitespaces between
// values are handled for us.
if let Err ( e ) = self . deser . rdr . parse_whitespace ( ) {
return Some ( Err ( e ) ) ;
} ;
match self . deser . rdr . eof ( ) {
Ok ( true ) = > None ,
Ok ( false ) = > match de ::Deserialize ::deserialize ( & mut self . deser ) {
Ok ( v ) = > Some ( Ok ( v ) ) ,
Err ( e ) = > Some ( Err ( e ) ) ,
} ,
Err ( e ) = > Some ( Err ( e ) ) ,
}
}
}
//////////////////////////////////////////////////////////////////////////////
/// Decodes a Hjson value from an iterator over an iterator
/// `Iterator<Item=u8>`.
pub fn from_iter < I , T > ( iter : I ) -> Result < T >
where
I : Iterator < Item = io ::Result < u8 > > ,
2021-03-04 07:35:13 +01:00
T : de ::DeserializeOwned ,
2020-11-22 01:37:16 +01:00
{
let fold : io ::Result < Vec < _ > > = iter . collect ( ) ;
2021-03-04 07:35:13 +01:00
2020-11-22 01:37:16 +01:00
if let Err ( e ) = fold {
return Err ( Error ::Io ( e ) ) ;
}
let bytes = fold . expect ( " Internal error: json parsing " ) ;
// deserialize tries first to decode with legacy support (new_for_root)
// and then with the standard method if this fails.
// todo: add compile switch
// deserialize and make sure the whole stream has been consumed
2021-03-04 07:35:13 +01:00
let mut de = Deserializer ::new_for_root ( bytes . iter ( ) . copied ( ) ) ;
de ::Deserialize ::deserialize ( & mut de )
. and_then ( | x | de . end ( ) . map ( | ( ) | x ) )
. or_else ( | _ | {
let mut de2 = Deserializer ::new ( bytes . iter ( ) . copied ( ) ) ;
de ::Deserialize ::deserialize ( & mut de2 ) . and_then ( | x | de2 . end ( ) . map ( | ( ) | x ) )
} )
2020-11-22 01:37:16 +01:00
/* without legacy support:
// deserialize and make sure the whole stream has been consumed
let mut de = Deserializer ::new ( bytes . iter ( ) . map ( | b | * b ) ) ;
let value = match de ::Deserialize ::deserialize ( & mut de )
2021-03-04 07:35:13 +01:00
. and_then ( | x | { try ! ( de . end ( ) ) ; Ok ( x ) } )
2020-11-22 01:37:16 +01:00
{
Ok ( v ) = > Ok ( v ) ,
Err ( e ) = > Err ( e ) ,
} ;
* /
}
/// Decodes a Hjson value from a `std::io::Read`.
pub fn from_reader < R , T > ( rdr : R ) -> Result < T >
where
R : io ::Read ,
2021-03-04 07:35:13 +01:00
T : de ::DeserializeOwned ,
2020-11-22 01:37:16 +01:00
{
from_iter ( rdr . bytes ( ) )
}
/// Decodes a Hjson value from a byte slice `&[u8]`.
pub fn from_slice < T > ( v : & [ u8 ] ) -> Result < T >
where
2021-03-04 07:35:13 +01:00
T : de ::DeserializeOwned ,
2020-11-22 01:37:16 +01:00
{
2021-09-10 00:44:22 +02:00
from_iter ( v . iter ( ) . map ( | & byte | Ok ( byte ) ) )
2020-11-22 01:37:16 +01:00
}
/// Decodes a Hjson value from a `&str`.
pub fn from_str < T > ( s : & str ) -> Result < T >
where
2021-03-04 07:35:13 +01:00
T : de ::DeserializeOwned ,
2020-11-22 01:37:16 +01:00
{
from_slice ( s . as_bytes ( ) )
}