1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
mod common;
mod object;
mod string;
mod array;
mod number;

use common::*;
pub use common::{Json,Jerr};

struct BasicIteratorParser;

impl IteratorParser for BasicIteratorParser {
    fn parse(&self,iter:&mut StrIt)->Result<Json,Jerr> {
        
        if begins_with_str(iter, "true"){
            return Ok(Json::Bool(true));
        }
        else if begins_with_str(iter, "false"){
            return Ok(Json::Bool(false));
        }
        else if begins_with_str(iter, "null"){
            return Ok(Json::Null);
        }
        else if is_number(iter) {
            number::JNumberParser::parse(iter)
        }
        else if is_string(iter) {
            let mut parser = crate::string::JStringParser::new();
            parser.parse(iter)
        }
        else if is_array(iter) {
            let mut parser = crate::array::JArrayParser::new();
            parser.parse(iter,self)
        }
        else if is_object(iter) {
            let mut parser = crate::object::JObjectParser::new();
            parser.parse(iter,self)
        }
        else { // unknown token
            Err(Jerr::UnexpectedChar(iter.peek().unwrap().0))
        }
    }
}

impl Json {
    pub fn parse(input:&String)->Result<Json,Jerr> {
        let mut iter = make_iterator(input.as_str().trim());
        let basic_parser = BasicIteratorParser;
        let json = basic_parser.parse(&mut iter)?;
        match iter.peek()  {
            None=>Ok(json),
            Some((i,_))=>Err(Jerr::ExpectedEnd(*i))
        }
    }
    pub fn as_number(&self)-> Option<&String> {
        match self {
            Json::Number(num)=>Some(num),
            _=>None
        }
    }
    pub fn as_string(&self)-> Option<&String> {
        match self {
            Json::String(str)=>Some(str),
            _=>None
        }
    }
    pub fn as_bool(&self)-> Option<&bool> {
        match self {
            Json::Bool(b)=>Some(b),
            _=>None
        }
    }
    pub fn as_null(&self)-> Option<()> {
        match self {
            Json::Null=>Some(()),
            _=>None
        }
    }
    pub fn as_array(&self)-> Option<&Vec<Json>> {
        match self {
            Json::Array(vec)=>Some(vec),
            _=>None
        }
    }
    pub fn as_mut_array(&mut self)-> Option<&mut Vec<Json>> {
        match self {
            Json::Array(vec)=>Some(vec),
            _=>None
        }
    }
    pub fn as_object(&self)-> Option<&Jmap> {
        match self {
            Json::Object(o)=>Some(o),
            _=>None
        }
    }
    pub fn as_mut_object(&mut self)-> Option<&mut Jmap> {
        match self {
            Json::Object(o)=>Some(o),
            _=>None
        }
    }
}

#[cfg(test)]
mod test {
    use crate::{BasicIteratorParser, common::{IteratorParser, make_iterator}};

    #[test]
    fn iterator_preserves_position(){
        let text = String::from("null,");
        let mut iter = make_iterator(text.as_str());
        let parser = BasicIteratorParser;
        parser.parse(&mut iter).unwrap();
        assert_eq!(iter.peek().unwrap().0,4);
    }

    #[test]
    fn preserves_position_on_number(){
        let text = String::from("234 ");
        let mut iter = make_iterator(text.as_str());
        let parser = BasicIteratorParser;
        parser.parse(&mut iter).unwrap();
        assert_eq!(iter.peek().unwrap().0,3);
    }

    #[test]
    fn preserves_position_on_string(){
        let text = String::from("\"text\":true");
        let mut iter = make_iterator(text.as_str());
        let parser = BasicIteratorParser;
        parser.parse(&mut iter).unwrap();
        assert_eq!(iter.peek().unwrap().0,6);
    }
}