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 ':' )
}
fn parse_keyname < V > ( & mut self , mut visitor : V ) -> Result < V ::Value >
where
V : de ::Visitor ,
{
// 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 {
return Err ( self . rdr . error ( ErrorCode ::EOFWhileParsingObject ) ) ;
} 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 ) ;
}
}
}
fn parse_value < V > ( & mut self , mut visitor : V ) -> Result < V ::Value >
where
V : de ::Visitor ,
{
self . rdr . parse_whitespace ( ) ? ;
if self . rdr . eof ( ) ? {
return Err ( self . rdr . error ( ErrorCode ::EOFWhileParsingValue ) ) ;
}
match self . state {
State ::Keyname = > {
self . state = State ::Normal ;
return self . parse_keyname ( visitor ) ;
}
State ::Root = > {
self . state = State ::Normal ;
return visitor . visit_map ( MapVisitor ::new ( self , true ) ) ;
}
_ = > { }
}
let value = match self . rdr . peek_or_null ( ) ? {
/*
b '-' = > {
self . rdr . eat_char ( ) ;
self . parse_integer ( false , visitor )
}
b '0' ..= b '9' = > {
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 ( ) ;
visitor . visit_seq ( SeqVisitor ::new ( self ) )
}
b '{' = > {
self . rdr . eat_char ( ) ;
visitor . visit_map ( MapVisitor ::new ( self , false ) )
}
b '\x00' = > Err ( self . rdr . error ( ErrorCode ::ExpectedSomeValue ) ) ,
_ = > self . parse_tfnns ( visitor ) ,
} ;
match value {
Ok ( value ) = > Ok ( value ) ,
Err ( Error ::Syntax ( code , _ , _ ) ) = > Err ( self . rdr . error ( code ) ) ,
Err ( err ) = > Err ( err ) ,
}
}
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 ( ( ) )
}
fn parse_tfnns < V > ( & mut self , mut visitor : V ) -> Result < V ::Value >
where
V : de ::Visitor ,
{
// 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 ) {
2020-11-22 01:37:16 +01:00
let mut pn = ParseNumber ::new ( self . str_buf . iter ( ) . cloned ( ) ) ;
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 ) ;
if self . str_buf = = vec! [ b '\'' ; 3 ] {
return self . parse_ml_string ( visitor ) ;
}
}
}
fn decode_hex_escape ( & mut self ) -> Result < u16 > {
let mut i = 0 ;
let mut n = 0 u16 ;
while i < 4 & & ! ( self . rdr . eof ( ) ? ) {
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 ( ( ) )
}
fn parse_ml_string < V > ( & mut self , mut visitor : V ) -> Result < V ::Value >
where
V : de ::Visitor ,
{
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 ( ) ? {
return Err ( self . rdr . error ( ErrorCode ::EOFWhileParsingString ) ) ;
} // 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 = > {
return Err ( self . rdr . error ( ErrorCode ::EOFWhileParsingString ) ) ;
}
} ;
match ch {
b '"' = > {
return Ok ( ( ) ) ;
}
b '\\' = > {
let ch = match self . rdr . next_char ( ) ? {
Some ( ch ) = > ch ,
None = > {
return Err ( self . rdr . error ( ErrorCode ::EOFWhileParsingString ) ) ;
}
} ;
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 ) ) ;
}
} ,
} ;
// FIXME: this allocation is required in order to be compatible with stable
// rust, which doesn't support encoding a `char` into a stack buffer.
let mut buf = String ::new ( ) ;
buf . push ( c ) ;
self . str_buf . extend ( buf . bytes ( ) ) ;
}
_ = > {
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 ) ) ,
None = > Err ( self . rdr . error ( ErrorCode ::EOFWhileParsingObject ) ) ,
}
}
}
impl < Iter > de ::Deserializer for Deserializer < Iter >
where
Iter : Iterator < Item = u8 > ,
{
type Error = Error ;
#[ inline ]
fn deserialize < V > ( & mut self , visitor : V ) -> Result < V ::Value >
where
V : de ::Visitor ,
{
self . parse_value ( visitor )
}
/// Parses a `null` as a None, and any other values as a `Some(...)`.
#[ inline ]
fn deserialize_option < V > ( & mut self , mut visitor : V ) -> Result < V ::Value >
where
V : de ::Visitor ,
{
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 ]
fn deserialize_newtype_struct < V > ( & mut self , _name : & str , mut visitor : V ) -> Result < V ::Value >
where
V : de ::Visitor ,
{
visitor . visit_newtype_struct ( self )
}
forward_to_deserialize! {
deserialize_bool ( ) ;
deserialize_usize ( ) ;
deserialize_u8 ( ) ;
deserialize_u16 ( ) ;
deserialize_u32 ( ) ;
deserialize_u64 ( ) ;
deserialize_isize ( ) ;
deserialize_i8 ( ) ;
deserialize_i16 ( ) ;
deserialize_i32 ( ) ;
deserialize_i64 ( ) ;
deserialize_f32 ( ) ;
deserialize_f64 ( ) ;
deserialize_char ( ) ;
deserialize_str ( ) ;
deserialize_string ( ) ;
deserialize_unit ( ) ;
deserialize_seq ( ) ;
deserialize_seq_fixed_size ( len : usize ) ;
deserialize_bytes ( ) ;
deserialize_map ( ) ;
deserialize_unit_struct ( name : & 'static str ) ;
deserialize_tuple_struct ( name : & 'static str , len : usize ) ;
deserialize_struct ( name : & 'static str , fields : & 'static [ & 'static str ] ) ;
deserialize_struct_field ( ) ;
deserialize_tuple ( len : usize ) ;
deserialize_enum ( name : & 'static str , variants : & 'static [ & 'static str ] ) ;
deserialize_ignored_any ( ) ;
}
}
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 }
}
}
impl < ' a , Iter > de ::SeqVisitor for SeqVisitor < ' a , Iter >
where
Iter : Iterator < Item = u8 > ,
{
type Error = Error ;
fn visit < T > ( & mut self ) -> Result < Option < T > >
where
T : de ::Deserialize ,
{
self . de . rdr . parse_whitespace ( ) ? ;
match self . de . rdr . peek ( ) ? {
Some ( b ']' ) = > {
return Ok ( None ) ;
}
Some ( _ ) = > { }
None = > {
return Err ( self . de . rdr . error ( ErrorCode ::EOFWhileParsingList ) ) ;
}
}
let value = de ::Deserialize ::deserialize ( self . de ) ? ;
// 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 ) )
}
fn end ( & mut self ) -> Result < ( ) > {
self . de . rdr . parse_whitespace ( ) ? ;
match self . de . rdr . next_char ( ) ? {
Some ( b ']' ) = > Ok ( ( ) ) ,
Some ( _ ) = > Err ( self . de . rdr . error ( ErrorCode ::TrailingCharacters ) ) ,
None = > Err ( self . de . rdr . error ( ErrorCode ::EOFWhileParsingList ) ) ,
}
}
}
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 ,
}
}
}
impl < ' a , Iter > de ::MapVisitor for MapVisitor < ' a , Iter >
where
Iter : Iterator < Item = u8 > ,
{
type Error = Error ;
fn visit_key < K > ( & mut self ) -> Result < Option < K > >
where
K : de ::Deserialize ,
{
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 {
return Err ( self . de . rdr . error ( ErrorCode ::EOFWhileParsingObject ) ) ;
}
}
}
match self . de . rdr . peek ( ) ? {
Some ( ch ) = > {
self . de . state = if ch = = b '"' {
State ::Normal
} else {
State ::Keyname
} ;
Ok ( Some ( de ::Deserialize ::deserialize ( self . de ) ? ) )
}
None = > Err ( self . de . rdr . error ( ErrorCode ::EOFWhileParsingValue ) ) ,
}
}
fn visit_value < V > ( & mut self ) -> Result < V >
where
V : de ::Deserialize ,
{
self . de . parse_object_colon ( ) ? ;
2021-02-12 11:13:14 +01:00
de ::Deserialize ::deserialize ( self . de )
2020-11-22 01:37:16 +01:00
}
fn end ( & mut self ) -> Result < ( ) > {
self . de . rdr . parse_whitespace ( ) ? ;
match self . de . rdr . next_char ( ) ? {
Some ( b '}' ) = > {
if ! self . root {
Ok ( ( ) )
} else {
Err ( self . de . rdr . error ( ErrorCode ::TrailingCharacters ) )
} // todo
}
Some ( _ ) = > Err ( self . de . rdr . error ( ErrorCode ::TrailingCharacters ) ) ,
None = > {
if self . root {
Ok ( ( ) )
} else {
Err ( self . de . rdr . error ( ErrorCode ::EOFWhileParsingObject ) )
}
}
}
}
fn missing_field < V > ( & mut self , field : & 'static str ) -> Result < V >
where
V : de ::Deserialize ,
{
struct MissingFieldDeserializer ( & 'static str ) ;
impl de ::Deserializer for MissingFieldDeserializer {
type Error = de ::value ::Error ;
fn deserialize < V > ( & mut self , _visitor : V ) -> std ::result ::Result < V ::Value , Self ::Error >
where
V : de ::Visitor ,
{
let & mut MissingFieldDeserializer ( field ) = self ;
Err ( de ::value ::Error ::MissingField ( field ) )
}
fn deserialize_option < V > (
& mut self ,
mut visitor : V ,
) -> std ::result ::Result < V ::Value , Self ::Error >
where
V : de ::Visitor ,
{
visitor . visit_none ( )
}
forward_to_deserialize! {
deserialize_bool ( ) ;
deserialize_usize ( ) ;
deserialize_u8 ( ) ;
deserialize_u16 ( ) ;
deserialize_u32 ( ) ;
deserialize_u64 ( ) ;
deserialize_isize ( ) ;
deserialize_i8 ( ) ;
deserialize_i16 ( ) ;
deserialize_i32 ( ) ;
deserialize_i64 ( ) ;
deserialize_f32 ( ) ;
deserialize_f64 ( ) ;
deserialize_char ( ) ;
deserialize_str ( ) ;
deserialize_string ( ) ;
deserialize_unit ( ) ;
deserialize_seq ( ) ;
deserialize_seq_fixed_size ( len : usize ) ;
deserialize_bytes ( ) ;
deserialize_map ( ) ;
deserialize_unit_struct ( name : & 'static str ) ;
deserialize_newtype_struct ( name : & 'static str ) ;
deserialize_tuple_struct ( name : & 'static str , len : usize ) ;
deserialize_struct ( name : & 'static str , fields : & 'static [ & 'static str ] ) ;
deserialize_struct_field ( ) ;
deserialize_tuple ( len : usize ) ;
deserialize_enum ( name : & 'static str , variants : & 'static [ & 'static str ] ) ;
deserialize_ignored_any ( ) ;
}
}
let mut de = MissingFieldDeserializer ( field ) ;
Ok ( de ::Deserialize ::deserialize ( & mut de ) ? )
}
}
impl < Iter > de ::VariantVisitor for Deserializer < Iter >
where
Iter : Iterator < Item = u8 > ,
{
type Error = Error ;
fn visit_variant < V > ( & mut self ) -> Result < V >
where
V : de ::Deserialize ,
{
let val = de ::Deserialize ::deserialize ( self ) ? ;
self . parse_object_colon ( ) ? ;
Ok ( val )
}
fn visit_unit ( & mut self ) -> Result < ( ) > {
de ::Deserialize ::deserialize ( self )
}
fn visit_newtype < T > ( & mut self ) -> Result < T >
where
T : de ::Deserialize ,
{
de ::Deserialize ::deserialize ( self )
}
fn visit_tuple < V > ( & mut self , _len : usize , visitor : V ) -> Result < V ::Value >
where
V : de ::Visitor ,
{
de ::Deserializer ::deserialize ( self , visitor )
}
fn visit_struct < V > ( & mut self , _fields : & 'static [ & 'static str ] , visitor : V ) -> Result < V ::Value >
where
V : de ::Visitor ,
{
de ::Deserializer ::deserialize ( self , visitor )
}
}
//////////////////////////////////////////////////////////////////////////////
/// Iterator that deserializes a stream into multiple Hjson values.
pub struct StreamDeserializer < T , Iter >
where
Iter : Iterator < Item = u8 > ,
T : de ::Deserialize ,
{
deser : Deserializer < Iter > ,
_marker : PhantomData < T > ,
}
impl < T , Iter > StreamDeserializer < T , Iter >
where
Iter : Iterator < Item = u8 > ,
T : de ::Deserialize ,
{
/// 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 > ,
T : de ::Deserialize ,
{
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 > > ,
T : de ::Deserialize ,
{
let fold : io ::Result < Vec < _ > > = iter . collect ( ) ;
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
let mut de = Deserializer ::new_for_root ( bytes . iter ( ) . cloned ( ) ) ;
let value = match de ::Deserialize ::deserialize ( & mut de ) . and_then ( | x | {
de . end ( ) ? ;
Ok ( x )
} ) {
Ok ( v ) = > Ok ( v ) ,
Err ( _ ) = > {
let mut de2 = Deserializer ::new ( bytes . iter ( ) . cloned ( ) ) ;
match de ::Deserialize ::deserialize ( & mut de2 ) . and_then ( | x | {
de2 . end ( ) ? ;
Ok ( x )
} ) {
Ok ( v ) = > Ok ( v ) ,
Err ( e ) = > Err ( e ) ,
}
}
} ;
/* 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 )
. and_then ( | x | { de . end ( ) ) ; Ok ( x ) } )
{
Ok ( v ) = > Ok ( v ) ,
Err ( e ) = > Err ( e ) ,
} ;
* /
value
}
/// Decodes a Hjson value from a `std::io::Read`.
pub fn from_reader < R , T > ( rdr : R ) -> Result < T >
where
R : io ::Read ,
T : de ::Deserialize ,
{
from_iter ( rdr . bytes ( ) )
}
/// Decodes a Hjson value from a byte slice `&[u8]`.
pub fn from_slice < T > ( v : & [ u8 ] ) -> Result < T >
where
T : de ::Deserialize ,
{
from_iter ( v . iter ( ) . map ( | byte | Ok ( * byte ) ) )
}
/// Decodes a Hjson value from a `&str`.
pub fn from_str < T > ( s : & str ) -> Result < T >
where
T : de ::Deserialize ,
{
from_slice ( s . as_bytes ( ) )
}