Skip to main content

docspec_json/
emitter.rs

1//! Fluent JSON emitter with stack-based state validation.
2
3use crate::{backend::JsonBackend, state::StateStack, value::WriteVal};
4use docspec_core::{Error, Result};
5
6/// Fluent JSON emitter generic over a [`JsonBackend`].
7///
8/// Drives the backend through valid JSON shapes only — invalid sequences
9/// (e.g. `key` outside an object, two values for one key) return errors
10/// before reaching the backend.
11///
12/// Provides two complementary APIs sharing the same state machine:
13/// - **Closure form** — `object(f)`, `array(f)`, `value(v)` plus keyed via [`KeyedEmitter`].
14/// - **Streaming form** — `open_object()`, `close_object()`, `open_array()`, `close_array()`.
15pub struct JsonEmitter<B: JsonBackend> {
16    backend: B,
17    stack: StateStack,
18}
19
20impl<B: JsonBackend> JsonEmitter<B> {
21    /// Write an unkeyed array using a closure.
22    ///
23    /// Best-effort scope guard: if the closure returns `Err`, [`Self::close_array`]
24    /// is still attempted so that the backend sees a matching `end_array` and the
25    /// emitter state machine is left in a consistent shape. The closure's error
26    /// takes precedence over any error produced by the close.
27    ///
28    /// # Errors
29    ///
30    /// Returns `Err` if a value is not allowed here, or if the closure or backend errors.
31    #[inline]
32    pub fn array<F>(&mut self, f: F) -> Result<()>
33    where
34        F: FnOnce(&mut Self) -> Result<()>,
35    {
36        self.open_array()?;
37        let inner = f(self);
38        let close = self.close_array();
39        inner.and(close)
40    }
41
42    /// Close the current array frame. Errors if the current frame is not an array.
43    ///
44    /// # Errors
45    ///
46    /// Returns `Err` if the current frame is not an array, or if the backend errors.
47    #[inline]
48    pub fn close_array(&mut self) -> Result<()> {
49        self.stack.peek_array()?;
50        self.backend.end_array()?;
51        self.stack.pop_array()?;
52        self.stack.mark_value_written()
53    }
54
55    /// Close the current object frame. Errors if the current frame is not an object.
56    ///
57    /// # Errors
58    ///
59    /// Returns `Err` if the current frame is not an object, or if the backend errors.
60    #[inline]
61    pub fn close_object(&mut self) -> Result<()> {
62        self.stack.peek_object()?;
63        self.backend.end_object()?;
64        self.stack.pop_object()?;
65        self.stack.mark_value_written()
66    }
67
68    /// Finish emission and return the backend's output.
69    ///
70    /// # Errors
71    ///
72    /// Returns `Err` if emission is incomplete, or if the backend errors during finish.
73    #[inline]
74    pub fn finish(self) -> Result<B::Output> {
75        if !self.stack.is_finished() {
76            return Err(Error::Json {
77                message: "cannot finish: open containers remain or no root value written"
78                    .to_string(),
79                position: None,
80            });
81        }
82        self.backend.finish()
83    }
84
85    /// Begin a keyed slot. Returns a single-use [`KeyedEmitter`] that must be
86    /// consumed by `.object()`, `.array()`, `.value()`, `.open_object()`, or `.open_array()`.
87    #[inline]
88    pub fn key<'a>(&'a mut self, name: &'a str) -> KeyedEmitter<'a, B> {
89        KeyedEmitter {
90            emitter: self,
91            name,
92        }
93    }
94
95    /// Create a new emitter wrapping `backend`.
96    #[inline]
97    #[must_use]
98    pub fn new(backend: B) -> Self {
99        Self {
100            backend,
101            stack: StateStack::new(),
102        }
103    }
104
105    /// Write an unkeyed object using a closure.
106    ///
107    /// Best-effort scope guard: if the closure returns `Err`, [`Self::close_object`]
108    /// is still attempted so that the backend sees a matching `end_object` and the
109    /// emitter state machine is left in a consistent shape. The closure's error
110    /// takes precedence over any error produced by the close.
111    ///
112    /// # Errors
113    ///
114    /// Returns `Err` if a value is not allowed here, or if the closure or backend errors.
115    #[inline]
116    pub fn object<F>(&mut self, f: F) -> Result<()>
117    where
118        F: FnOnce(&mut Self) -> Result<()>,
119    {
120        self.open_object()?;
121        let inner = f(self);
122        let close = self.close_object();
123        inner.and(close)
124    }
125
126    /// Open an unkeyed array. Caller must later call [`JsonEmitter::close_array`].
127    ///
128    /// # Errors
129    ///
130    /// Returns `Err` if a value is not allowed here, or if the backend errors.
131    #[inline]
132    pub fn open_array(&mut self) -> Result<()> {
133        self.stack.expect_value_allowed()?;
134        self.backend.begin_array()?;
135        self.stack.push_array();
136        Ok(())
137    }
138
139    /// Open an unkeyed object. Caller must later call [`JsonEmitter::close_object`].
140    ///
141    /// # Errors
142    ///
143    /// Returns `Err` if a value is not allowed here, or if the backend errors.
144    #[inline]
145    pub fn open_object(&mut self) -> Result<()> {
146        self.stack.expect_value_allowed()?;
147        self.backend.begin_object()?;
148        self.stack.push_object();
149        Ok(())
150    }
151
152    /// Write an unkeyed scalar value.
153    ///
154    /// # Errors
155    ///
156    /// Returns `Err` if a value is not allowed here, or if the backend errors.
157    #[inline]
158    pub fn value<V: WriteVal>(&mut self, v: V) -> Result<()> {
159        self.stack.expect_value_allowed()?;
160        v.write_to(&mut self.backend)?;
161        self.stack.mark_value_written()
162    }
163
164    /// Write a key name and transition the object state machine.
165    fn write_key(&mut self, name: &str) -> Result<()> {
166        self.stack.expect_key_allowed()?;
167        self.backend.write_name(name)?;
168        self.stack.mark_key_written()
169    }
170}
171
172/// Single-use handle returned by [`JsonEmitter::key`].
173///
174/// Consumed by [`KeyedEmitter::object`], [`KeyedEmitter::array`],
175/// [`KeyedEmitter::value`], [`KeyedEmitter::open_object`], or
176/// [`KeyedEmitter::open_array`].
177#[must_use = "KeyedEmitter must be consumed by .object(), .array(), .value(), .open_object(), or .open_array()"]
178pub struct KeyedEmitter<'a, B: JsonBackend> {
179    emitter: &'a mut JsonEmitter<B>,
180    name: &'a str,
181}
182
183impl<B: JsonBackend> KeyedEmitter<'_, B> {
184    /// Consume the key and write an array value via closure.
185    ///
186    /// Best-effort scope guard: if the closure returns `Err`, the array close is
187    /// still attempted; the closure's error takes precedence.
188    ///
189    /// # Errors
190    ///
191    /// Returns `Err` if a key is not allowed here, or if the closure or backend errors.
192    #[inline]
193    pub fn array<F>(self, f: F) -> Result<()>
194    where
195        F: FnOnce(&mut JsonEmitter<B>) -> Result<()>,
196    {
197        let emitter = self.emitter;
198        emitter.write_key(self.name)?;
199        emitter.open_array()?;
200        let inner = f(emitter);
201        let close = emitter.close_array();
202        inner.and(close)
203    }
204
205    /// Consume the key and write an object value via closure.
206    ///
207    /// Best-effort scope guard: if the closure returns `Err`, the object close is
208    /// still attempted; the closure's error takes precedence.
209    ///
210    /// # Errors
211    ///
212    /// Returns `Err` if a key is not allowed here, or if the closure or backend errors.
213    #[inline]
214    pub fn object<F>(self, f: F) -> Result<()>
215    where
216        F: FnOnce(&mut JsonEmitter<B>) -> Result<()>,
217    {
218        let emitter = self.emitter;
219        emitter.write_key(self.name)?;
220        emitter.open_object()?;
221        let inner = f(emitter);
222        let close = emitter.close_object();
223        inner.and(close)
224    }
225
226    /// Consume the key and open an array. Caller must later call
227    /// [`JsonEmitter::close_array`] on the underlying emitter.
228    ///
229    /// # Errors
230    ///
231    /// Returns `Err` if a key is not allowed here, or if the backend errors.
232    #[inline]
233    pub fn open_array(self) -> Result<()> {
234        self.emitter.write_key(self.name)?;
235        self.emitter.open_array()
236    }
237
238    /// Consume the key and open an object. Caller must later call
239    /// [`JsonEmitter::close_object`] on the underlying emitter.
240    ///
241    /// # Errors
242    ///
243    /// Returns `Err` if a key is not allowed here, or if the backend errors.
244    #[inline]
245    pub fn open_object(self) -> Result<()> {
246        self.emitter.write_key(self.name)?;
247        self.emitter.open_object()
248    }
249
250    /// Consume the key and write a scalar value.
251    ///
252    /// # Errors
253    ///
254    /// Returns `Err` if a key is not allowed here, or if the backend errors.
255    #[inline]
256    pub fn value<V: WriteVal>(self, v: V) -> Result<()> {
257        let emitter = self.emitter;
258        let name = self.name;
259        emitter.write_key(name)?;
260        v.write_to(&mut emitter.backend)?;
261        emitter.stack.mark_value_written()
262    }
263}
264
265#[cfg(test)]
266mod tests {
267    mod errors {
268        use super::*;
269
270        #[test]
271        fn array_in_object_without_key_errors() {
272            let mut e = make();
273            assert!(e.object(|j| j.array(|_| Ok(()))).is_err());
274        }
275
276        #[test]
277        fn close_array_when_top_is_object_errors() {
278            let mut e = make();
279            assert!(e.open_object().is_ok());
280            assert!(e.close_array().is_err());
281        }
282
283        #[test]
284        fn close_object_at_root_errors() {
285            let mut e = make();
286            assert!(e.close_object().is_err());
287        }
288
289        #[test]
290        fn close_object_when_top_is_array_errors() {
291            let mut e = make();
292            assert!(e.open_array().is_ok());
293            assert!(e.close_object().is_err());
294        }
295
296        #[test]
297        fn closure_error_in_array_still_closes_array() {
298            let mut e = make();
299            let inner = e.array(|j| {
300                j.value("first")?;
301                Err(docspec_core::Error::Other {
302                    message: "inner".to_string(),
303                })
304            });
305            assert!(inner.is_err());
306            let tokens = finish_tokens(e);
307            assert_eq!(
308                tokens,
309                vec![
310                    Token::BeginArray,
311                    Token::StringValue("first".to_string()),
312                    Token::EndArray,
313                ]
314            );
315        }
316
317        #[test]
318        fn closure_error_in_object_still_closes_object() {
319            let mut e = make();
320            let inner = e.object(|j| {
321                j.key("a").value("1")?;
322                Err(docspec_core::Error::Other {
323                    message: "inner".to_string(),
324                })
325            });
326            assert!(inner.is_err());
327            let tokens = finish_tokens(e);
328            assert_eq!(
329                tokens,
330                vec![
331                    Token::BeginObject,
332                    Token::Name("a".to_string()),
333                    Token::StringValue("1".to_string()),
334                    Token::EndObject,
335                ]
336            );
337        }
338
339        #[test]
340        fn closure_error_propagates() {
341            let mut e = make();
342            let result = e.object(|_| {
343                Err(docspec_core::Error::Other {
344                    message: "inner error".to_string(),
345                })
346            });
347            assert!(result.is_err());
348        }
349
350        #[test]
351        fn dropped_key_does_not_corrupt_state() {
352            let mut e = make();
353            assert!(e.open_object().is_ok());
354            let k = e.key("x");
355            drop(k);
356            assert!(e.key("y").value("z").is_ok());
357            assert!(e.close_object().is_ok());
358        }
359
360        #[test]
361        fn finish_after_root_value_succeeds() {
362            let mut e = make();
363            assert!(e.value("x").is_ok());
364            assert!(e.finish().is_ok());
365        }
366
367        #[test]
368        fn finish_with_open_array_errors() {
369            let mut e = make();
370            assert!(e.open_array().is_ok());
371            assert!(e.finish().is_err());
372        }
373
374        #[test]
375        fn finish_with_open_object_errors() {
376            let mut e = make();
377            assert!(e.open_object().is_ok());
378            assert!(e.finish().is_err());
379        }
380
381        #[test]
382        fn finish_without_any_value_errors() {
383            let e = make();
384            assert!(e.finish().is_err());
385        }
386
387        #[test]
388        fn key_inside_array_errors() {
389            let mut e = make();
390            assert!(e.array(|j| j.key("x").value("1")).is_err());
391        }
392
393        #[test]
394        fn key_outside_object_errors() {
395            let mut e = make();
396            assert!(e.key("x").value("1").is_err());
397        }
398
399        #[test]
400        fn keyed_array_closure_error_still_closes_array() {
401            let mut e = make();
402            assert!(e.open_object().is_ok());
403            let inner = e.key("items").array(|j| {
404                j.value("first")?;
405                Err(docspec_core::Error::Other {
406                    message: "inner".to_string(),
407                })
408            });
409            assert!(inner.is_err());
410            assert!(e.close_object().is_ok());
411            let tokens = finish_tokens(e);
412            assert_eq!(
413                tokens,
414                vec![
415                    Token::BeginObject,
416                    Token::Name("items".to_string()),
417                    Token::BeginArray,
418                    Token::StringValue("first".to_string()),
419                    Token::EndArray,
420                    Token::EndObject,
421                ]
422            );
423        }
424
425        #[test]
426        fn keyed_object_closure_error_still_closes_object() {
427            let mut e = make();
428            assert!(e.open_object().is_ok());
429            let inner = e.key("inner").object(|j| {
430                j.key("a").value("1")?;
431                Err(docspec_core::Error::Other {
432                    message: "inner".to_string(),
433                })
434            });
435            assert!(inner.is_err());
436            assert!(e.close_object().is_ok());
437            let tokens = finish_tokens(e);
438            assert_eq!(
439                tokens,
440                vec![
441                    Token::BeginObject,
442                    Token::Name("inner".to_string()),
443                    Token::BeginObject,
444                    Token::Name("a".to_string()),
445                    Token::StringValue("1".to_string()),
446                    Token::EndObject,
447                    Token::EndObject,
448                ]
449            );
450        }
451
452        #[test]
453        fn object_in_object_without_key_errors() {
454            let mut e = make();
455            assert!(e.object(|j| j.object(|_| Ok(()))).is_err());
456        }
457
458        #[test]
459        fn open_object_in_object_expecting_value_errors() {
460            let mut e = make();
461            assert!(e.open_object().is_ok());
462            assert!(e.key("k").open_object().is_ok());
463            assert!(e.open_object().is_err());
464        }
465
466        #[test]
467        fn state_validation_uses_json_error_variant() {
468            let mut e = make();
469            assert!(e.open_object().is_ok());
470            let err = e.value("x");
471            assert!(matches!(err, Err(docspec_core::Error::Json { .. })));
472        }
473
474        #[test]
475        fn value_at_root_after_root_value_already_written_errors() {
476            let mut e = make();
477            assert!(e.value("first").is_ok());
478            assert!(e.value("second").is_err());
479        }
480
481        #[test]
482        fn value_in_object_without_key_errors() {
483            let mut e = make();
484            assert!(e.object(|j| j.value("x")).is_err());
485        }
486    }
487
488    mod happy_path {
489        use super::*;
490
491        #[test]
492        fn array_of_objects() {
493            let mut e = make();
494            assert!(e
495                .array(|j| { j.object(|j2| j2.key("x").value("a")) })
496                .is_ok());
497            let t = finish_tokens(e);
498            assert_eq!(
499                t,
500                vec![
501                    Token::BeginArray,
502                    Token::BeginObject,
503                    Token::Name("x".to_string()),
504                    Token::StringValue("a".to_string()),
505                    Token::EndObject,
506                    Token::EndArray,
507                ]
508            );
509        }
510
511        #[test]
512        fn array_of_scalars() {
513            let mut e = make();
514            assert!(e
515                .array(|j| {
516                    j.value("a")?;
517                    j.value(true)?;
518                    j.value(Null)
519                })
520                .is_ok());
521            let t = finish_tokens(e);
522            assert_eq!(
523                t,
524                vec![
525                    Token::BeginArray,
526                    Token::StringValue("a".to_string()),
527                    Token::BoolValue(true),
528                    Token::NullValue,
529                    Token::EndArray,
530                ]
531            );
532        }
533
534        #[test]
535        fn finish_returns_backend_output_tokens() {
536            let mut e = make();
537            assert!(e.value("hi").is_ok());
538            let t = finish_tokens(e);
539            assert_eq!(t, vec![Token::StringValue("hi".to_string())]);
540        }
541
542        #[test]
543        fn mixed_nested_structure_object_array_object() {
544            let mut e = make();
545            assert!(e
546                .object(|j| {
547                    j.key("a")
548                        .array(|j2| j2.object(|j3| j3.key("b").value(true)))
549                })
550                .is_ok());
551            let t = finish_tokens(e);
552            assert_eq!(
553                t,
554                vec![
555                    Token::BeginObject,
556                    Token::Name("a".to_string()),
557                    Token::BeginArray,
558                    Token::BeginObject,
559                    Token::Name("b".to_string()),
560                    Token::BoolValue(true),
561                    Token::EndObject,
562                    Token::EndArray,
563                    Token::EndObject,
564                ]
565            );
566        }
567
568        #[test]
569        fn nested_object_in_object() {
570            let mut e = make();
571            assert!(e
572                .object(|j| { j.key("inner").object(|j2| j2.key("k").value("v")) })
573                .is_ok());
574            let t = finish_tokens(e);
575            assert_eq!(
576                t,
577                vec![
578                    Token::BeginObject,
579                    Token::Name("inner".to_string()),
580                    Token::BeginObject,
581                    Token::Name("k".to_string()),
582                    Token::StringValue("v".to_string()),
583                    Token::EndObject,
584                    Token::EndObject,
585                ]
586            );
587        }
588
589        #[test]
590        fn object_with_multiple_keys_in_order() {
591            let mut e = make();
592            assert!(e
593                .object(|j| {
594                    j.key("a").value("1")?;
595                    j.key("b").value(true)?;
596                    j.key("c").value(Null)
597                })
598                .is_ok());
599            let t = finish_tokens(e);
600            assert_eq!(
601                t,
602                vec![
603                    Token::BeginObject,
604                    Token::Name("a".to_string()),
605                    Token::StringValue("1".to_string()),
606                    Token::Name("b".to_string()),
607                    Token::BoolValue(true),
608                    Token::Name("c".to_string()),
609                    Token::NullValue,
610                    Token::EndObject,
611                ]
612            );
613        }
614
615        #[test]
616        fn object_with_single_key_string_value() {
617            let mut e = make();
618            assert!(e.object(|j| j.key("k").value("v")).is_ok());
619            let t = finish_tokens(e);
620            assert_eq!(
621                t,
622                vec![
623                    Token::BeginObject,
624                    Token::Name("k".to_string()),
625                    Token::StringValue("v".to_string()),
626                    Token::EndObject,
627                ]
628            );
629        }
630
631        #[test]
632        fn root_array_empty() {
633            let mut e = make();
634            assert!(e.array(|_| Ok(())).is_ok());
635            assert_eq!(finish_tokens(e), vec![Token::BeginArray, Token::EndArray]);
636        }
637
638        #[test]
639        fn root_object_empty() {
640            let mut e = make();
641            assert!(e.object(|_| Ok(())).is_ok());
642            assert_eq!(finish_tokens(e), vec![Token::BeginObject, Token::EndObject]);
643        }
644
645        #[test]
646        fn root_scalar_null() {
647            let mut e = make();
648            assert!(e.value(Null).is_ok());
649            assert_eq!(finish_tokens(e), vec![Token::NullValue]);
650        }
651
652        #[test]
653        fn root_scalar_string() {
654            let mut e = make();
655            assert!(e.value("hello").is_ok());
656            assert_eq!(
657                finish_tokens(e),
658                vec![Token::StringValue("hello".to_string())]
659            );
660        }
661    }
662
663    mod streaming {
664        use super::*;
665
666        #[test]
667        fn keyed_open_array_then_close() {
668            let mut e = make();
669            assert!(e.open_object().is_ok());
670            assert!(e.key("content").open_array().is_ok());
671            assert!(e.value("x").is_ok());
672            assert!(e.close_array().is_ok());
673            assert!(e.close_object().is_ok());
674            let t = finish_tokens(e);
675            assert_eq!(
676                t,
677                vec![
678                    Token::BeginObject,
679                    Token::Name("content".to_string()),
680                    Token::BeginArray,
681                    Token::StringValue("x".to_string()),
682                    Token::EndArray,
683                    Token::EndObject,
684                ]
685            );
686        }
687
688        #[test]
689        fn keyed_open_object_then_close() {
690            let mut e = make();
691            assert!(e.open_array().is_ok());
692            assert!(e.open_object().is_ok());
693            assert!(e.key("type").value("h").is_ok());
694            assert!(e.close_object().is_ok());
695            assert!(e.close_array().is_ok());
696            let t = finish_tokens(e);
697            assert_eq!(
698                t,
699                vec![
700                    Token::BeginArray,
701                    Token::BeginObject,
702                    Token::Name("type".to_string()),
703                    Token::StringValue("h".to_string()),
704                    Token::EndObject,
705                    Token::EndArray,
706                ]
707            );
708        }
709
710        #[test]
711        fn keyed_open_then_unkeyed_open_in_array() {
712            let mut e = make();
713            assert!(e.open_object().is_ok());
714            assert!(e.key("c").open_array().is_ok());
715            assert!(e.open_object().is_ok());
716            assert!(e.close_object().is_ok());
717            assert!(e.close_array().is_ok());
718            assert!(e.close_object().is_ok());
719            assert!(!finish_tokens(e).is_empty());
720        }
721
722        #[test]
723        fn mixed_closure_and_streaming() {
724            let mut e = make();
725            assert!(e.open_object().is_ok());
726            assert!(e.key("k1").value("a").is_ok());
727            assert!(e.key("k2").array(|j| j.value(true)).is_ok());
728            assert!(e.close_object().is_ok());
729            let t = finish_tokens(e);
730            assert_eq!(
731                t,
732                vec![
733                    Token::BeginObject,
734                    Token::Name("k1".to_string()),
735                    Token::StringValue("a".to_string()),
736                    Token::Name("k2".to_string()),
737                    Token::BeginArray,
738                    Token::BoolValue(true),
739                    Token::EndArray,
740                    Token::EndObject,
741                ]
742            );
743        }
744
745        #[test]
746        fn nested_streaming_objects() {
747            let mut e = make();
748            assert!(e.open_object().is_ok());
749            assert!(e.key("a").open_object().is_ok());
750            assert!(e.key("b").open_object().is_ok());
751            assert!(e.close_object().is_ok());
752            assert!(e.close_object().is_ok());
753            assert!(e.close_object().is_ok());
754            let t = finish_tokens(e);
755            assert_eq!(
756                t,
757                vec![
758                    Token::BeginObject,
759                    Token::Name("a".to_string()),
760                    Token::BeginObject,
761                    Token::Name("b".to_string()),
762                    Token::BeginObject,
763                    Token::EndObject,
764                    Token::EndObject,
765                    Token::EndObject,
766                ]
767            );
768        }
769
770        #[test]
771        fn open_close_array_empty() {
772            let mut e = make();
773            assert!(e.open_array().is_ok());
774            assert!(e.close_array().is_ok());
775            assert_eq!(finish_tokens(e), vec![Token::BeginArray, Token::EndArray]);
776        }
777
778        #[test]
779        fn open_close_object_empty() {
780            let mut e = make();
781            assert!(e.open_object().is_ok());
782            assert!(e.close_object().is_ok());
783            assert_eq!(finish_tokens(e), vec![Token::BeginObject, Token::EndObject]);
784        }
785
786        #[test]
787        fn streaming_emits_blocknote_block_shape() {
788            let mut e = make();
789            assert!(e.open_array().is_ok());
790            assert!(e.open_object().is_ok());
791            assert!(e.key("type").value("heading").is_ok());
792            assert!(e.key("content").open_array().is_ok());
793            assert!(e.close_array().is_ok());
794            assert!(e.close_object().is_ok());
795            assert!(e.close_array().is_ok());
796            let t = finish_tokens(e);
797            assert_eq!(
798                t,
799                vec![
800                    Token::BeginArray,
801                    Token::BeginObject,
802                    Token::Name("type".to_string()),
803                    Token::StringValue("heading".to_string()),
804                    Token::Name("content".to_string()),
805                    Token::BeginArray,
806                    Token::EndArray,
807                    Token::EndObject,
808                    Token::EndArray,
809                ]
810            );
811        }
812
813        #[test]
814        fn streaming_root_array_with_two_objects_via_open_close() {
815            let mut e = make();
816            assert!(e.open_array().is_ok());
817            assert!(e.open_object().is_ok());
818            assert!(e.key("a").value("1").is_ok());
819            assert!(e.close_object().is_ok());
820            assert!(e.open_object().is_ok());
821            assert!(e.key("b").value("2").is_ok());
822            assert!(e.close_object().is_ok());
823            assert!(e.close_array().is_ok());
824            let t = finish_tokens(e);
825            assert_eq!(
826                t,
827                vec![
828                    Token::BeginArray,
829                    Token::BeginObject,
830                    Token::Name("a".to_string()),
831                    Token::StringValue("1".to_string()),
832                    Token::EndObject,
833                    Token::BeginObject,
834                    Token::Name("b".to_string()),
835                    Token::StringValue("2".to_string()),
836                    Token::EndObject,
837                    Token::EndArray,
838                ]
839            );
840        }
841    }
842
843    use super::*;
844    use crate::backend::{CapturingBackend, Token};
845    use crate::value::Null;
846
847    fn finish_tokens(e: JsonEmitter<CapturingBackend>) -> Vec<Token> {
848        let result = e.finish();
849        assert!(result.is_ok(), "finish should succeed");
850        result.unwrap_or_default()
851    }
852
853    fn make() -> JsonEmitter<CapturingBackend> {
854        JsonEmitter::new(CapturingBackend::new())
855    }
856}