use ast::Json;
use buffer::{Buffer, Utf8Buffer};
use std::char;
use std::collections::HashMap;
use std::error::Error;
use std::f64;
use std::fmt;
use std::io::{self, Chars, CharsError, Read};
use std::str;
use std::{i8, i16, i32, i64, isize};
use std::{u8, u16, u32, u64, usize};
pub struct Decoder<I: Iterator> {
chars: Source<I>,
config: Config,
buffer: [u8; 512]
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Config {
pub max_nesting: usize
}
const DEFAULT_CONFIG: Config = Config { max_nesting: 16 };
impl Config {
pub fn default() -> Config { DEFAULT_CONFIG }
}
pub struct Element<A> {
pub value: A,
pub is_last: bool
}
macro_rules! require {
($e: expr) => {
match $e {
Some(c) => c,
None => return Err(DecodeError::EndOfInput)
}
}
}
macro_rules! integral {
($name: ident, $ty: ty, false) => {
pub fn $name(&mut self) -> DecodeResult<$ty> {
self.skip_whitespace();
let digit =
try!(require!(self.chars.next())
.to_digit(10)
.ok_or(DecodeError::Expected("digit")));
let mut dec = digit as $ty;
while let Some(c) = self.chars.next() {
match c.to_digit(10) {
Some(n) => {
if dec > ($name::MAX - n as $ty) / 10 {
return Err(DecodeError::IntOverflow)
}
dec = dec * 10 + n as $ty;
}
None => {
self.chars.put_back(c);
break
}
}
}
Ok(dec)
}
};
($name: ident, $ty: ty, true) => {
pub fn $name(&mut self) -> DecodeResult<$ty> {
self.skip_whitespace();
let is_neg =
match self.chars.peek() {
Some('-') => {
self.chars.next();
true
}
_ => false
};
let digit =
try!(require!(self.chars.next())
.to_digit(10)
.ok_or(DecodeError::Expected("digit")));
let mut dec = -(digit as $ty);
while let Some(c) = self.chars.next() {
match c.to_digit(10) {
Some(n) => {
if dec < ($name::MIN + n as $ty) / 10 {
return Err(DecodeError::IntOverflow)
}
dec = dec * 10 - n as $ty;
}
None => {
self.chars.put_back(c);
break
}
}
}
Ok(if is_neg {dec} else {-dec})
}
}
}
impl<I: Iterator<Item=char>> Decoder<I> {
pub fn new(c: Config, i: I) -> Decoder<I> {
Decoder {
chars: Source::new(i),
config: c,
buffer: [0; 512]
}
}
pub fn default(i: I) -> Decoder<I> {
Decoder::new(Config::default(), i)
}
pub fn into_iter(self) -> I {
self.chars.into_iter()
}
pub fn decode(&mut self) -> DecodeResult<Json> {
let n = self.config.max_nesting;
self.decode_json(n)
}
fn decode_json(&mut self, level: usize) -> DecodeResult<Json> {
if level == 0 {
return Err(DecodeError::MaxRecursion)
}
self.skip_whitespace();
match require!(self.chars.peek()) {
'"' => self.string().map(Json::String),
't' | 'f' => self.bool().map(Json::Bool),
'n' => self.null().map(|_| Json::Null),
'0' ... '9' | '-' => self.f64().map(Json::Number),
'[' => {
let v = try!(self.array(|d| {
let mut v = Vec::new();
loop {
let x = try!(d.element(|d| Decoder::decode_json(d, level - 1)));
v.push(x.value);
if x.is_last {
break
}
}
Ok(Json::Array(v))
}));
Ok(v.unwrap_or_else(|| Json::Array(Vec::new())))
}
'{' => {
let o = try!(self.object(|d| {
let mut m = HashMap::new();
loop {
let k = try!(d.key());
let v = try!(d.value(|d| Decoder::decode_json(d, level - 1)));
m.insert(k, v.value);
if v.is_last {
break
}
}
Ok(Json::Object(m))
}));
Ok(o.unwrap_or_else(|| Json::Object(HashMap::new())))
}
chr => return Err(DecodeError::Unexpected(chr))
}
}
pub fn skip(&mut self) -> DecodeResult<()> {
let n = self.config.max_nesting;
let mut b = [0; 0];
let mut u = Utf8Buffer::new(&mut b);
self.skip_json(&mut u, n)
}
fn skip_json(&mut self, b: &mut Utf8Buffer, level: usize) -> DecodeResult<()> {
if level == 0 {
return Err(DecodeError::MaxRecursion)
}
self.skip_whitespace();
match require!(self.chars.peek()) {
'"' => self.str(b, false).map(|_| ()),
't' | 'f' => self.bool().map(|_| ()),
'n' => self.null().map(|_| ()),
'0' ... '9' | '-' => self.f64().map(|_| ()),
'[' => {
try!(self.array(|d| {
loop {
let x = try!(d.element(|d| Decoder::skip_json(d, b, level - 1)));
if x.is_last {
break
}
}
Ok(())
}));
Ok(())
}
'{' => {
try!(self.object(|d| {
loop {
try!(d.key_str(b, false));
let v = try!(d.value(|d| Decoder::skip_json(d, b, level - 1)));
if v.is_last {
break
}
}
Ok(())
}));
Ok(())
}
chr => return Err(DecodeError::Unexpected(chr))
}
}
integral!(u8, u8, false);
integral!(u16, u16, false);
integral!(u32, u32, false);
integral!(u64, u64, false);
integral!(usize, usize, false);
integral!(i8, i8, true);
integral!(i16, i16, true);
integral!(i32, i32, true);
integral!(i64, i64, true);
integral!(isize, isize, true);
pub fn f64(&mut self) -> DecodeResult<f64> {
fn is_valid(x: char) -> bool {
match x {
'0'...'9'|'.'|'e'|'E'|'+'|'-' => true,
_ => false
}
}
self.skip_whitespace();
let is_neg =
match self.chars.peek() {
Some('-') => {
self.chars.next();
true
}
_ => false
};
let d = require!(self.chars.next());
if !d.is_digit(10) {
return Err(DecodeError::Unexpected(d))
}
let mut buf = Utf8Buffer::new(&mut self.buffer);
buf.push(d);
while let Some(c) = self.chars.next() {
if is_valid(c) {
buf.push(c)
} else {
self.chars.put_back(c);
break
}
}
match buf.as_str().parse::<f64>() {
Err(_) => Err(DecodeError::Number),
Ok(n) if n.is_nan() => Err(DecodeError::Number),
Ok(n) if n.is_infinite() => Err(DecodeError::Number),
Ok(n) => Ok(if is_neg {-n} else {n})
}
}
pub fn null(&mut self) -> DecodeResult<()> {
self.skip_whitespace();
self.matches("null")
}
pub fn bool(&mut self) -> DecodeResult<bool> {
self.skip_whitespace();
match require!(self.chars.next()) {
't' => self.matches("rue").map(|_| true),
'f' => self.matches("alse").map(|_| false),
chr => Err(DecodeError::Unexpected(chr)),
}
}
pub fn string(&mut self) -> DecodeResult<String> {
let mut s = String::new();
try!(self.string_into(&mut s, false));
Ok(s)
}
pub fn str(&mut self, b: &mut Utf8Buffer, overflow_err: bool) -> DecodeResult<()> {
self.string_into(b, overflow_err)
}
fn string_into<B: Buffer>(&mut self, s: &mut B, overflow_err: bool) -> DecodeResult<()> {
self.skip_whitespace();
if self.chars.next() != Some('"') {
return Err(DecodeError::Expected("\""))
}
let mut escaped = false;
loop {
match require!(self.chars.next()) {
chr if escaped => {
match chr {
'"' => s.push('"'),
'/' => s.push('/'),
'\\' => s.push('\\'),
'b' => s.push('\x08'),
'f' => s.push('\x0C'),
'n' => s.push('\n'),
'r' => s.push('\r'),
't' => s.push('\t'),
'u' => match try!(self.hex_unicode()) {
hi @ 0xD800 ... 0xDBFF => {
try!(self.matches("\\u"));
let lo = try!(self.hex_unicode());
if lo < 0xDC00 || lo > 0xDFFF {
return Err(DecodeError::UnicodeEscape)
}
let c = (((hi - 0xD800) as u32) << 10 | (lo - 0xDC00) as u32) + 0x10000;
s.push(char::from_u32(c).unwrap())
}
0xDC00 ... 0xDFFF => return Err(DecodeError::UnicodeEscape),
x => match char::from_u32(x as u32) {
Some(c) => s.push(c),
None => return Err(DecodeError::UnicodeEscape)
}
},
c => return Err(DecodeError::Unexpected(c))
}
escaped = false
}
'\\' => escaped = true,
'"' => break,
chr => s.push(chr)
}
if overflow_err && s.is_full() {
return Err(DecodeError::BufferOverflow)
}
}
Ok(())
}
pub fn optional<A, F>(&mut self, mut f: F) -> DecodeResult<Option<A>>
where F: FnMut(&mut Decoder<I>) -> DecodeResult<A> {
self.skip_whitespace();
match require!(self.chars.peek()) {
'n' => self.null().map(|_| None),
_ => f(self).map(Some)
}
}
fn container<A, F>
(&mut self,
start: char,
end: char,
expected: &'static str,
mut f: F) -> DecodeResult<Option<A>>
where F: FnMut(&mut Decoder<I>) -> DecodeResult<A> {
self.skip_whitespace();
if self.chars.next() != Some(start) {
return Err(DecodeError::Expected(expected))
}
self.skip_whitespace();
if self.chars.peek() == Some(end) {
self.chars.next();
return Ok(None)
}
f(self).map(Some)
}
pub fn array<A, F>(&mut self, f: F) -> DecodeResult<Option<A>>
where F: FnMut(&mut Decoder<I>) -> DecodeResult<A> {
self.container('[', ']', "[", f)
}
pub fn array1<A, F>(&mut self, f: F) -> DecodeResult<A>
where F: FnMut(&mut Decoder<I>) -> DecodeResult<A> {
match try!(self.array(f)) {
None => Err(DecodeError::Expected("non-empty array")),
Some(a) => Ok(a)
}
}
pub fn array_iter<A, F>(&mut self, f: F) -> DecodeResult<ArrayIter<A, I, F>>
where F: FnMut(&mut Decoder<I>) -> DecodeResult<A> {
self.skip_whitespace();
if self.chars.next() != Some('[') {
return Err(DecodeError::Expected("["))
}
self.skip_whitespace();
if self.chars.peek() == Some(']') {
self.chars.next();
Ok(ArrayIter { gen: f, dec: self, fin: true })
} else {
Ok(ArrayIter { gen: f, dec: self, fin: false })
}
}
pub fn element<A, F>(&mut self, mut f: F) -> DecodeResult<Element<A>>
where F: FnMut(&mut Decoder<I>) -> DecodeResult<A> {
let x = try!(f(self));
self.skip_whitespace();
let is_last =
match require!(self.chars.next()) {
',' => false,
']' => true,
_ => return Err(DecodeError::Expected("',' or ']'")),
};
Ok(Element { value: x, is_last: is_last })
}
pub fn object<A, F>(&mut self, f: F) -> DecodeResult<Option<A>>
where F: FnMut(&mut Decoder<I>) -> DecodeResult<A> {
self.container('{', '}', "{", f)
}
pub fn object1<A, F>(&mut self, f: F) -> DecodeResult<A>
where F: FnMut(&mut Decoder<I>) -> DecodeResult<A> {
match try!(self.object(f)) {
None => Err(DecodeError::Expected("non-empty object")),
Some(a) => Ok(a)
}
}
pub fn key(&mut self) -> DecodeResult<String> {
let mut s = String::new();
try!(self.key_into(&mut s, false));
Ok(s)
}
pub fn key_str(&mut self, b: &mut Utf8Buffer, overflow_err: bool) -> DecodeResult<()> {
self.key_into(b, overflow_err)
}
fn key_into<B: Buffer>(&mut self, s: &mut B, overflow_err: bool) -> DecodeResult<()> {
try!(self.string_into(s, overflow_err));
self.skip_whitespace();
if self.chars.next() != Some(':') {
return Err(DecodeError::Expected(":"))
}
Ok(())
}
pub fn value<A, F>(&mut self, mut f: F) -> DecodeResult<Element<A>>
where F: FnMut(&mut Decoder<I>) -> DecodeResult<A> {
let x = try!(f(self));
self.skip_whitespace();
let is_last =
match require!(self.chars.next()) {
',' => false,
'}' => true,
_ => return Err(DecodeError::Expected("',' or '}'")),
};
Ok(Element { value: x, is_last: is_last })
}
fn skip_whitespace(&mut self) {
while let Some(c) = self.chars.next() {
if !c.is_whitespace() {
self.chars.put_back(c);
break
}
}
}
fn hex_unicode(&mut self) -> DecodeResult<u16> {
let a = try!(hex_byte(require!(self.chars.next())));
let b = try!(hex_byte(require!(self.chars.next())));
let c = try!(hex_byte(require!(self.chars.next())));
let d = try!(hex_byte(require!(self.chars.next())));
Ok(a as u16 * 0x1000 + b as u16 * 0x100 + c as u16 * 0x10 + d as u16)
}
fn matches(&mut self, pattern: &str) -> DecodeResult<()> {
for a in pattern.chars() {
let b = require!(self.chars.next());
if a != b {
return Err(DecodeError::Unexpected(b))
}
}
Ok(())
}
}
fn hex_byte(digit: char) -> DecodeResult<u8> {
match digit {
'0' => Ok(0),
'1' => Ok(1),
'2' => Ok(2),
'3' => Ok(3),
'4' => Ok(4),
'5' => Ok(5),
'6' => Ok(6),
'7' => Ok(7),
'8' => Ok(8),
'9' => Ok(9),
'A' | 'a' => Ok(10),
'B' | 'b' => Ok(11),
'C' | 'c' => Ok(12),
'D' | 'd' => Ok(13),
'E' | 'e' => Ok(14),
'F' | 'f' => Ok(15),
chr => Err(DecodeError::Unexpected(chr))
}
}
pub type DecodeResult<A> = Result<A, DecodeError>;
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum DecodeError {
EndOfInput,
Expected(&'static str),
MaxRecursion,
IntOverflow,
Unexpected(char),
UnicodeEscape,
Number,
BufferOverflow
}
impl fmt::Display for DecodeError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
DecodeError::EndOfInput => write!(f, "end of input"),
DecodeError::Expected(e) => write!(f, "expected \"{}\"", e),
DecodeError::MaxRecursion => write!(f, "max. number of recursions reached"),
DecodeError::IntOverflow => write!(f, "integer overflow"),
DecodeError::Unexpected(c) => write!(f, "unexpected \"{}\"", c),
DecodeError::UnicodeEscape => write!(f, "invalid unicode escape"),
DecodeError::Number => write!(f, "failed to parse number"),
DecodeError::BufferOverflow => write!(f, "buffer overflow")
}
}
}
impl Error for DecodeError {
fn description(&self) -> &str { "DecodeError" }
}
struct Source<I: Iterator> {
iter: I,
front: Option<I::Item>
}
impl<I: Iterator> Source<I> {
fn new(i: I) -> Source<I> {
Source { iter: i, front: None }
}
fn put_back(&mut self, i: I::Item) {
self.front = Some(i)
}
fn peek(&mut self) -> Option<I::Item> where I::Item: Copy {
self.next().map(|c| { self.put_back(c); c })
}
fn into_iter(self) -> I {
self.iter
}
}
impl<I: Iterator> Iterator for Source<I> {
type Item = I::Item;
fn next(&mut self) -> Option<I::Item> {
self.front.take().or_else(|| self.iter.next())
}
}
pub struct ArrayIter<'r, A, I, F>
where F: FnMut(&mut Decoder<I>) -> DecodeResult<A>,
I: Iterator<Item=char> + 'r {
gen: F,
dec: &'r mut Decoder<I>,
fin: bool
}
impl<'r, A, I, F> Iterator for ArrayIter<'r, A, I, F>
where F: FnMut(&mut Decoder<I>) -> DecodeResult<A>,
I: Iterator<Item=char> + 'r {
type Item = DecodeResult<A>;
fn next(&mut self) -> Option<DecodeResult<A>> {
if self.fin {
return None
}
let f = &mut self.gen;
match self.dec.element(f) {
Ok(a) => {
if a.is_last { self.fin = true }
Some(Ok(a.value))
}
Err(e) => Some(Err(e))
}
}
}
pub struct ReadIter<R: Read> {
iter: Chars<R>,
error: Option<ReadError>
}
impl<R: Read> ReadIter<R> {
pub fn new(r: R) -> ReadIter<R> {
ReadIter {
iter: r.chars(),
error: None
}
}
pub fn error(&self) -> Option<&ReadError> {
self.error.as_ref()
}
}
impl<R: Read> Iterator for ReadIter<R> {
type Item = char;
fn next(&mut self) -> Option<char> {
match self.iter.next() {
Some(Ok(c)) => Some(c),
Some(Err(e)) => {
self.error = Some(From::from(e));
None
}
None => None
}
}
}
#[derive(Debug)]
pub enum ReadError {
InvalidUtf8,
Io(io::Error)
}
impl fmt::Display for ReadError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
ReadError::InvalidUtf8 => write!(f, "invalid utf-8 encoding"),
ReadError::Io(ref e) => write!(f, "i/o: {}", e)
}
}
}
impl Error for ReadError {
fn description(&self) -> &str { "ReadError" }
fn cause(&self) -> Option<&Error> {
match *self {
ReadError::Io(ref e) => Some(e),
_ => None
}
}
}
impl From<CharsError> for ReadError {
fn from(e: CharsError) -> ReadError {
match e {
CharsError::NotUtf8 => ReadError::InvalidUtf8,
CharsError::Other(cause) => ReadError::Io(cause)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn empty1() {
let mut d = Decoder::default(r#"[{}]"#.chars());
d.decode().unwrap();
}
#[test]
fn empty2() {
let mut d = Decoder::default(r#"[]"#.chars());
let mut v = Vec::new();
for x in d.array_iter(Decoder::bool).unwrap() {
v.push(x.unwrap())
}
assert!(v.is_empty())
}
#[test]
fn object() {
let mut d = Decoder::default(r#" {"outer": {"inner": 32 } } "#.chars());
d.object(|d| {
let k = try!(d.key());
assert_eq!(String::from("outer"), k);
d.object(|d| {
let k = try!(d.key());
assert_eq!(String::from("inner"), k);
let v = try!(d.value(Decoder::isize));
assert!(v.is_last);
assert_eq!(32, v.value);
Ok(())
})
}).unwrap();
}
#[test]
fn array() {
let mut d = Decoder::default(" [ [ [1, 2 ,3], 42 ] ] ".chars());
let result =
d.array1(|d|
d.array1(|d| {
let (a, b, c) = try!(d.element(|d| {
d.array1(|d| {
let a = try!(d.element(Decoder::isize)).value;
let b = try!(d.element(Decoder::isize)).value;
let c = try!(d.element(Decoder::isize)).value;
Ok((a, b, c))
})
})).value;
let trail = try!(d.element(Decoder::isize)).value;
Ok((a, b, c, trail))
}));
assert_eq!((1, 2, 3, 42), result.unwrap())
}
#[test]
fn array_iter() {
let mut d = Decoder::new(Config::default(), "[ true, false, true ]".chars());
let mut v = Vec::new();
for x in d.array_iter(Decoder::bool).unwrap() {
v.push(x.unwrap())
}
assert_eq!(vec![true,false,true], v)
}
#[test]
fn array_macro() {
fn read_array() -> DecodeResult<Vec<bool>> {
let mut d = Decoder::new(Config::default(), "[ true, false, true ]".chars());
array!(d, Decoder::bool)
}
assert_eq!(vec![true,false,true], read_array().unwrap())
}
#[test]
fn numbers() {
let mut d = Decoder::default("1 0 -1 18446744073709551615 -9223372036854775808 255 256".chars());
assert_eq!(1, d.u8().unwrap());
assert_eq!(0, d.u8().unwrap());
assert_eq!(-1, d.i8().unwrap());
assert_eq!(18446744073709551615, d.u64().unwrap());
assert_eq!(-9223372036854775808, d.i64().unwrap());
assert_eq!(255, d.u8().unwrap());
assert_eq!(Some(DecodeError::IntOverflow), d.u8().err())
}
}