rjson/
lib.rs

1#![no_std]
2#![feature(alloc)]
3#![feature(core_intrinsics)]
4extern crate alloc;
5use alloc::string::String;
6use core::option::Option;
7use core::convert::From;
8
9pub trait Array <T: Value<Self, O, N>, O: Object<T, Self, N>, N: Null<T, Self, O>> where Self: Sized{
10    fn push(&mut self, v: T);
11    fn new() -> Self;
12}
13
14pub trait Object<T: Value<A, Self, N>, A: Array<T, Self, N>, N: Null<T, A, Self>> where Self: Sized{
15    fn insert(&mut self, k: String, v: T);
16    fn new() -> Self;
17}
18
19pub trait Null<T: Value<A, O, Self>, A: Array<T, O, Self>, O: Object<T, A, Self>> where Self: Sized{
20    fn new() -> Self;
21}
22
23pub trait Value<A: Array<Self, O, N>, O: Object<Self, A, N>, N: Null<Self, A, O>>:
24From<String> + From<f64> + From<bool> + From<A> + From<O> + From<N> {
25}
26
27fn is_space(c: char) -> bool {
28    c.is_whitespace() || c == '\t' || c == '\n' || c == '\r'
29}
30pub fn parse<T: Value<A, O, N>, A: Array<T, O, N>, O: Object<T, A, N>, N: Null<T, A, O>>
31(src: &[char], index: &mut usize) -> Option<T> {
32    while src.len() > *index && is_space(src[*index]) {
33        *index += 1;
34    }
35    if src.len() <= *index {
36        return Option::None;
37    }
38    if src[*index] == '{' {
39        parse_object::<T, A, O, N>(src, index).map(|v| T::from(v))
40    } else if src[*index] == '[' {
41        parse_array::<T, A, O, N>(src, index).map(|v| T::from(v))
42    } else if src[*index] == 't' {
43        parse_true(src, index).map(|v| T::from(v))
44    } else if src[*index] == 'f' {
45        parse_false(src, index).map(|v| T::from(v))
46    } else if src[*index] == '"' {
47        parse_string(src, index).map(|v| T::from(v))
48    } else if src[*index] == 'n' {
49        parse_null::<T, A, O, N>(src, index).map(|v| T::from(v))
50    } else if src[*index] == '-' || src[*index].is_ascii_digit() {
51        parse_number(src, index).map(|v| T::from(v))
52    } else {
53        Option::None
54    }
55}
56
57fn parse_object<T: Value<A, O, N>, A: Array<T, O, N>, O: Object<T, A, N>, N: Null<T, A, O>>
58(src: &[char], index: &mut usize) -> Option<O> {
59    if src.len() <= *index + 1 || src[*index] != '{' {
60        return Option::None;
61    }
62    *index += 1;
63    let mut v = O::new();
64    while src.len() > *index {
65        while src.len() > *index && is_space(src[*index]) {
66            *index += 1;
67        }
68        if src.len() <= *index {
69            return Option::None;
70        }
71        if src[*index] == '}' {
72            *index += 1;
73            return Some(v);
74        }
75        let k = parse_string(src, index);
76        if k.is_none() {
77            return Option::None;
78        }
79        while src.len() > *index && is_space(src[*index]) {
80            *index += 1;
81        }
82        if src.len() <= *index {
83            return Option::None;
84        }
85        if src[*index] != ':' {
86            return Option::None;
87        }
88        *index += 1;
89        while src.len() > *index && is_space(src[*index]) {
90            *index += 1;
91        }
92        if src.len() <= *index {
93            return Option::None;
94        }
95        let c = parse::<T, A, O, N>(src, index);
96        if c.is_none() {
97            return Option::None;
98        }
99        v.insert(k.unwrap(), c.unwrap());
100        while src.len() > *index && is_space(src[*index]) {
101            *index += 1;
102        }
103        if src.len() <= *index {
104            return Option::None;
105        }
106        if src[*index] == ',' {
107            *index += 1;
108        } else if src[*index] == '}' {
109            *index += 1;
110            return Some(v);
111        } else {
112            return Option::None;
113        }
114    }
115    Option::None
116}
117
118fn parse_array<T: Value<A, O, N>, A: Array<T, O, N>, O: Object<T, A, N>, N: Null<T, A, O>>
119(src: &[char], index: &mut usize) -> Option<A> {
120    if src.len() <= *index + 1 || src[*index] != '[' {
121        return Option::None;
122    }
123    *index += 1;
124    let mut v = A::new();
125    while src.len() > *index {
126        while src.len() > *index && is_space(src[*index]) {
127            *index += 1;
128        }
129        if src.len() <= *index {
130            return Option::None;
131        }
132        if src[*index] == ']' {
133            *index += 1;
134            return Some(v);
135        }
136        let i = parse::<T, A, O, N>(src, index);
137        if i.is_none() {
138            return Option::None;
139        }
140        v.push(i.unwrap());
141        while src.len() > *index && is_space(src[*index]) {
142            *index += 1;
143        }
144        if src.len() <= *index {
145            return Option::None;
146        }
147        if src[*index] == ',' {
148            *index += 1;
149        } else if src[*index] == ']' {
150            *index += 1;
151            return Some(v);
152        } else {
153            return Option::None;
154        }
155    }
156    Option::None
157}
158
159fn parse_true(src: &[char], index: &mut usize) -> Option<bool> {
160    let mut test_true = "true".chars();
161    while src.len() > *index {
162        let c = test_true.next();
163        if c.is_none() {
164            return Some(true);
165        }
166        if src[*index] == c.unwrap() {
167            *index += 1;
168        } else {
169            return Option::None;
170        }
171    }
172    Option::None
173}
174fn parse_false(src: &[char], index: &mut usize) -> Option<bool> {
175    let mut test_false = "false".chars();
176    while src.len() > *index {
177        let c = test_false.next();
178        if c.is_none() {
179            return Some(false);
180        }
181        if src[*index] == c.unwrap() {
182            *index += 1;
183        } else {
184            return Option::None;
185        }
186    }
187    Option::None
188}
189
190fn parse_null<T: Value<A, O, N>, A: Array<T, O, N>, O: Object<T, A, N>, N: Null<T, A, O>>
191(src: &[char], index: &mut usize) -> Option<N> {
192    let mut test_null = "null".chars();
193    while src.len() > *index {
194        let c = test_null.next();
195        if c.is_none() {
196            return Some(N::new());
197        }
198        if src[*index] == c.unwrap() {
199            *index += 1;
200        } else {
201            return Option::None;
202        }
203    }
204    Option::None
205}
206
207fn parse_string_unicode(src: &[char], index: &mut usize) -> Option<char> {
208    if src.len() <= *index + 4 {
209        return Option::None;
210    }
211    let mut v: u32 = 0;
212    for i in 1..5 {
213        let d = src[*index + i].to_digit(16).unwrap_or(16);
214        if d == 16 {
215            return Option::None;
216        }
217        v = v * 16 + d;
218    }
219    *index += 4; // because there is another `*index += 1` in `parse_string`
220    use core::char;
221    unsafe { Some(char::from_u32_unchecked(v)) }
222}
223
224fn parse_string(src: &[char], index: &mut usize) -> Option<String> {
225    if src.len() <= *index + 1 || src[*index] != '"'  {
226        return Option::None;
227    }
228    *index += 1;
229    let mut v = String::new();
230    let mut escaped = false;
231    while src.len() > *index {
232        if escaped {
233            let c = match src[*index] {
234                'b' => '\u{0008}',
235                'f' => '\u{000c}',
236                'n' => '\n',
237                'r' => '\r',
238                't' => '\t',
239                '\n' => '\0',
240                '\r' => '\0',
241                'u' => parse_string_unicode(src, index).unwrap_or('\u{fffd}'),
242                _ => src[*index]
243            };
244            if c!= '\0' {
245                v.push(c);
246            }
247            escaped = false;
248        } else if src[*index] == '\\' {
249            escaped = true;
250        } else if src[*index] == '"' {
251            *index += 1;
252            return Some(v);
253        } else {
254            v.push(src[*index]);
255        }
256        *index += 1;
257    }
258    Option::None 
259}
260
261fn parse_number_integer(src: &[char], index: &mut usize) -> f64 {
262    let mut v: f64 = 0 as f64;
263    while src.len() > *index && src[*index].is_ascii_digit() {
264        v = v * 10.0 + src[*index].to_digit(10).unwrap() as f64;
265        *index += 1;
266    }
267    v
268}
269
270fn parse_number_decimal(src: &[char], index: &mut usize) -> f64 {
271    let head = *index;
272    let v = parse_number_integer(src, index);
273    v * unsafe { core::intrinsics::powif64(0.1, (*index - head) as i32) }
274}
275
276fn parse_number(src: &[char], index: &mut usize) -> Option<f64> {
277    let mut v: f64 = 0 as f64;
278    let mut sign = 1;
279    if src.len() <= *index {
280        return Option::None;
281    }
282    if src[*index] == '-' {
283        sign = -1;
284        *index += 1;
285        if src.len() <= *index {
286            return Option::None;
287        }
288    }
289    if src[*index] != '0' {
290        v += parse_number_integer(src, index);
291    } else {
292        *index += 1;
293    }
294    if src.len() <= *index {
295        return Some(v * sign as f64);
296    }
297    if src[*index] == '.' {
298        *index += 1;
299        v += parse_number_decimal(src, index);
300        if src.len() <= *index {
301            return Some(v * sign as f64);
302        }
303    }
304    if src[*index] == 'e' || src[*index] == 'E' {
305        *index += 1;
306        if src.len() <= *index {
307            return Option::None;
308        }
309        let mut e_sign = 1;
310        if src[*index] == '-' || src[*index] == '+' {
311            e_sign = if src[*index] == '-' { -1 } else { 1 };
312            *index += 1;
313            if src.len() <= *index {
314                return Option::None;
315            }
316        }
317        let e = parse_number_integer(src, index);
318        v *= unsafe { core::intrinsics::powif64(10.0, e as i32 * e_sign) };
319    }
320    Some(v * sign as f64)
321}