lil_json/
lib.rs

1#![no_std]
2
3use core::fmt::{Debug, Display, Formatter, Write as CoreFmtWrite};
4use embedded_io::{ErrorType, Write};
5use numtoa::base10;
6
7#[cfg(feature = "alloc")]
8extern crate elsa;
9#[cfg(feature = "alloc")]
10use elsa::FrozenVec;
11
12/// (re-export of `esla::FrozenVec<String>`) a buffer for infinite string escaping. enabled with `alloc` feature.
13#[cfg(feature = "alloc")]
14pub type InfiniteEscapeBuffer = FrozenVec<String>;
15
16/// trait for types that JSON can be serialized into. mainly meant for internal usage.
17pub trait StringWrite {
18    type StringWriteFailure: Debug;
19    fn write_char(&mut self, data: char, bytes_to_skip: usize) -> Result<usize,(usize,Self::StringWriteFailure)>;
20}
21
22impl<T: Write + ErrorType> StringWrite for T {
23    type StringWriteFailure = T::Error;
24    fn write_char(&mut self, data: char, resume_from: usize) -> Result<usize,(usize,Self::StringWriteFailure)> {
25        debug_assert!(resume_from <= 4);
26        let mut str_buffer = [0_u8; 4];
27        let encoded_string = data.encode_utf8(str_buffer.as_mut_slice()).as_bytes();
28        let to_skip = core::cmp::min(encoded_string.len(), resume_from);
29        let target = encoded_string.split_at(to_skip).1;
30        if target.is_empty() {
31            return Ok(0);
32        }
33        match self.write_all(target) {
34            Ok(()) => Ok(target.len() + to_skip),
35            Err(e) => Err((0,e))
36        }
37    }
38}
39
40struct FormatWrapper<T: ?Sized> {
41    inner: T,
42}
43
44impl<T> FormatWrapper<T> {
45    fn new(inner: T) -> Self {
46        FormatWrapper { inner }
47    }
48}
49
50impl<'a> StringWrite for FormatWrapper<&mut Formatter<'a>> {
51    type StringWriteFailure = core::fmt::Error;
52    fn write_char(&mut self, data: char, bytes_to_skip: usize) -> Result<usize,(usize,Self::StringWriteFailure)> {
53        assert!(bytes_to_skip == 0);
54        let mut encoding_buffer = [0_u8; 4];
55        let n = data.encode_utf8(encoding_buffer.as_mut_slice()).len();
56        match self.inner.write_char(data) {
57            Ok(()) => Ok(n),
58            Err(e) => Err((0,e))
59        }
60    }
61}
62
63/// trait for an optionally mutable collection of JSON array values
64pub trait ValueBuffer<'a>: AsRef<[JsonValue<'a>]> {
65
66    /// convenience one-liner to call JsonArray::wrap_init on this Sized type, consuming it
67    fn into_json_array(self) -> JsonArray<Self> where Self: Sized {
68        JsonArray::wrap_init(self)
69    }
70    
71    /// convenience one-liner to call JsonArray::wrap_init on an immutable reference to this type
72    fn as_json_array(&self) -> JsonArray<&Self> {
73        JsonArray::wrap_init(self)
74    }
75
76}
77
78/// ValueBuffer is automatically implemented for all types that implement AsRef<[JsonField<'data,'data>]>
79impl <'a,T: AsRef<[JsonValue<'a>]>> ValueBuffer<'a> for T {}
80
81
82/// trait for a mutable collection of JSON array values
83pub trait ValueBufferMut<'a>: ValueBuffer<'a> +  AsMut<[JsonField<'a,'a>]> {
84
85    /// convenience one-liner to call JsonObject::wrap_init on a mutable reference to this type
86    fn as_json_array_mut(&mut self) -> JsonArray<&mut Self> {
87        JsonArray::wrap_init(self)
88    }
89}
90
91/// ValueBufferMut is automatically implemented for all types that implement FieldBuffer + AsMut<[JsonField<'data,'data>]>
92impl <'a,T: ValueBuffer<'a> + AsMut<[JsonField<'a,'a>]>> ValueBufferMut<'a> for T {}
93
94
95/// trait for all optionally mutable collection of JSON object fields
96pub trait FieldBuffer<'data>: AsRef<[JsonField<'data,'data>]> {
97
98    /// convenience one-liner to call JsonObject::wrap_init on this Sized type, moving it
99    fn into_json_object(self) -> JsonObject<Self> where Self: Sized {
100        JsonObject::wrap_init(self)
101    }
102    
103    /// convenience one-liner to call JsonObject::wrap_init on an immutable reference to this type
104    fn as_json_object(&self) -> JsonObject<&Self> {
105        JsonObject::wrap_init(self)
106    }
107
108}
109
110/// FieldBuffer is automatically implemented for all types that implement AsRef<[JsonField<'data,'data>]>
111impl <'a,T: AsRef<[JsonField<'a,'a>]>> FieldBuffer<'a> for T {}
112
113/// trait for a mutable collection of JSON object fields
114pub trait FieldBufferMut<'a>: FieldBuffer<'a> +  AsMut<[JsonField<'a,'a>]> {
115
116    /// convenience one-liner to call JsonObject::wrap_init on a mutable reference to this type
117    fn as_json_object_mut(&mut self) -> JsonObject<&mut Self> {
118        JsonObject::wrap_init(self)
119    }
120
121}
122
123/// FieldBufferMut is automatically implemented for all types that implement FieldBuffer + AsMut<[JsonField<'data,'data>]>
124impl <'a,T: FieldBuffer<'a> + AsMut<[JsonField<'a,'a>]>> FieldBufferMut<'a> for T {}
125
126/// the various reasons parsing JSON can fail
127#[derive(Debug,PartialEq,Eq,Clone,Copy)]
128pub enum JsonParseFailure {
129    /// there was no error, but the data slice is incomplete
130    Incomplete,
131    /// there was no error, but there were more fields than the provided field buffer could hold
132    FieldBufferTooSmall,
133    /// there was no error, but there were more fields than the provided string escape buffer could hold
134    EscapeBufferTooSmall,
135    /// there was an error in the JSON structure of the data
136    InvalidStructure,
137    /// an invalid JSON string was encountered
138    InvalidStringField,
139    /// an invalid JSON number was encountered
140    InvalidNumericField,
141    /// a valid JSON number was encountered but we failed to interpret it
142    NumberParseError,
143    /// an invalid JSON boolean was encountered
144    InvalidBooleanField,
145    /// an invalid JSON null was encountered
146    InvalidNullField,
147}
148
149/// terminal (non-nested) JSON types
150#[derive(Debug,PartialEq,Eq,Clone,Copy)]
151pub enum JsonValue<'a> {
152    /// a JSON string - it will be automatically escaped
153    String(&'a str),
154    /// a JSON boolean
155    Boolean(bool),
156    /// a JSON number
157    Number(i64),
158    /// a JSON null value
159    Null,
160}
161
162impl <'a> JsonValue<'a> {
163    pub fn parse(data: &'a [u8], escape_buffer_slice: &'a mut [u8]) -> Result<(usize,Self),JsonParseFailure> {
164        let mut escape_buffer = StringBuffer::Finite(0, escape_buffer_slice);
165        let mut current_data_index = 0_usize;
166        skip_whitespace(&mut current_data_index, data)?;
167        // let first_character = data[current_data_index];
168        let value = if data[current_data_index] == b'"' {
169                let unescaped_string_value = unescape_json_string(&mut current_data_index, data, &mut escape_buffer)?;
170                JsonValue::String(unescaped_string_value)
171            } else if data[current_data_index] == b'n' {
172                skip_literal(&mut current_data_index, data, "null", JsonParseFailure::InvalidBooleanField)?;
173                JsonValue::Null
174            } else if data[current_data_index] == b't' || data[current_data_index] == b'f' {
175                let expect_true = data[current_data_index] == b't';
176                skip_literal(&mut current_data_index, data, if expect_true { "true" } else { "false"}, JsonParseFailure::InvalidBooleanField)?;
177                JsonValue::Boolean(expect_true)
178            } else if data[current_data_index] == b'-' {
179                // negative number
180                let minus_sign_numeric_start_index = current_data_index;
181                current_data_index += 1;
182                skip_numeric(&mut current_data_index, data)?;
183                let minus_sign_numeric_end = current_data_index;
184                if minus_sign_numeric_end - minus_sign_numeric_start_index == 1 {
185                    // no digits found
186                    return Err(JsonParseFailure::InvalidNumericField);
187                }
188                let numeric_string = core::str::from_utf8(&data[minus_sign_numeric_start_index..minus_sign_numeric_end]).expect("skipped negative number digit(s)");
189                let numeric_value: i64 = match numeric_string.parse() {
190                    Ok(i) => i,
191                    Err(_parse_int_error) => return Err(JsonParseFailure::NumberParseError),
192                };
193                JsonValue::Number(numeric_value)
194            } else if data[current_data_index] >= b'0' && data[current_data_index] < b'9' {
195                // positive number
196                let numeric_start_index = current_data_index;
197                current_data_index += 1;
198                skip_numeric(&mut current_data_index, data)?;
199                let numeric_after_index = current_data_index;
200                let numeric_string = core::str::from_utf8(&data[numeric_start_index..numeric_after_index]).expect("skipped positive number digit(s)");
201                let numeric_value: i64 = match numeric_string.parse() {
202                    Ok(i) => i,
203                    Err(_parse_int_error) => return Err(JsonParseFailure::NumberParseError),
204                };
205                JsonValue::Number(numeric_value)
206            } else {
207                return Err(JsonParseFailure::InvalidStructure);
208            };
209            Ok((current_data_index,value))
210    }
211}
212
213impl<'a> Default for JsonValue<'a> {
214    fn default() -> Self { JsonValue::Null }
215}
216
217impl From<i64> for JsonValue<'static> {
218    fn from(n: i64) -> Self {
219        Self::Number(n)
220    }
221}
222
223impl From<bool> for JsonValue<'static> {
224    fn from(b: bool) -> Self {
225        Self::Boolean(b)
226    }
227}
228
229impl From<()> for JsonValue<'static> {
230    fn from(_: ()) -> Self {
231        Self::Null
232    }
233}
234
235impl<'a> From<&'a str> for JsonValue<'a> {
236    fn from(s: &'a str) -> Self {
237        Self::String(s)
238    }
239}
240
241/// a field within a JSON object
242#[derive(Debug,PartialEq,Eq,Clone,Copy)]
243pub struct JsonField<'a,'b> {
244    pub key: &'a str,
245    pub value: JsonValue<'b>,
246}
247
248impl <'a,'b> JsonField<'a,'b> {
249    /// create a new JSON object field with the given key & value
250    pub const fn new(key: &'a str, value: JsonValue<'b>) -> Self {
251        JsonField { key, value }
252    }
253
254    /// convenience helper to get the json field as a (key,value) tuple
255    pub const fn from_tuple(tuple: (&'a str, JsonValue<'b>)) -> Self {
256        Self::new(tuple.0, tuple.1)
257    }
258
259    /// convenience helper to get the json field as a (key,value) tuple
260    pub const fn as_tuple(&self) -> (&'a str, JsonValue<'b>) {
261        (self.key, self.value)
262    }
263
264    /// convenience helper to create a new JSON object string field
265    pub const fn new_string(key: &'a str, value: &'b str) -> Self {
266        Self::new(key, JsonValue::String(value))
267    }
268    /// convenience helper to create a new JSON object number field
269    pub const fn new_number(key: &'a str, value: i64) -> Self {
270        Self::new(key, JsonValue::Number(value))
271    }
272    /// convenience helper to create a new JSON object boolean field
273    pub const fn new_boolean(key: &'a str, value: bool) -> Self {
274        Self::new(key, JsonValue::Boolean(value))
275    }
276}
277
278/// two JsonObjects are equal if their initialized fields are identical (in the same order)
279impl<'a,T: FieldBuffer<'a>> PartialEq for JsonObject<T> {
280    fn eq(&self, other: &JsonObject<T>) -> bool {
281        self.num_fields == other.num_fields && PartialEq::eq(self.fields.as_ref(), other.fields.as_ref())
282    }
283}
284
285/// PartialEq for JsonObject is reflexive
286impl<'a,T: FieldBuffer<'a>> Eq for JsonObject<T> {}
287
288/// a default JSON field with static lifetime. equivalent to `{"":null}``.
289pub const EMPTY_FIELD: JsonField<'static,'static> = JsonField{ key: "", value: JsonValue::Null};
290
291impl <'a,'b,V: Into<JsonValue<'b>>> From<(&'a str, V)> for JsonField<'a,'b> {
292    fn from(tuple: (&'a str, V)) -> Self {
293        Self::new(tuple.0, tuple.1.into())
294    }
295}
296
297impl <'a,'b> Default for JsonField<'a,'b> {
298    fn default() -> Self {
299        EMPTY_FIELD
300    }
301}
302
303/// JsonObject represents an RFC 8259 JSON Array. It wraps a mutable or immutable buffer of JSON values.  The easiest way to use it is through the ArrayJsonArray type alias, however you can use JsonArray directly to wrap your own buffer like a heap allocated Vec.
304#[derive(Debug,Clone,Copy)]
305pub struct JsonArray<Values> {
306    values: Values,
307    num_values: usize,
308}
309
310impl<T> JsonArray<T> {
311    /// consume this JsonObject to return (field buffer, num fields considered initialized)
312    pub fn into_inner(self) -> (T,usize) {
313        (self.values,self.num_values)
314    }
315}
316
317impl<'a,T: FieldBuffer<'a> + Default + ?Sized> Default for JsonArray<T> {
318    fn default() -> Self {
319        JsonArray { values: T::default(), num_values: 0 }
320    }
321}
322
323impl <'a,T: ValueBuffer<'a>> JsonArray<T> {
324
325    /// wrap a collection of values into a JsonArray and considers none of the values to be initialized
326    pub const fn wrap(values: T) -> Self {
327        JsonArray { values, num_values: 0 }
328    }
329
330    /// wrap a collection of fields into a JsonObject and considers all of the fields to be initialized
331    pub fn wrap_init(values: T) -> Self {
332        let num_values = values.as_ref().len();
333        JsonArray { values, num_values }
334    }
335
336    /// get the number of initialized values in this JsonArray. Same as self.values().len()
337    pub const fn len(&self) -> usize {
338        self.num_values
339    }
340
341    /// get the max number of values this JsonArray can store
342    pub fn capacity(&self) -> usize {
343        self.values.as_ref().len()
344    }
345
346    /// get an immutable reference to the initialized values of this JsonArray
347    pub fn values(&self) -> &[JsonValue<'a>] {
348        self.values.as_ref().split_at(self.num_values).0
349    }
350
351    /// attempt to serialize this JsonArray into the provided output & returns the number of bytes written on success
352    pub fn serialize<Output: Write>(&self, mut output: Output) -> Result<usize,Output::Error> {
353        match serialize_json_array(&mut output, self.values().as_ref(), 0) {
354            Ok(n) => Ok(n),
355            Err((_written,e)) => Err(e),
356        }
357    }
358
359    /// attempt to serialize this JsonArray into the provided output starting from `resume_from` & returns the number of bytes written on both success & failure
360    pub fn serialize_resume<Output: Write>(&self, mut output: Output, resume_from: usize) -> Result<usize,(usize,Output::Error)> {
361        serialize_json_array(&mut output, self.values().as_ref(), resume_from)
362    }
363
364}
365
366impl <'a,T: ValueBuffer<'a>> Display for JsonArray<T> {
367    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), core::fmt::Error> {
368        match serialize_json_array(
369            &mut FormatWrapper::new(fmt),
370            self.values.as_ref(),
371            0,
372        ) {
373            Ok(_) => Ok(()),
374            Err((_written,e)) => Err(e),
375        }
376    }
377}
378
379/// ArrayJsonObject is a type alias for a JsonObject that wraps an array. It has extra functionality when compared to any other type of JsonObject.
380pub type ArrayJsonArray<'a,const N: usize> = JsonArray<[JsonValue<'a>; N]>;
381
382impl<'a,const N: usize> ArrayJsonArray<'a,N> {
383    
384    /// convenience method to initialize a new array & call JsonObject::wrap on it
385    pub const fn new() -> Self {
386        JsonArray::wrap([JsonValue::Null; N])
387    }
388
389    /// convenience method to automatically create an ArrayJsonObject if object parsing is successful
390    // pub fn new_parsed(data: &'a [u8], escape_buffer: &'a mut [u8]) -> Result<(usize,Self),JsonParseFailure> {
391    //     let mut ret = Self::new();
392    //     let data_end = ret.parse(data, escape_buffer)?;
393    //     Ok((data_end,ret))
394    // }
395
396    /// similar to JsonObject::push but supports const contexts & only returns a reference
397    pub const fn push_const(&mut self, value: JsonValue<'a>) -> Result<(),()> {
398        if self.num_values == N {
399            return Err(());
400        }
401        self.values[self.num_values] = value;
402        self.num_values += 1;
403        Ok(())
404    }
405
406    /// similar to JsonObject::pop but supports const contexts
407    pub const fn pop_const(&mut self) -> Option<&JsonValue<'a>> {
408        match self.values_const().split_last() {
409            None => return None,
410            Some((split,_remaining)) => return Some(split),
411        }
412    }
413
414    /// same as JsonObject::fields but supports const contexts
415    pub const fn values_const(&self) -> &[JsonValue<'a>] {
416        self.values.split_at(self.num_values).0
417    }
418
419    /// same as JsonObject::fields_mut but supports const contexts
420    pub const fn values_mut_const(&mut self) -> &mut [JsonValue<'a>] {
421        self.values.split_at_mut(self.num_values).0
422    }
423}
424
425
426/// JsonObject represents an RFC 8259 JSON Object. It wraps a mutable or immutable buffer of object fields. The easiest way to use it is through the ArrayJsonObject type alias, however you can use JsonObject directly to wrap your own buffer like a heap allocated Vec
427#[derive(Debug,Clone,Copy)]
428pub struct JsonObject<Fields> {
429    fields: Fields,
430    num_fields: usize,
431}
432
433impl<T> JsonObject<T> {
434    /// consume this JsonObject to return (field buffer, num fields considered initialized)
435    pub fn into_inner(self) -> (T,usize) {
436        (self.fields,self.num_fields)
437    }
438}
439
440impl<'a,T: FieldBuffer<'a> + Default + ?Sized> Default for JsonObject<T> {
441    fn default() -> Self {
442        JsonObject::wrap(T::default())
443    }
444}
445
446impl <'a,T: FieldBuffer<'a>> JsonObject<T> {
447
448    /// wrap a collection of fields into a JsonObject and considers none of the fields to be initialized
449    pub const fn wrap(fields: T) -> Self {
450        JsonObject { fields, num_fields: 0 }
451    }
452
453    /// wrap a collection of fields into a JsonObject and considers all of the fields to be initialized
454    pub fn wrap_init(fields: T) -> Self {
455        let num_fields = fields.as_ref().len();
456        JsonObject { fields, num_fields }
457    }
458
459    /// get the number of initialized fields in this JsonObject. Same as self.fields().len().
460    pub const fn len(&self) -> usize {
461        self.num_fields
462    }
463
464    /// get the max number of fields this JsonObject can store.
465    pub fn capacity(&self) -> usize {
466        self.fields.as_ref().len()
467    }
468
469    /// get an immutable reference to the initialized fields of this JsonObject
470    pub fn fields(&self) -> &[JsonField<'a,'a>] {
471        self.fields.as_ref().split_at(self.num_fields).0
472    }
473
474    /// attempt to serialize this JsonObject into the provided output & returns the number of bytes written on success
475    pub fn serialize<Output: Write>(&self, mut output: Output) -> Result<usize,Output::Error> {
476        match serialize_json_object(&mut output, self.fields().as_ref(), 0) {
477            Ok(n) => Ok(n),
478            Err((_written,e)) => Err(e),
479        }
480    }
481
482    /// attempt to serialize this JsonObject into the provided output starting from `resume_from` & returns the number of bytes written on both success & failure
483    pub fn serialize_resume<Output: Write>(&self, mut output: Output, resume_from: usize) -> Result<usize,(usize,Output::Error)> {
484        serialize_json_object(&mut output, self.fields().as_ref(), resume_from)
485    }
486}
487
488impl <'a,T: FieldBuffer<'a>> Display for JsonObject<T> {
489    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), core::fmt::Error> {
490        match serialize_json_object(
491            &mut FormatWrapper::new(fmt),
492            self.fields.as_ref(),
493            0
494        ) {
495            Ok(_) => Ok(()),
496            Err((_written,e)) => Err(e),
497        }
498    }
499}
500
501impl <'a,T: FieldBuffer<'a>> From<T> for JsonObject<T> {
502    fn from(t: T) -> Self {
503        Self::wrap_init(t)
504    }
505}
506
507impl <'a,T: FieldBufferMut<'a>> JsonObject<T> {
508
509    /// get a mutable reference to the initialized fields of this JsonObject
510    pub fn fields_mut(&mut self) -> &mut [JsonField<'a,'a>] {
511        self.fields.as_mut().split_at_mut(self.num_fields).0
512    }
513
514    /// attempt to push a new field - returns the field if there is not enough space
515    pub fn push<'x: 'a,'y: 'a>(&mut self, field: JsonField<'x,'y>) -> Result<(),JsonField<'x,'y>> {
516        if self.num_fields == self.fields.as_ref().len(){
517            return Err(field);
518        }
519        self.fields.as_mut()[self.num_fields] = field;
520        self.num_fields += 1;
521        Ok(())
522    }
523
524    /// attempt to pop an existing field - returns None if there are no initialized fields
525    pub fn pop(&mut self) -> Option<JsonField<'a,'a>> {
526        if self.num_fields == 0 {
527            return None;
528        }
529        self.num_fields -= 1;
530        Some(core::mem::take(&mut self.fields.as_mut()[self.num_fields+1]))
531    }
532
533    /// convenience helper to create and push a new field
534    pub fn push_field<'x: 'a,'y: 'a>(&mut self, key: &'x str, value: JsonValue<'y>) -> Result<(),()> {
535        if self.num_fields == self.fields.as_ref().len(){
536            return Err(());
537        }
538        self.fields.as_mut()[self.num_fields] = JsonField { key, value };
539        self.num_fields += 1;
540        Ok(())
541    }
542
543    /// attempt to parse a JSON object from the provided data slice and write its fields into this JsonObject - returns a tuple of (num bytes consumed, num fields parsed) on success
544    pub fn parse(&mut self, data: &'a [u8], string_escape_buffer: &'a mut [u8]) -> Result<usize,JsonParseFailure> {
545        let (data_end, parsed_fields) = parse_json_object(
546            data,
547            ParseBuffer::Finite(0, self.fields.as_mut()),
548            &mut StringBuffer::Finite(0, string_escape_buffer),
549        )?;
550        let new_num_fields = parsed_fields;
551        self.num_fields = new_num_fields;
552        Ok(data_end)
553    }
554
555    /// attempt to parse a JSON object from the provided data slice and write its fields into this JsonObject while allocating space as needed for storing escaped strings
556    /// returns num bytes consumed on success
557    #[cfg(feature = "alloc")]
558    pub fn parse_alloc_escape(&mut self, data: &'a [u8], escape_buffer: &'a FrozenVec<String>) -> Result<usize,JsonParseFailure> {
559        let (data_end, parsed_fields) = parse_json_object(
560            data,
561            ParseBuffer::Finite(0,self.fields.as_mut()),
562            &mut crate::StringBuffer::Infinite(String::new(), escape_buffer)
563        )?;
564        let new_num_fields = parsed_fields;
565        self.num_fields = new_num_fields;
566        Ok(data_end)
567    }
568
569}
570
571impl <'a,T: FieldBufferMut<'a> + Default> JsonObject<T> {
572
573    /// convenience method to automatically create a JsonObject if object parsing is successful
574    pub fn default_parsed(data: &'a [u8], escape_buffer: &'a mut [u8]) -> Result<(usize,Self),JsonParseFailure> {
575        let mut ret = Self::default();
576        let num_bytes = ret.parse(data, escape_buffer)?;
577        Ok((num_bytes,ret))
578    }
579
580}
581
582
583/// ArrayJsonObject is a type alias for a JsonObject that wraps an array. It has extra functionality when compared to any other type of JsonObject.
584pub type ArrayJsonObject<'a,const N: usize> = JsonObject<[JsonField<'a,'a>; N]>;
585
586impl<'a,const N: usize> ArrayJsonObject<'a,N> {
587
588    /// convenience method to initialize a new array & call JsonObject::wrap on it
589    pub const fn new() -> Self {
590        JsonObject::wrap([EMPTY_FIELD; N])
591    }
592
593    /// convenience method to automatically create an ArrayJsonObject if object parsing is successful
594    pub fn new_parsed(data: &'a [u8], escape_buffer: &'a mut [u8]) -> Result<(usize,Self),JsonParseFailure> {
595        let mut ret = Self::new();
596        let data_end = ret.parse(data, escape_buffer)?;
597        Ok((data_end,ret))
598    }
599
600    /// similar to JsonObject::push but supports const contexts & only returns a reference
601    pub const fn push_const(&mut self, key: &'a str, value: JsonValue<'a>) -> Result<(),()> {
602        if self.num_fields == N {
603            return Err(());
604        }
605        self.fields[self.num_fields] = JsonField { key, value: value };
606        self.num_fields += 1;
607        Ok(())
608    }
609
610    /// similar to JsonObject::pop but supports const contexts
611    pub const fn pop_const(&mut self) -> Option<&JsonField<'a,'a>> {
612        match self.fields_const().split_last() {
613            None => return None,
614            Some((split,_remaining)) => return Some(split),
615        }
616    }
617
618    /// same as JsonObject::fields but supports const contexts
619    pub const fn fields_const(&self) -> &[JsonField<'a,'a>] {
620        self.fields.split_at(self.num_fields).0
621    }
622
623    /// same as JsonObject::fields_mut but supports const contexts
624    pub const fn fields_mut_const(&mut self) -> &mut [JsonField<'a,'a>] {
625        self.fields.split_at_mut(self.num_fields).0
626    }
627
628}
629
630#[cfg(feature = "alloc")]
631extern crate alloc as alloclib;
632#[cfg(feature = "alloc")]
633use alloclib::{string::String, vec::Vec};
634
635/// a buffer that any sized type can be written to. `ParseBuffer::Infinite` is only available with the `alloc` feature enabled.
636pub enum ParseBuffer<'a,T> {
637    /// a finite buffer of T
638    Finite(usize, &'a mut [T]),
639    /// an infinite buffer of T
640    #[cfg(feature = "alloc")]
641    Infinite(usize,&'a mut Vec<T>)
642}
643
644impl<'a,T> ParseBuffer<'a,T> {
645
646    fn write_thing(&mut self, thing: T) -> Result<(),JsonParseFailure> {
647        match self {
648            ParseBuffer::Finite(position, slice) => {
649                if *position == (*slice).len() {
650                    Err(JsonParseFailure::FieldBufferTooSmall)
651                } else {
652                    slice[*position] = thing;
653                    *position += 1;
654                    Ok(())
655                }
656            },
657            #[cfg(feature = "alloc")]
658            ParseBuffer::Infinite(position,vec) => {
659                if *position < vec.len() {
660                    vec[*position] = thing;
661                    *position += 1;
662                    Ok(())
663                } else {
664                    vec.push(thing);
665                    *position += 1;
666                    Ok(())
667                }
668            }
669        }
670    }
671
672    const fn consume(self) -> usize {
673        match self {
674            ParseBuffer::Finite(n, _) => n,
675            #[cfg(feature = "alloc")]
676            ParseBuffer::Infinite(n, _) => n,
677        }
678    }
679}
680
681// pub enum StringOutput<T> {
682//     Write(usize,T),
683
684//     String(String),
685// }
686
687/// a buffer that string slices can be written to
688pub enum StringBuffer<'a> {
689    Finite(usize, &'a mut [u8]),
690    #[cfg(feature = "alloc")]
691    Infinite(String,&'a InfiniteEscapeBuffer),
692}
693
694impl<'a> StringBuffer<'a> {
695    fn write_part(&mut self, string: &str) -> Result<(),JsonParseFailure> {
696        if string.len() == 0 {
697            return Ok(())
698        }
699        match self {
700            StringBuffer::Finite(position, slice) => {
701                let needed = string.len();
702                let have = slice.len() - *position;
703                if needed > have {
704                    return Err(JsonParseFailure::EscapeBufferTooSmall);
705                }
706                let target = slice.split_at_mut(*position).1.split_at_mut(needed).0;
707                target.copy_from_slice(string.as_bytes());
708                *position += needed;
709                Ok(())
710            },
711            #[cfg(feature = "alloc")]
712            StringBuffer::Infinite(current_string, _frozen_vec) => {
713                current_string.push_str(string);
714                Ok(())
715            },
716        }
717    }
718    fn consume_string(&mut self) -> &'a str {
719        match self {
720            StringBuffer::Finite(position, slice) => {
721                let (ret, remaining) = core::mem::take(slice).split_at_mut(*position);
722                *slice = remaining;
723                *position = 0;
724                // safety: this data was written from &str
725                unsafe { core::str::from_utf8_unchecked(ret) }
726            },
727            #[cfg(feature = "alloc")]
728            StringBuffer::Infinite(current_string, frozen_vec) => {
729                let completed_string = core::mem::replace(current_string, String::new());
730                let x = frozen_vec.push_get(completed_string);
731                x
732            },
733        }
734    }
735}
736
737
738
739/// the core function that powers parsing in the JsonObject API. It attempts to parse the fields of a json object from the provided data slice into the provided parse buffer.
740/// returns (num bytes consumed,num fields parsed) on success
741pub fn parse_json_object<'input_data: 'escaped_data,'escaped_data>(
742    data: &'input_data [u8],
743    mut field_buffer: ParseBuffer<'_,JsonField<'escaped_data,'escaped_data>>,
744    string_escape_buffer: &mut StringBuffer<'escaped_data>,
745) -> Result<(usize,usize),JsonParseFailure> {
746    let mut current_data_index = 0;
747    // let mut current_field_index = 0;
748    let mut map_entry_needs_comma = false;
749    skip_whitespace(&mut current_data_index, data)?;
750    if data[current_data_index] != b'{' {
751        return Err(JsonParseFailure::InvalidStructure);
752    }
753    let _map_start_index = current_data_index;
754    current_data_index += 1;
755    while current_data_index < data.len()  {
756        skip_whitespace(&mut current_data_index, data)?;
757        if data[current_data_index] == b'}' {
758            return Ok((current_data_index+1,field_buffer.consume()))
759        } else if map_entry_needs_comma  {
760            if data[current_data_index] != b',' {
761                return Err(JsonParseFailure::InvalidStructure);
762            }
763            current_data_index += 1;
764            map_entry_needs_comma = false;
765        } else {
766            map_entry_needs_comma = true;
767            // let key_start_quote_index = current_data_index;
768            // current_data_index += 1; // include the quote for json string
769
770            let string_key = unescape_json_string(&mut current_data_index, data, string_escape_buffer)?;
771
772            // skip_json_string(&mut current_data_index, data)?;
773            // let key_end_quote_index = current_data_index;
774            // let string_key = core::str::from_utf8(&data[key_start_quote_index+1..key_end_quote_index]).expect("skipped json object key string");
775            // current_data_index += 1;
776            skip_whitespace(&mut current_data_index, data)?;
777            if data[current_data_index] != b':' {
778                return Err(JsonParseFailure::InvalidStructure);
779            }
780            current_data_index += 1;
781            skip_whitespace(&mut current_data_index, data)?;
782
783            if data[current_data_index] == b'"' {
784                let unescaped_string_value = unescape_json_string(&mut current_data_index, data, string_escape_buffer)?;
785                field_buffer.write_thing(JsonField::new(string_key, JsonValue::String(unescaped_string_value)))?;
786            } else if data[current_data_index] == b'n' {
787                skip_literal(&mut current_data_index, data, "null", JsonParseFailure::InvalidBooleanField)?;
788                field_buffer.write_thing(JsonField::new(string_key, JsonValue::Null))?;
789            } else if data[current_data_index] == b't' || data[current_data_index] == b'f' {
790                let expect_true = data[current_data_index] == b't';
791                skip_literal(&mut current_data_index, data, if expect_true { "true" } else { "false"}, JsonParseFailure::InvalidBooleanField)?;
792                field_buffer.write_thing(JsonField::new(string_key, JsonValue::Boolean(expect_true)))?;
793            } else if data[current_data_index] == b'-' {
794                // negative number
795                let minus_sign_numeric_start_index = current_data_index;
796                current_data_index += 1;
797                skip_numeric(&mut current_data_index, data)?;
798                let minus_sign_numeric_end = current_data_index;
799                if minus_sign_numeric_end - minus_sign_numeric_start_index == 1 {
800                    // no digits found
801                    return Err(JsonParseFailure::InvalidNumericField);
802                }
803                let numeric_string = core::str::from_utf8(&data[minus_sign_numeric_start_index..minus_sign_numeric_end]).expect("skipped negative number digit(s)");
804                let numeric_value: i64 = match numeric_string.parse() {
805                    Ok(i) => i,
806                    Err(_parse_int_error) => return Err(JsonParseFailure::NumberParseError),
807                };
808                field_buffer.write_thing(JsonField::new(string_key, JsonValue::Number(numeric_value)))?;
809            } else if data[current_data_index] >= b'0' && data[current_data_index] < b'9' {
810                // positive number
811                let numeric_start_index = current_data_index;
812                current_data_index += 1;
813                skip_numeric(&mut current_data_index, data)?;
814                let numeric_after_index = current_data_index;
815                let numeric_string = core::str::from_utf8(&data[numeric_start_index..numeric_after_index]).expect("skipped positive number digit(s)");
816                let numeric_value: i64 = match numeric_string.parse() {
817                    Ok(i) => i,
818                    Err(_parse_int_error) => return Err(JsonParseFailure::NumberParseError),
819                };
820                field_buffer.write_thing(JsonField::new(string_key, JsonValue::Number(numeric_value)))?;
821            } else {
822                return Err(JsonParseFailure::InvalidStructure);
823            }
824        }
825    }
826    Err(JsonParseFailure::Incomplete)
827}
828
829const fn escape_char(c: char) -> Option<&'static str> {
830    Some(match c {
831        '"' => r#"\""#, // quotation mark
832        '\\' => r#"\\"#, // reverse solidus
833        '/' => r#"\/"#, // solidus
834        '\u{0008}' =>  r#"\b"#, // backspace
835        '\u{000C}' =>  r#"\f"#, // form feed
836        '\n' =>  r#"\n"#, // line feed
837        '\r' => r#"\r"#, // carriage return
838        '\t' => r#"\t"#, // character tabulation
839        _ => return None,
840    })
841}
842
843const fn unescape_char(c: char) -> Option<char> {
844    Some(match c {
845        '"' => '"',
846        '\\' => '\\',
847        '/' => '/',
848        'b' => '\u{0008}',
849        'f' => '\u{000C}',
850        'n' => '\n',
851        'r' => '\r',
852        't' => '\t',
853        _ => return None,
854    })
855}
856
857fn unescape_json_string<'data,'escaped>(index: &mut usize, data: &[u8], escaped: &mut StringBuffer<'escaped>) -> Result<&'escaped str,JsonParseFailure> {
858    if data[*index] != b'\"' {
859        return Err(JsonParseFailure::InvalidStringField);
860    }
861    *index += 1;
862    let mut current_char_escaped = false;
863    let mut encoding_buffer = [0_u8; 4];
864    while *index < data.len() {
865        let current_char = data[*index];
866        if !current_char.is_ascii() {
867            return Err(JsonParseFailure::InvalidStringField);
868        } else if current_char_escaped {
869            if let Some(unescaped_char) = unescape_char(current_char as char) {
870                let encoded = unescaped_char.encode_utf8(&mut encoding_buffer);
871                escaped.write_part(&encoded)?;
872                *index += 1;
873                current_char_escaped = false;
874            } else {
875                return Err(JsonParseFailure::InvalidStringField);
876            }
877        } else if current_char == '\\' as u8 {
878            current_char_escaped = true;
879            *index += 1;
880        } else if current_char == '"' as u8 {
881            *index += 1;
882            return Ok(escaped.consume_string());
883        } else {
884            let encoded = (current_char as char).encode_utf8(&mut encoding_buffer);
885            escaped.write_part(&encoded)?;
886            *index += 1;
887        }
888        // else if '\\' as u8 == current_char {
889        //     if current_char_escaped {
890        //         escaped.write_part("\\")?;
891        //         current_char_escaped = false;
892        //     } else {
893        //         current_char_escaped = true;
894        //     }
895        // } else if '"' as u8 == current_char {
896        //     if current_char_escaped {
897        //         escaped.write_part(r#"""#)?;
898        //         current_char_escaped = false;
899        //     } else {
900        //         *index += 1;
901        //         return Ok(escaped.consume_string());
902        //     }
903        // } else if let Some(escape_sequence) = escape_char(current_char as char) {
904        //     if !current_char_escaped {
905        //         return Err(JsonParseFailure::InvalidStringField);
906        //     }
907        //     let mut char_buffer = [0_u8; 4];
908        //     let char_as_str = (current_char as char).encode_utf8(&mut char_buffer);
909        //     escaped.write_part(char_as_str)?;
910        //     *index += char_as_str.len();
911        //     current_char_escaped = false;
912        // } else {
913        //     let mut char_buffer = [0_u8; 4];
914        //     let char_as_str = (current_char as char).encode_utf8(&mut char_buffer);
915        //     escaped.write_part(char_as_str)?;
916        //     *index += char_as_str.len();
917        //     current_char_escaped = false;
918        // }
919    }
920    Err(JsonParseFailure::Incomplete)
921}
922
923const fn skip_numeric(index: &mut usize, data: &[u8]) -> Result<(),JsonParseFailure> {
924    while *index < data.len() && data[*index] <= b'9' && data[*index] >= b'0' {
925        *index += 1;
926    }
927    if *index == data.len() {
928        Err(JsonParseFailure::Incomplete)
929    } else if data[*index].is_ascii_whitespace() || data[*index] == b',' || data[*index] == b'}' {
930        Ok(())
931    } else {
932        Err(JsonParseFailure::InvalidNumericField)
933    }
934}
935
936fn skip_literal(index: &mut usize, data: &[u8], target: &str, field_error_type: JsonParseFailure) -> Result<(),JsonParseFailure> {
937    let start = *index;
938    while (*index - start) < target.len() {
939        if *index >= data.len() {
940            return Err(JsonParseFailure::Incomplete)
941        }
942        if data[*index] != target.as_bytes()[*index-start] {
943            return Err(field_error_type);
944        }
945        *index += 1;
946    }
947    Ok(())
948}
949
950fn skip_whitespace(index: &mut usize, data: &[u8]) -> Result<(),JsonParseFailure> {
951    while *index < data.len() && data[*index].is_ascii_whitespace() {
952        *index += 1;
953    }
954    if *index == data.len() {
955        Err(JsonParseFailure::Incomplete)
956    } else {
957        Ok(())
958    }
959}
960
961/// the core function that powers serialization in the JsonArray API. It attempts to serialize the provided values as a JSON array into the provided output & returns the number of bytes written on success.
962pub fn serialize_json_array<'data, Output: StringWrite>(
963    output: &mut Output,
964    fields: &[JsonValue<'data>],
965    resume_from: usize,
966) -> Result<usize, (usize,Output::StringWriteFailure)> {
967    let mut ret = 0;
968    tracked_write(output,&mut ret , &resume_from, LEFT_SQUARE_BRACKET)?;
969    let mut value_needs_comma = false;
970    for value in fields.as_ref().iter() {
971        if value_needs_comma {
972            tracked_write(output,&mut ret , &resume_from, ",")?;
973        } else {
974            value_needs_comma = true;
975        }
976        match *value {
977            JsonValue::Boolean(b) => if b {
978                tracked_write(output,&mut ret , &resume_from, "true")?;
979            } else {
980                tracked_write(output,&mut ret , &resume_from, "false")?;
981            },
982            JsonValue::Null => {
983                tracked_write(output,&mut ret , &resume_from, "null")?;
984            },
985            JsonValue::Number(n) => {
986                tracked_write(output,&mut ret , &resume_from, base10::i64(n).as_str())?;
987            },
988            JsonValue::String(s) => {
989                write_escaped_json_string(output, &mut ret , &resume_from, s)?;
990            },
991        }
992    }
993    tracked_write(output, &mut ret , &resume_from, RIGHT_SQUARE_BRACKET)?;
994    Ok(ret.saturating_sub(resume_from))
995}
996
997// const LEFT_SQUARE_BRACKET_CHAR: char = '{';
998const LEFT_SQUARE_BRACKET: &str = "[";
999const LEFT_CURLY_BRACKET: &str = "{";
1000const RIGHT_SQUARE_BRACKET: &str = "]";
1001const RIGHT_CURLY_BRACKET: &str = "}";
1002const COLON: &str = ":";
1003const COMMA: &str = ",";
1004
1005/// the core function that powers serialization in the JsonObject API. It attempts to serialize the provided fields as a JSON object into the provided output, & returns the number of bytes written on success.
1006fn serialize_json_object<'data, Output: StringWrite>(
1007    output: &mut Output,
1008    fields: &[JsonField<'data,'data>],
1009    resume_from: usize,
1010) -> Result<usize, (usize,Output::StringWriteFailure)> {
1011    let mut ret = 0;
1012    tracked_write(output,&mut ret , &resume_from, LEFT_CURLY_BRACKET)?;
1013    let mut field_needs_comma = false;
1014    for field in fields.as_ref().iter() {
1015        if field_needs_comma {
1016            tracked_write(output,&mut ret , &resume_from, COMMA)?;
1017        } else {
1018            field_needs_comma = true;
1019        }
1020        write_escaped_json_string(output, &mut ret , &resume_from, field.key)?;
1021        tracked_write(output, &mut ret, &resume_from, COLON)?;
1022        match field.value {
1023            JsonValue::Boolean(b) => if b {
1024                tracked_write(output,&mut ret , &resume_from, "true")?;
1025            } else {
1026                tracked_write(output,&mut ret , &resume_from, "false")?;
1027            },
1028            JsonValue::Null => {
1029                tracked_write(output,&mut ret , &resume_from, "null")?;
1030            },
1031            JsonValue::Number(n) => {
1032                tracked_write(output,&mut ret , &resume_from, base10::i64(n).as_str())?;
1033            },
1034            JsonValue::String(s) => {
1035                write_escaped_json_string(output, &mut ret , &resume_from, s)?;
1036            },
1037        }
1038    }
1039    tracked_write(output, &mut ret, &resume_from, RIGHT_CURLY_BRACKET)?;
1040    Ok(ret.saturating_sub(resume_from))
1041}
1042
1043fn tracked_write<T: StringWrite>(output: &mut T, counter: &mut usize, resume_from: &usize, the_string: &str) -> Result<(), (usize,T::StringWriteFailure)> {
1044    let mut encoding_buffer = [0_u8; 4];
1045    for char in the_string.chars() {
1046        let encoded_char = char.encode_utf8(encoding_buffer.as_mut_slice());
1047        let to_skip = if resume_from <= counter {
1048            0
1049        } else {
1050            let to_skip = *resume_from - *counter;
1051            if to_skip >= encoded_char.len() {
1052                *counter += encoded_char.len();
1053                continue;
1054            } else {
1055                to_skip
1056            }
1057        };
1058        match output.write_char(char, to_skip) {
1059            Ok(n_success) => *counter += n_success,
1060            Err((n_failed, e)) => {
1061                *counter += n_failed;
1062                return Err((counter.saturating_sub(*resume_from), e));
1063            },
1064        };
1065    }
1066    Ok(())
1067    // let to_skip = if resume_from <= counter {
1068    //     0
1069    // } else {
1070    //     let to_skip = *resume_from - *counter;
1071    //     if to_skip >= data.len() {
1072    //         *counter += data.len();
1073    //         return Ok(());
1074    //     } else {
1075    //         to_skip
1076    //     }
1077    // };
1078    // let target = data.split_at(to_skip).1;
1079    // match output.write_string(target) {
1080    //     Ok(n) => {
1081    //         *counter += n;
1082    //         Ok(())
1083    //     },
1084    //     Err((partial, e)) => {
1085    //         *counter += partial;
1086    //         Err((counter.saturating_sub(*resume_from),e))
1087    //     },
1088    // }
1089}
1090
1091fn write_escaped_json_string<T: StringWrite>(output: &mut T, counter: &mut usize, resume_from: &usize, data: &str) -> Result<(), (usize,T::StringWriteFailure)> {
1092    tracked_write(output, counter, resume_from, "\"")?;
1093    for field_character in data.chars() {
1094        if !field_character.is_ascii() {
1095            continue;
1096        } else if let Some(escape_sequence) = escape_char(field_character) {
1097            tracked_write(output, counter, resume_from, escape_sequence)?;
1098        } else {
1099            tracked_write(output, counter, resume_from, field_character.encode_utf8(&mut [0_u8; 4]))?;
1100        }
1101    }
1102    tracked_write(output, counter, resume_from, "\"")?;
1103    Ok(())
1104}
1105
1106#[cfg(feature = "alloc")]
1107mod alloc {
1108
1109    extern crate alloc as alloclib;
1110    
1111
1112    use alloclib::string::String;
1113    use alloclib::vec::Vec;
1114
1115    pub use elsa::FrozenVec;
1116
1117    use crate::{parse_json_object, FieldBufferMut, JsonField, JsonObject, JsonParseFailure, ParseBuffer, StringBuffer};
1118
1119    impl <'a,T: FieldBufferMut<'a>> JsonObject<T> {
1120
1121    }
1122
1123    // impl <'a,const N: usize> ArrayJsonObject<'a,N> {
1124    //     /// attempt to parse a JSON object from the provided data slice and write its fields into this JsonObject while allocating space as needed for storing escaped strings
1125    //     /// returns num bytes consumed on success
1126    //     pub fn parse_alloc_escape(&mut self, data: &'a [u8], escape_buffer: &'a FrozenVec<String>) -> Result<usize,JsonParseFailure> {
1127    //         let (data_end, parsed_fields) = parse_json_object(
1128    //             data,
1129    //             ParseBuffer::Finite(0,self.fields.as_mut()),
1130    //             &mut crate::StringBuffer::Infinite(String::new(), escape_buffer)
1131    //         )?;
1132    //         let new_num_fields = parsed_fields;
1133    //         self.num_fields = new_num_fields;
1134    //         Ok(data_end)
1135    //     }
1136    // }
1137
1138    impl <'a, T: AsMut<Vec<JsonField<'a,'a>>>> JsonObject<T> {
1139
1140        /// attempt to parse a JSON object from the provided data slice and write its fields into this JsonObject while allocating space as needed for storing parsed fields
1141        /// returns num bytes consumed on success
1142        pub fn parse_alloc_fields(&mut self, data: &'a [u8], escape_buffer: &'a mut [u8]) -> Result<usize,JsonParseFailure> {
1143            let (data_end, parsed_fields) = parse_json_object(
1144                data,
1145                ParseBuffer::Infinite(0, self.fields.as_mut()),
1146                &mut StringBuffer::Finite(0, escape_buffer),
1147            )?;
1148            let new_num_fields = parsed_fields;
1149            self.num_fields = new_num_fields;
1150            Ok(data_end)
1151        }
1152
1153        /// attempt to parse a JSON object from the provided data slice and write its fields into this JsonObject while allocating space as needed for storing parsed fields & escaped strings
1154        /// returns num bytes consumed on success
1155        pub fn parse_alloc(&mut self, data: &'a [u8], escape_buffer: &'a FrozenVec<String>) -> Result<usize,JsonParseFailure> {
1156            let (data_end, parsed_fields) = parse_json_object(
1157                data,
1158                ParseBuffer::Infinite(0, self.fields.as_mut()),
1159                &mut crate::StringBuffer::Infinite(String::new(), escape_buffer),
1160            )?;
1161            let new_num_fields = parsed_fields;
1162            self.num_fields = new_num_fields;
1163            Ok(data_end)
1164        }
1165    }
1166
1167}
1168
1169
1170#[cfg(feature = "std")]
1171mod stdlib {
1172    extern crate std;
1173    use embedded_io_adapters::std::FromStd;
1174    use crate::FieldBuffer;
1175    use crate::JsonObject;
1176
1177    impl <'a,T: FieldBuffer<'a>> JsonObject<T> {
1178        /// convenience method to serialize to types implementing std::io::Write by wrapping it with embedded_io_adapters::std::FromStd
1179        pub fn serialize_std<Output: std::io::Write>(&self, output: Output) -> Result<usize,std::io::Error> {
1180            self.serialize(FromStd::new(output))
1181        }
1182    }
1183}
1184
1185#[cfg(all(test,feature = "alloc"))]
1186mod test_alloc {
1187    use super::*;
1188
1189    extern crate alloc;
1190    use alloc::vec::Vec;
1191    use alloclib::string::ToString;
1192
1193    #[test]
1194    fn test_parse_core_vec_no_alloc_too_many_fields() {
1195        match parse_json_object(
1196            br#"{"a":0}"#,
1197            ParseBuffer::Finite(0,&mut Vec::new()),
1198            &mut StringBuffer::Finite(0, &mut [0_u8; 256]),
1199        ) {
1200            Err(JsonParseFailure::FieldBufferTooSmall) => {},
1201            other => panic!("{:?}", other),
1202        }
1203    }
1204
1205    #[test]
1206    fn test_parse_core_vec_with_alloc_simple() {
1207        let mut fields = Vec::new();
1208        match parse_json_object(
1209            br#"{"a":0}"#,
1210            ParseBuffer::Infinite(0,&mut fields),
1211            &mut StringBuffer::Finite(0, &mut [0_u8; 256])
1212        ) {
1213            Ok((num_bytes, num_fields)) => {
1214                assert_eq!(7, num_bytes);
1215                assert_eq!(1, num_fields);
1216                assert_eq!(1, fields.len());
1217                assert_eq!(JsonField::new("a", JsonValue::Number(0)), fields[0])
1218            },
1219            other => panic!("{:?}", other),
1220        }
1221
1222    }
1223
1224    #[test]
1225    fn test_parse_core_vec_success_empty() {
1226        let (bytes_consumed,num_fields_parsed) = parse_json_object(
1227            b"{}",
1228            ParseBuffer::Infinite(0,&mut Vec::new()),
1229            &mut StringBuffer::Finite(0, &mut [0_u8; 256])
1230        ).unwrap();
1231        assert_eq!(2,bytes_consumed);
1232        assert_eq!(0,num_fields_parsed);
1233    }
1234
1235    #[test]
1236    fn test_parse_object_vec_success_empty() {
1237        let mut escape_buffer = [0_u8; 256];
1238        let mut parser = JsonObject::wrap(Vec::new());
1239        let bytes_consumed =  parser.parse(b"{}", &mut escape_buffer).unwrap();
1240        assert_eq!(0,parser.fields().len());
1241        assert_eq!(bytes_consumed, 2);
1242    }
1243
1244    #[test]
1245    fn test_serialize_empty_to_string() {
1246        let string: String = ArrayJsonObject::<0>::new().to_string();
1247        assert_eq!("{}", string);
1248    }
1249
1250
1251}
1252
1253#[cfg(test)]
1254mod test_core {
1255
1256    use embedded_io::SliceWriteError;
1257
1258    use super::*;
1259
1260    #[test]
1261    fn test_parse_value_string() {
1262        let data = br#""this is a string""#;
1263        match JsonValue::parse(data, &mut [0_u8; 16]) {
1264            Ok((value_end,value)) => {
1265                assert_eq!(data.len(),value_end);
1266                match value {
1267                    JsonValue::String(s) => {
1268                        assert_eq!("this is a string", s);
1269                    },
1270                    other => panic!("{:?}", other),
1271                }
1272            },
1273            other => panic!("{:?}", other),
1274        }
1275    }
1276
1277    #[test]
1278    fn test_parse_value_integer() {
1279        let data = br#"12345 "#;
1280        match JsonValue::parse(data, &mut [0_u8; 16]) {
1281            Ok((value_end,value)) => {
1282                assert_eq!(data.len(),value_end+1); // need non-numeric to recognize end
1283                match value {
1284                    JsonValue::Number(n) => {
1285                        assert_eq!(12345, n);
1286                    },
1287                    other => panic!("{:?}", other),
1288                }
1289            },
1290            other => panic!("{:?}", other),
1291        }
1292    }
1293
1294    #[test]
1295    fn test_parse_value_null() {
1296        let data = br#"null"#;
1297        match JsonValue::parse(data, &mut [0_u8; 16]) {
1298            Ok((value_end,value)) => {
1299                assert_eq!(data.len(),value_end);
1300                match value {
1301                    JsonValue::Null => {},
1302                    other => panic!("{:?}", other),
1303                }
1304            },
1305            other => panic!("{:?}", other),
1306        }
1307    }
1308
1309    #[test]
1310    fn test_parse_object_empty_core() {
1311        let mut escape_buffer = [0_u8; 256];
1312        let (bytes_consumed,num_fields) = parse_json_object(
1313            b"{}",
1314            ParseBuffer::Finite(0,&mut []),
1315            &mut StringBuffer::Finite(0, &mut escape_buffer),
1316        ).unwrap();
1317        assert_eq!(bytes_consumed, 2);
1318        assert_eq!(num_fields, 0);
1319    }
1320
1321    #[test]
1322    fn test_parse_object_empty_trait_array() {
1323        let mut parser = JsonObject::wrap([]);
1324        let bytes_consumed = parser.parse(b"{}", &mut []).unwrap();
1325        assert_eq!(bytes_consumed, 2);
1326        assert_eq!(parser.len(), 0);
1327    }
1328
1329    #[test]
1330    fn test_parse_object_empty_trait_slice() {
1331        let mut parser = JsonObject::wrap(&mut []);
1332        let bytes_consumed = parser.parse(b"{}", &mut []).unwrap();
1333        assert_eq!(bytes_consumed, 2);
1334        assert_eq!(parser.len(), 0);
1335    }
1336
1337    #[test]
1338    fn test_parse_object_empty_arrayhelper() {
1339        let mut parser = ArrayJsonObject::<0>::new();
1340        let bytes_consumed = parser.parse(b"{}", &mut []).unwrap();
1341        assert_eq!(bytes_consumed, 2);
1342        assert_eq!(parser.len(), 0);
1343    }
1344
1345    #[test]
1346    fn test_parse_object_simple() {
1347        let data = br#"{"sub":"1234567890","name":"John Doe","iat":1516239022,"something":false,"null_thing":null}"#;
1348        let mut escape_buffer = [0_u8; 256];
1349        let (data_end,json_object) = ArrayJsonObject::<50>::new_parsed(data, &mut escape_buffer).unwrap();
1350        assert_eq!(data_end, data.len());
1351        let test_fields = json_object.fields();
1352        assert_eq!(5, test_fields.len());
1353        assert_eq!(JsonField { key: "sub", value: JsonValue::String("1234567890")}, test_fields[0]);
1354        assert_eq!(JsonField { key: "name", value: JsonValue::String("John Doe")}, test_fields[1]);
1355        assert_eq!(JsonField { key: "iat", value: JsonValue::Number(1516239022)}, test_fields[2]);
1356        assert_eq!(JsonField { key: "something", value: JsonValue::Boolean(false)}, test_fields[3]);
1357        assert_eq!(JsonField { key: "null_thing", value: JsonValue::Null}, test_fields[4]);
1358    }
1359
1360    #[test]
1361    fn test_parse_object_empty_strings() {
1362        let data = br#"{"":""}"#;
1363        let mut escape_buffer = [0_u8; 256];
1364        let (data_end,json_object) = ArrayJsonObject::<50>::new_parsed(data, &mut escape_buffer).unwrap();
1365        assert_eq!(data_end, data.len());
1366        let test_fields = json_object.fields();
1367        assert_eq!(1, test_fields.len());
1368        assert_eq!(JsonField { key: "", value: JsonValue::String("")}, test_fields[0]);
1369    }
1370
1371        #[test]
1372    fn test_parse_object_backspace_strings() {
1373        let data = br#"{"\b":""}"#;
1374        let mut escape_buffer = [0_u8; 256];
1375        let (data_end,json_object) = ArrayJsonObject::<50>::new_parsed(data, &mut escape_buffer).unwrap();
1376        assert_eq!(data_end, data.len());
1377        let test_fields = json_object.fields();
1378        assert_eq!(1, test_fields.len());
1379        assert_eq!(JsonField { key: "\u{0008}", value: JsonValue::String("")}, test_fields[0]);
1380    }
1381
1382    #[test]
1383    fn test_parse_object_ignore_trailing_whitespace() {
1384        let data = br#"{}    "#; // add 4 spaces to the end
1385        let (data_end,_) = ArrayJsonObject::<0>::new_parsed(data,&mut []).unwrap();
1386        assert_eq!(data_end, data.len() - 4);
1387    }
1388
1389    #[test]
1390    fn test_parse_object_failure_too_many_fields() {
1391        let mut escape_buffer = [0_u8; 256];
1392        match ArrayJsonObject::<0>::new_parsed(br#"{"some":"thing"}"#,&mut escape_buffer) {
1393            Err(JsonParseFailure::FieldBufferTooSmall) => {},
1394            other => panic!("{:?}", other)
1395        }
1396    }
1397
1398    // #[test]
1399    // fn test_parse_object_failure_invalid_number_minus() {
1400    //     match ArrayJsonObject::<1>::new_parsed(br#"{"": -}"#,&mut []) {
1401    //         Err(JsonParseFailure::InvalidNumericField) => {},
1402    //         other => panic!("{:?}", other)
1403    //     }
1404    // }
1405
1406    #[test]
1407    fn test_parse_object_failure_incomplete_a() {
1408        match ArrayJsonObject::<0>::new_parsed(b"{",&mut []) {
1409            Err(JsonParseFailure::Incomplete) => {},
1410            other => panic!("{:?}", other)
1411        }
1412    }
1413
1414    #[test]
1415    fn test_parse_object_failure_incomplete_b() {
1416        let mut escape_buffer = [0_u8; 256];
1417        match ArrayJsonObject::<50>::new_parsed(
1418            br#"{"sub":"1234567890","name":"John Doe","iat":1516239022,"something":false"#,
1419            &mut escape_buffer,
1420        ) {
1421            Err(JsonParseFailure::Incomplete) => {},
1422            other => panic!("{:?}", other)
1423        }
1424    }
1425
1426    #[test]
1427    fn test_serialize_array_empty() {
1428        let mut buffer = [0_u8; 2];
1429        let test_array = ArrayJsonArray::<0>::new();
1430        let n = test_array.serialize(buffer.as_mut_slice()).unwrap();
1431        assert_eq!(b"[]", buffer.split_at(n).0)
1432    }
1433
1434    #[test]
1435    fn test_serialize_resume_array_empty() {
1436        let mut buffer = [0_u8; 2];
1437        let test_array = ArrayJsonArray::<0>::new();
1438        let n = test_array.serialize_resume(buffer.as_mut_slice(),1).unwrap();
1439        assert_eq!(b"]", buffer.split_at(n).0)
1440    }
1441
1442    #[test]
1443    fn test_display_array_empty() {
1444        let mut buffer = [0_u8; 2];
1445        buffer.as_mut_slice().write_fmt(format_args!("{}", ArrayJsonArray::<0>::new())).unwrap();
1446        assert_eq!(b"[]", buffer.as_slice())
1447    }
1448
1449    #[test]
1450    fn test_serialize_object_empty() {
1451        let mut buffer = [0_u8; 2];
1452        let test_object = ArrayJsonObject::<0>::new();
1453        let n = test_object.serialize(buffer.as_mut_slice()).unwrap();
1454        assert_eq!(b"{}", buffer.split_at(n).0)
1455    }
1456
1457    #[test]
1458    fn test_serialize_resume_object_empty() {
1459        let mut buffer = [0_u8; 2];
1460        let test_object = ArrayJsonObject::<0>::new();
1461        let n = test_object.serialize_resume(buffer.as_mut_slice(), 1).unwrap();
1462        assert_eq!(b"}", buffer.split_at(n).0)
1463    }
1464
1465    #[test]
1466    fn test_serialize_resume_skip_object_empty() {
1467        let mut buffer = [0_u8; 2];
1468        let test_object = ArrayJsonObject::<0>::new();
1469        let n = test_object.serialize_resume(buffer.as_mut_slice(), 2).unwrap();
1470        assert_eq!(b"", buffer.split_at(n).0)
1471    }
1472
1473    #[test]
1474    fn test_serialize_resume_too_many_object_empty() {
1475        let mut buffer = [0_u8; 2];
1476        let test_object = ArrayJsonObject::<0>::new();
1477        let n = test_object.serialize_resume(buffer.as_mut_slice(), 3).unwrap();
1478        assert_eq!(b"", buffer.split_at(n).0)
1479    }
1480
1481    #[test]
1482    fn test_display_object_empty() {
1483        let mut buffer = [0_u8; 2];
1484        buffer.as_mut_slice().write_fmt(format_args!("{}", ArrayJsonObject::<0>::new())).unwrap();
1485        assert_eq!(b"{}", buffer.as_slice())
1486    }
1487
1488    #[test]
1489    fn test_serialize_object_simple() {
1490        let mut buffer = [0_u8; 1000];
1491        let mut test_map = ArrayJsonObject::<50>::new();
1492        test_map.push_field("sub", JsonValue::String("1234567890")).unwrap();
1493        test_map.push_field("name", JsonValue::String("John Doe")).unwrap();
1494        test_map.push_field("iat", JsonValue::Number(1516239022)).unwrap();
1495        test_map.push_field("something", JsonValue::Boolean(false)).unwrap();
1496        test_map.push_field("null_thing", JsonValue::Null).unwrap();
1497        let n = test_map.serialize(buffer.as_mut_slice()).unwrap();
1498        assert_eq!(br#"{"sub":"1234567890","name":"John Doe","iat":1516239022,"something":false,"null_thing":null}"#, buffer.split_at(n).0)
1499    }
1500
1501    #[test]
1502    fn test_serialize_resume_object_simple() {
1503        const SKIP: usize = 10;
1504        const EXPECTED: &[u8] = br#"{"sub":"1234567890","name":"John Doe","iat":1516239022,"something":false,"null_thing":null}"#.split_at(SKIP).1;
1505
1506        let mut buffer = [0_u8; 1000];
1507        let mut test_map = ArrayJsonObject::<50>::new();
1508        test_map.push_field("sub", JsonValue::String("1234567890")).unwrap();
1509        test_map.push_field("name", JsonValue::String("John Doe")).unwrap();
1510        test_map.push_field("iat", JsonValue::Number(1516239022)).unwrap();
1511        test_map.push_field("something", JsonValue::Boolean(false)).unwrap();
1512        test_map.push_field("null_thing", JsonValue::Null).unwrap();
1513        let n = test_map.serialize_resume(buffer.as_mut_slice(), 10).unwrap();
1514        assert_eq!(EXPECTED, buffer.split_at(n).0)
1515    }
1516
1517    #[test]
1518    fn test_serialize_resume_object_single_byte() {
1519        const EXPECTED: &[u8] = br#"{"sub":"1234567890","name":"John Doe","iat":1516239022,"something":false,"null_thing":null}"#;
1520
1521        let mut buffer = [0_u8; 1];
1522        let mut test_map = ArrayJsonObject::<50>::new();
1523        test_map.push_field("sub", JsonValue::String("1234567890")).unwrap();
1524        test_map.push_field("name", JsonValue::String("John Doe")).unwrap();
1525        test_map.push_field("iat", JsonValue::Number(1516239022)).unwrap();
1526        test_map.push_field("something", JsonValue::Boolean(false)).unwrap();
1527        test_map.push_field("null_thing", JsonValue::Null).unwrap();
1528
1529        // attempt to resume from every each byte
1530        for (index,expected_byte) in EXPECTED.iter().enumerate() {
1531            match test_map.serialize_resume(buffer.as_mut_slice(), index) {
1532                Err((1,SliceWriteError::Full)) => {
1533                    assert_eq!(*expected_byte as char, buffer[0] as char)
1534                },
1535                Ok(0) => assert_eq!(EXPECTED.len(),index),
1536                Ok(1) => assert_eq!(EXPECTED.len()-1,index),
1537                unexpected => panic!("{:?}", unexpected),
1538            };
1539        }
1540    }
1541
1542}