libyaml_safer/
emitter.rs

1use std::collections::VecDeque;
2
3use crate::macros::{
4    is_alpha, is_ascii, is_blank, is_blankz, is_bom, is_break, is_breakz, is_printable, is_space,
5};
6use crate::{
7    Break, Encoding, Error, Event, EventData, MappingStyle, Result, ScalarStyle, SequenceStyle,
8    TagDirective, VersionDirective, OUTPUT_BUFFER_SIZE,
9};
10
11/// The emitter structure.
12///
13/// All members are internal. Manage the structure using the `yaml_emitter_`
14/// family of functions.
15#[non_exhaustive]
16pub struct Emitter<'w> {
17    /// Write handler.
18    pub(crate) write_handler: Option<&'w mut dyn std::io::Write>,
19    /// The working buffer.
20    ///
21    /// This always contains valid UTF-8.
22    pub(crate) buffer: String,
23    /// The raw buffer.
24    ///
25    /// This contains the output in the encoded format, so for example it may be
26    /// UTF-16 encoded.
27    pub(crate) raw_buffer: Vec<u8>,
28    /// The stream encoding.
29    pub(crate) encoding: Encoding,
30    /// If the output is in the canonical style?
31    pub(crate) canonical: bool,
32    /// The number of indentation spaces.
33    pub(crate) best_indent: i32,
34    /// The preferred width of the output lines.
35    pub(crate) best_width: i32,
36    /// Allow unescaped non-ASCII characters?
37    pub(crate) unicode: bool,
38    /// The preferred line break.
39    pub(crate) line_break: Break,
40    /// The stack of states.
41    pub(crate) states: Vec<EmitterState>,
42    /// The current emitter state.
43    pub(crate) state: EmitterState,
44    /// The event queue.
45    pub(crate) events: VecDeque<Event>,
46    /// The stack of indentation levels.
47    pub(crate) indents: Vec<i32>,
48    /// The list of tag directives.
49    pub(crate) tag_directives: Vec<TagDirective>,
50    /// The current indentation level.
51    pub(crate) indent: i32,
52    /// The current flow level.
53    pub(crate) flow_level: i32,
54    /// Is it the document root context?
55    pub(crate) root_context: bool,
56    /// Is it a sequence context?
57    pub(crate) sequence_context: bool,
58    /// Is it a mapping context?
59    pub(crate) mapping_context: bool,
60    /// Is it a simple mapping key context?
61    pub(crate) simple_key_context: bool,
62    /// The current line.
63    pub(crate) line: i32,
64    /// The current column.
65    pub(crate) column: i32,
66    /// If the last character was a whitespace?
67    pub(crate) whitespace: bool,
68    /// If the last character was an indentation character (' ', '-', '?', ':')?
69    pub(crate) indention: bool,
70    /// If an explicit document end is required?
71    pub(crate) open_ended: i32,
72    /// If the stream was already opened?
73    pub(crate) opened: bool,
74    /// If the stream was already closed?
75    pub(crate) closed: bool,
76    /// The information associated with the document nodes.
77    // Note: Same length as `document.nodes`.
78    pub(crate) anchors: Vec<Anchors>,
79    /// The last assigned anchor id.
80    pub(crate) last_anchor_id: i32,
81}
82
83impl Default for Emitter<'_> {
84    fn default() -> Self {
85        Self::new()
86    }
87}
88
89/// The emitter states.
90#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
91#[non_exhaustive]
92pub enum EmitterState {
93    /// Expect STREAM-START.
94    #[default]
95    StreamStart = 0,
96    /// Expect the first DOCUMENT-START or STREAM-END.
97    FirstDocumentStart = 1,
98    /// Expect DOCUMENT-START or STREAM-END.
99    DocumentStart = 2,
100    /// Expect the content of a document.
101    DocumentContent = 3,
102    /// Expect DOCUMENT-END.
103    DocumentEnd = 4,
104    /// Expect the first item of a flow sequence.
105    FlowSequenceFirstItem = 5,
106    /// Expect an item of a flow sequence.
107    FlowSequenceItem = 6,
108    /// Expect the first key of a flow mapping.
109    FlowMappingFirstKey = 7,
110    /// Expect a key of a flow mapping.
111    FlowMappingKey = 8,
112    /// Expect a value for a simple key of a flow mapping.
113    FlowMappingSimpleValue = 9,
114    /// Expect a value of a flow mapping.
115    FlowMappingValue = 10,
116    /// Expect the first item of a block sequence.
117    BlockSequenceFirstItem = 11,
118    /// Expect an item of a block sequence.
119    BlockSequenceItem = 12,
120    /// Expect the first key of a block mapping.
121    BlockMappingFirstKey = 13,
122    /// Expect the key of a block mapping.
123    BlockMappingKey = 14,
124    /// Expect a value for a simple key of a block mapping.
125    BlockMappingSimpleValue = 15,
126    /// Expect a value of a block mapping.
127    BlockMappingValue = 16,
128    /// Expect nothing.
129    End = 17,
130}
131
132#[derive(Copy, Clone, Default)]
133pub(crate) struct Anchors {
134    /// The number of references.
135    pub references: i32,
136    /// The anchor id.
137    pub anchor: i32,
138    /// If the node has been emitted?
139    pub serialized: bool,
140}
141
142#[derive(Default)]
143struct Analysis<'a> {
144    pub anchor: Option<AnchorAnalysis<'a>>,
145    pub tag: Option<TagAnalysis<'a>>,
146    pub scalar: Option<ScalarAnalysis<'a>>,
147}
148
149struct AnchorAnalysis<'a> {
150    pub anchor: &'a str,
151    pub alias: bool,
152}
153
154struct TagAnalysis<'a> {
155    pub handle: &'a str,
156    pub suffix: &'a str,
157}
158
159struct ScalarAnalysis<'a> {
160    /// The scalar value.
161    pub value: &'a str,
162    /// Does the scalar contain line breaks?
163    pub multiline: bool,
164    /// Can the scalar be expessed in the flow plain style?
165    pub flow_plain_allowed: bool,
166    /// Can the scalar be expressed in the block plain style?
167    pub block_plain_allowed: bool,
168    /// Can the scalar be expressed in the single quoted style?
169    pub single_quoted_allowed: bool,
170    /// Can the scalar be expressed in the literal or folded styles?
171    pub block_allowed: bool,
172    /// The output style.
173    pub style: ScalarStyle,
174}
175
176impl<'w> Emitter<'w> {
177    /// Create an self.
178    pub fn new() -> Emitter<'w> {
179        Emitter {
180            write_handler: None,
181            buffer: String::with_capacity(OUTPUT_BUFFER_SIZE),
182            raw_buffer: Vec::with_capacity(OUTPUT_BUFFER_SIZE),
183            encoding: Encoding::Any,
184            canonical: false,
185            best_indent: 0,
186            best_width: 0,
187            unicode: false,
188            line_break: Break::default(),
189            states: Vec::with_capacity(16),
190            state: EmitterState::default(),
191            events: VecDeque::with_capacity(16),
192            indents: Vec::with_capacity(16),
193            tag_directives: Vec::with_capacity(16),
194            indent: 0,
195            flow_level: 0,
196            root_context: false,
197            sequence_context: false,
198            mapping_context: false,
199            simple_key_context: false,
200            line: 0,
201            column: 0,
202            whitespace: false,
203            indention: false,
204            open_ended: 0,
205            opened: false,
206            closed: false,
207            anchors: Vec::new(),
208            last_anchor_id: 0,
209        }
210    }
211
212    /// Reset the emitter state.
213    pub fn reset(&mut self) {
214        *self = Self::new();
215    }
216
217    /// Start a YAML stream.
218    ///
219    /// This function should be used before
220    /// [`Document::dump()`](crate::Document::dump) is called.
221    pub fn open(&mut self) -> Result<()> {
222        assert!(!self.opened);
223        let event = Event::stream_start(Encoding::Any);
224        self.emit(event)?;
225        self.opened = true;
226        Ok(())
227    }
228
229    /// Finish a YAML stream.
230    ///
231    /// This function should be used after
232    /// [`Document::dump()`](crate::Document::dump) is called.
233    pub fn close(&mut self) -> Result<()> {
234        assert!(self.opened);
235        if self.closed {
236            return Ok(());
237        }
238        let event = Event::stream_end();
239        self.emit(event)?;
240        self.closed = true;
241        Ok(())
242    }
243
244    /// Set a string output.
245    ///
246    /// The emitter will write the output characters to the `output` buffer.
247    pub fn set_output_string(&mut self, output: &'w mut Vec<u8>) {
248        assert!(self.write_handler.is_none());
249        if self.encoding == Encoding::Any {
250            self.set_encoding(Encoding::Utf8);
251        } else if self.encoding != Encoding::Utf8 {
252            panic!("cannot output UTF-16 to String")
253        }
254        output.clear();
255        self.write_handler = Some(output);
256    }
257
258    /// Set a generic output handler.
259    pub fn set_output(&mut self, handler: &'w mut dyn std::io::Write) {
260        assert!(self.write_handler.is_none());
261        self.write_handler = Some(handler);
262    }
263
264    /// Set the output encoding.
265    pub fn set_encoding(&mut self, encoding: Encoding) {
266        assert_eq!(self.encoding, Encoding::Any);
267        self.encoding = encoding;
268    }
269
270    /// Set if the output should be in the "canonical" format as in the YAML
271    /// specification.
272    pub fn set_canonical(&mut self, canonical: bool) {
273        self.canonical = canonical;
274    }
275
276    /// Set the indentation increment.
277    pub fn set_indent(&mut self, indent: i32) {
278        self.best_indent = if 1 < indent && indent < 10 { indent } else { 2 };
279    }
280
281    /// Set the preferred line width. -1 means unlimited.
282    pub fn set_width(&mut self, width: i32) {
283        self.best_width = if width >= 0 { width } else { -1 };
284    }
285
286    /// Set if unescaped non-ASCII characters are allowed.
287    pub fn set_unicode(&mut self, unicode: bool) {
288        self.unicode = unicode;
289    }
290
291    /// Set the preferred line break.
292    pub fn set_break(&mut self, line_break: Break) {
293        self.line_break = line_break;
294    }
295
296    /// Emit an event.
297    ///
298    /// The event object may be generated using the
299    /// [`Parser::parse()`](crate::Parser::parse) function. The emitter takes
300    /// the responsibility for the event object and destroys its content after
301    /// it is emitted. The event object is destroyed even if the function fails.
302    pub fn emit(&mut self, event: Event) -> Result<()> {
303        self.events.push_back(event);
304        while let Some(event) = self.needs_mode_events() {
305            let tag_directives = core::mem::take(&mut self.tag_directives);
306
307            let mut analysis = self.analyze_event(&event, &tag_directives)?;
308            self.state_machine(&event, &mut analysis)?;
309
310            // The DOCUMENT-START event populates the tag directives, and this
311            // happens only once, so don't swap out the tags in that case.
312            if self.tag_directives.is_empty() {
313                self.tag_directives = tag_directives;
314            }
315        }
316        Ok(())
317    }
318
319    /// Equivalent of the libyaml `FLUSH` macro.
320    fn flush_if_needed(&mut self) -> Result<()> {
321        if self.buffer.len() < OUTPUT_BUFFER_SIZE - 5 {
322            Ok(())
323        } else {
324            self.flush()
325        }
326    }
327
328    /// Equivalent of the libyaml `PUT` macro.
329    fn put(&mut self, value: char) -> Result<()> {
330        self.flush_if_needed()?;
331        self.buffer.push(value);
332        self.column += 1;
333        Ok(())
334    }
335
336    /// Equivalent of the libyaml `PUT_BREAK` macro.
337    fn put_break(&mut self) -> Result<()> {
338        self.flush_if_needed()?;
339        if self.line_break == Break::Cr {
340            self.buffer.push('\r');
341        } else if self.line_break == Break::Ln {
342            self.buffer.push('\n');
343        } else if self.line_break == Break::CrLn {
344            self.buffer.push_str("\r\n");
345        }
346        self.column = 0;
347        self.line += 1;
348        Ok(())
349    }
350
351    /// Write UTF-8 charanters from `string` to `emitter` and increment
352    /// `emitter.column` the appropriate number of times. It is assumed that the
353    /// string does not contain line breaks!
354    fn write_str(&mut self, string: &str) -> Result<()> {
355        if self.buffer.len() + string.len() > OUTPUT_BUFFER_SIZE {
356            self.flush()?;
357        }
358
359        // Note: Reserves less than what is necessary if there are UTF-8
360        // characters present.
361        self.buffer.reserve(string.len());
362
363        self.column += string.chars().count() as i32;
364
365        // Note: This may cause the buffer to become slightly larger than
366        // `OUTPUT_BUFFER_SIZE`, but not by much.
367        self.buffer.push_str(string);
368
369        Ok(())
370    }
371
372    /// Equivalent of the libyaml `WRITE` macro.
373    fn write_char(&mut self, ch: char) -> Result<()> {
374        self.flush_if_needed()?;
375        self.buffer.push(ch);
376        self.column += 1;
377        Ok(())
378    }
379
380    /// Equivalent of the libyaml `WRITE_BREAK` macro.
381    fn write_break(&mut self, ch: char) -> Result<()> {
382        self.flush_if_needed()?;
383        if ch == '\n' {
384            self.put_break()?;
385        } else {
386            self.write_char(ch)?;
387            self.column = 0;
388            self.line += 1;
389        }
390        Ok(())
391    }
392
393    fn needs_mode_events(&mut self) -> Option<Event> {
394        let first = self.events.front()?;
395
396        let accummulate = match &first.data {
397            EventData::DocumentStart { .. } => 1,
398            EventData::SequenceStart { .. } => 2,
399            EventData::MappingStart { .. } => 3,
400            _ => return self.events.pop_front(),
401        };
402
403        if self.events.len() > accummulate {
404            return self.events.pop_front();
405        }
406
407        let mut level = 0;
408        for event in &self.events {
409            match event.data {
410                EventData::StreamStart { .. }
411                | EventData::DocumentStart { .. }
412                | EventData::SequenceStart { .. }
413                | EventData::MappingStart { .. } => {
414                    level += 1;
415                }
416
417                EventData::StreamEnd
418                | EventData::DocumentEnd { .. }
419                | EventData::SequenceEnd
420                | EventData::MappingEnd => {
421                    level -= 1;
422                }
423                _ => {}
424            }
425
426            if level == 0 {
427                return self.events.pop_front();
428            }
429        }
430
431        None
432    }
433
434    fn append_tag_directive(&mut self, value: TagDirective, allow_duplicates: bool) -> Result<()> {
435        for tag_directive in &self.tag_directives {
436            if value.handle == tag_directive.handle {
437                if allow_duplicates {
438                    return Ok(());
439                }
440                return Err(Error::emitter("duplicate %TAG directive"));
441            }
442        }
443        self.tag_directives.push(value);
444        Ok(())
445    }
446
447    fn increase_indent(&mut self, flow: bool, indentless: bool) {
448        self.indents.push(self.indent);
449        if self.indent < 0 {
450            self.indent = if flow { self.best_indent } else { 0 };
451        } else if !indentless {
452            self.indent += self.best_indent;
453        }
454    }
455
456    fn state_machine<'a>(&mut self, event: &'a Event, analysis: &mut Analysis<'a>) -> Result<()> {
457        match self.state {
458            EmitterState::StreamStart => self.emit_stream_start(event),
459            EmitterState::FirstDocumentStart => self.emit_document_start(event, true),
460            EmitterState::DocumentStart => self.emit_document_start(event, false),
461            EmitterState::DocumentContent => self.emit_document_content(event, analysis),
462            EmitterState::DocumentEnd => self.emit_document_end(event),
463            EmitterState::FlowSequenceFirstItem => {
464                self.emit_flow_sequence_item(event, true, analysis)
465            }
466            EmitterState::FlowSequenceItem => self.emit_flow_sequence_item(event, false, analysis),
467            EmitterState::FlowMappingFirstKey => self.emit_flow_mapping_key(event, true, analysis),
468            EmitterState::FlowMappingKey => self.emit_flow_mapping_key(event, false, analysis),
469            EmitterState::FlowMappingSimpleValue => {
470                self.emit_flow_mapping_value(event, true, analysis)
471            }
472            EmitterState::FlowMappingValue => self.emit_flow_mapping_value(event, false, analysis),
473            EmitterState::BlockSequenceFirstItem => {
474                self.emit_block_sequence_item(event, true, analysis)
475            }
476            EmitterState::BlockSequenceItem => {
477                self.emit_block_sequence_item(event, false, analysis)
478            }
479            EmitterState::BlockMappingFirstKey => {
480                self.emit_block_mapping_key(event, true, analysis)
481            }
482            EmitterState::BlockMappingKey => self.emit_block_mapping_key(event, false, analysis),
483            EmitterState::BlockMappingSimpleValue => {
484                self.emit_block_mapping_value(event, true, analysis)
485            }
486            EmitterState::BlockMappingValue => {
487                self.emit_block_mapping_value(event, false, analysis)
488            }
489            EmitterState::End => Err(Error::emitter("expected nothing after STREAM-END")),
490        }
491    }
492
493    fn emit_stream_start(&mut self, event: &Event) -> Result<()> {
494        self.open_ended = 0;
495        if let EventData::StreamStart { ref encoding } = event.data {
496            if self.encoding == Encoding::Any {
497                self.encoding = *encoding;
498            }
499            if self.encoding == Encoding::Any {
500                self.encoding = Encoding::Utf8;
501            }
502            if self.best_indent < 2 || self.best_indent > 9 {
503                self.best_indent = 2;
504            }
505            if self.best_width >= 0 && self.best_width <= self.best_indent * 2 {
506                self.best_width = 80;
507            }
508            if self.best_width < 0 {
509                self.best_width = i32::MAX;
510            }
511            if self.line_break == Break::Any {
512                self.line_break = Break::Ln;
513            }
514            self.indent = -1;
515            self.line = 0;
516            self.column = 0;
517            self.whitespace = true;
518            self.indention = true;
519            if self.encoding != Encoding::Utf8 {
520                self.write_bom()?;
521            }
522            self.state = EmitterState::FirstDocumentStart;
523            return Ok(());
524        }
525        Err(Error::emitter("expected STREAM-START"))
526    }
527
528    fn emit_document_start(&mut self, event: &Event, first: bool) -> Result<()> {
529        if let EventData::DocumentStart {
530            version_directive,
531            tag_directives,
532            implicit,
533        } = &event.data
534        {
535            let default_tag_directives: [TagDirective; 2] = [
536                // TODO: Avoid these heap allocations.
537                TagDirective {
538                    handle: String::from("!"),
539                    prefix: String::from("!"),
540                },
541                TagDirective {
542                    handle: String::from("!!"),
543                    prefix: String::from("tag:yaml.org,2002:"),
544                },
545            ];
546            let mut implicit = *implicit;
547            if let Some(version_directive) = version_directive {
548                Self::analyze_version_directive(*version_directive)?;
549            }
550            for tag_directive in tag_directives {
551                Self::analyze_tag_directive(tag_directive)?;
552                self.append_tag_directive(tag_directive.clone(), false)?;
553            }
554            for tag_directive in default_tag_directives {
555                self.append_tag_directive(tag_directive, true)?;
556            }
557            if !first || self.canonical {
558                implicit = false;
559            }
560            if (version_directive.is_some() || !tag_directives.is_empty()) && self.open_ended != 0 {
561                self.write_indicator("...", true, false, false)?;
562                self.write_indent()?;
563            }
564            self.open_ended = 0;
565            if let Some(version_directive) = version_directive {
566                implicit = false;
567                self.write_indicator("%YAML", true, false, false)?;
568                if version_directive.minor == 1 {
569                    self.write_indicator("1.1", true, false, false)?;
570                } else {
571                    self.write_indicator("1.2", true, false, false)?;
572                }
573                self.write_indent()?;
574            }
575            if !tag_directives.is_empty() {
576                implicit = false;
577                for tag_directive in tag_directives {
578                    self.write_indicator("%TAG", true, false, false)?;
579                    self.write_tag_handle(&tag_directive.handle)?;
580                    self.write_tag_content(&tag_directive.prefix, true)?;
581                    self.write_indent()?;
582                }
583            }
584            if Self::check_empty_document() {
585                implicit = false;
586            }
587            if !implicit {
588                self.write_indent()?;
589                self.write_indicator("---", true, false, false)?;
590                if self.canonical {
591                    self.write_indent()?;
592                }
593            }
594            self.state = EmitterState::DocumentContent;
595            self.open_ended = 0;
596            return Ok(());
597        } else if let EventData::StreamEnd = &event.data {
598            if self.open_ended == 2 {
599                self.write_indicator("...", true, false, false)?;
600                self.open_ended = 0;
601                self.write_indent()?;
602            }
603            self.flush()?;
604            self.state = EmitterState::End;
605            return Ok(());
606        }
607
608        Err(Error::emitter("expected DOCUMENT-START or STREAM-END"))
609    }
610
611    fn emit_document_content(&mut self, event: &Event, analysis: &mut Analysis) -> Result<()> {
612        self.states.push(EmitterState::DocumentEnd);
613        self.emit_node(event, true, false, false, false, analysis)
614    }
615
616    fn emit_document_end(&mut self, event: &Event) -> Result<()> {
617        if let EventData::DocumentEnd { implicit } = &event.data {
618            let implicit = *implicit;
619            self.write_indent()?;
620            if !implicit {
621                self.write_indicator("...", true, false, false)?;
622                self.open_ended = 0;
623                self.write_indent()?;
624            } else if self.open_ended == 0 {
625                self.open_ended = 1;
626            }
627            self.flush()?;
628            self.state = EmitterState::DocumentStart;
629            self.tag_directives.clear();
630            return Ok(());
631        }
632
633        Err(Error::emitter("expected DOCUMENT-END"))
634    }
635
636    fn emit_flow_sequence_item(
637        &mut self,
638        event: &Event,
639        first: bool,
640        analysis: &mut Analysis,
641    ) -> Result<()> {
642        if first {
643            self.write_indicator("[", true, true, false)?;
644            self.increase_indent(true, false);
645            self.flow_level += 1;
646        }
647        if let EventData::SequenceEnd = &event.data {
648            self.flow_level -= 1;
649            self.indent = self.indents.pop().unwrap();
650            if self.canonical && !first {
651                self.write_indicator(",", false, false, false)?;
652                self.write_indent()?;
653            }
654            self.write_indicator("]", false, false, false)?;
655            self.state = self.states.pop().unwrap();
656            return Ok(());
657        }
658        if !first {
659            self.write_indicator(",", false, false, false)?;
660        }
661        if self.canonical || self.column > self.best_width {
662            self.write_indent()?;
663        }
664        self.states.push(EmitterState::FlowSequenceItem);
665        self.emit_node(event, false, true, false, false, analysis)
666    }
667
668    fn emit_flow_mapping_key(
669        &mut self,
670        event: &Event,
671        first: bool,
672        analysis: &mut Analysis,
673    ) -> Result<()> {
674        if first {
675            self.write_indicator("{", true, true, false)?;
676            self.increase_indent(true, false);
677            self.flow_level += 1;
678        }
679        if let EventData::MappingEnd = &event.data {
680            assert!(!self.indents.is_empty(), "self.indents should not be empty");
681            self.flow_level -= 1;
682            self.indent = self.indents.pop().unwrap();
683            if self.canonical && !first {
684                self.write_indicator(",", false, false, false)?;
685                self.write_indent()?;
686            }
687            self.write_indicator("}", false, false, false)?;
688            self.state = self.states.pop().unwrap();
689            return Ok(());
690        }
691        if !first {
692            self.write_indicator(",", false, false, false)?;
693        }
694        if self.canonical || self.column > self.best_width {
695            self.write_indent()?;
696        }
697        if !self.canonical && self.check_simple_key(event, analysis) {
698            self.states.push(EmitterState::FlowMappingSimpleValue);
699            self.emit_node(event, false, false, true, true, analysis)
700        } else {
701            self.write_indicator("?", true, false, false)?;
702            self.states.push(EmitterState::FlowMappingValue);
703            self.emit_node(event, false, false, true, false, analysis)
704        }
705    }
706
707    fn emit_flow_mapping_value(
708        &mut self,
709        event: &Event,
710        simple: bool,
711        analysis: &mut Analysis,
712    ) -> Result<()> {
713        if simple {
714            self.write_indicator(":", false, false, false)?;
715        } else {
716            if self.canonical || self.column > self.best_width {
717                self.write_indent()?;
718            }
719            self.write_indicator(":", true, false, false)?;
720        }
721        self.states.push(EmitterState::FlowMappingKey);
722        self.emit_node(event, false, false, true, false, analysis)
723    }
724
725    fn emit_block_sequence_item(
726        &mut self,
727        event: &Event,
728        first: bool,
729        analysis: &mut Analysis,
730    ) -> Result<()> {
731        if first {
732            self.increase_indent(false, self.mapping_context && !self.indention);
733        }
734        if let EventData::SequenceEnd = &event.data {
735            self.indent = self.indents.pop().unwrap();
736            self.state = self.states.pop().unwrap();
737            return Ok(());
738        }
739        self.write_indent()?;
740        self.write_indicator("-", true, false, true)?;
741        self.states.push(EmitterState::BlockSequenceItem);
742        self.emit_node(event, false, true, false, false, analysis)
743    }
744
745    fn emit_block_mapping_key(
746        &mut self,
747        event: &Event,
748        first: bool,
749        analysis: &mut Analysis,
750    ) -> Result<()> {
751        if first {
752            self.increase_indent(false, false);
753        }
754        if let EventData::MappingEnd = &event.data {
755            self.indent = self.indents.pop().unwrap();
756            self.state = self.states.pop().unwrap();
757            return Ok(());
758        }
759        self.write_indent()?;
760        if self.check_simple_key(event, analysis) {
761            self.states.push(EmitterState::BlockMappingSimpleValue);
762            self.emit_node(event, false, false, true, true, analysis)
763        } else {
764            self.write_indicator("?", true, false, true)?;
765            self.states.push(EmitterState::BlockMappingValue);
766            self.emit_node(event, false, false, true, false, analysis)
767        }
768    }
769
770    fn emit_block_mapping_value(
771        &mut self,
772        event: &Event,
773        simple: bool,
774        analysis: &mut Analysis,
775    ) -> Result<()> {
776        if simple {
777            self.write_indicator(":", false, false, false)?;
778        } else {
779            self.write_indent()?;
780            self.write_indicator(":", true, false, true)?;
781        }
782        self.states.push(EmitterState::BlockMappingKey);
783        self.emit_node(event, false, false, true, false, analysis)
784    }
785
786    fn emit_node(
787        &mut self,
788        event: &Event,
789        root: bool,
790        sequence: bool,
791        mapping: bool,
792        simple_key: bool,
793        analysis: &mut Analysis,
794    ) -> Result<()> {
795        self.root_context = root;
796        self.sequence_context = sequence;
797        self.mapping_context = mapping;
798        self.simple_key_context = simple_key;
799
800        match event.data {
801            EventData::Alias { .. } => self.emit_alias(event, analysis.anchor.as_ref()),
802            EventData::Scalar { .. } => self.emit_scalar(event, analysis),
803            EventData::SequenceStart { .. } => self.emit_sequence_start(event, analysis),
804            EventData::MappingStart { .. } => self.emit_mapping_start(event, analysis),
805            _ => Err(Error::emitter(
806                "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS",
807            )),
808        }
809    }
810
811    fn emit_alias(&mut self, _event: &Event, analysis: Option<&AnchorAnalysis>) -> Result<()> {
812        self.process_anchor(analysis)?;
813        if self.simple_key_context {
814            self.put(' ')?;
815        }
816        self.state = self.states.pop().unwrap();
817        Ok(())
818    }
819
820    fn emit_scalar(&mut self, event: &Event, analysis: &mut Analysis) -> Result<()> {
821        let (anchor, tag, scalar) = match analysis {
822            Analysis {
823                anchor,
824                tag,
825                scalar: Some(scalar),
826            } => (anchor, tag, scalar),
827            _ => unreachable!("no scalar analysis"),
828        };
829
830        self.select_scalar_style(event, scalar, tag)?;
831        self.process_anchor(anchor.as_ref())?;
832        self.process_tag(tag.as_ref())?;
833        self.increase_indent(true, false);
834        self.process_scalar(scalar)?;
835        self.indent = self.indents.pop().unwrap();
836        self.state = self.states.pop().unwrap();
837        Ok(())
838    }
839
840    fn emit_sequence_start(&mut self, event: &Event, analysis: &Analysis) -> Result<()> {
841        let Analysis { anchor, tag, .. } = analysis;
842        self.process_anchor(anchor.as_ref())?;
843        self.process_tag(tag.as_ref())?;
844
845        let style = match &event.data {
846            EventData::SequenceStart { style, .. } => style,
847            _ => unreachable!(),
848        };
849
850        if self.flow_level != 0
851            || self.canonical
852            || *style == SequenceStyle::Flow
853            || self.check_empty_sequence(event)
854        {
855            self.state = EmitterState::FlowSequenceFirstItem;
856        } else {
857            self.state = EmitterState::BlockSequenceFirstItem;
858        }
859        Ok(())
860    }
861
862    fn emit_mapping_start(&mut self, event: &Event, analysis: &Analysis) -> Result<()> {
863        let Analysis { anchor, tag, .. } = analysis;
864        self.process_anchor(anchor.as_ref())?;
865        self.process_tag(tag.as_ref())?;
866
867        let style = match &event.data {
868            EventData::MappingStart { style, .. } => style,
869            _ => unreachable!(),
870        };
871
872        if self.flow_level != 0
873            || self.canonical
874            || *style == MappingStyle::Flow
875            || self.check_empty_mapping(event)
876        {
877            self.state = EmitterState::FlowMappingFirstKey;
878        } else {
879            self.state = EmitterState::BlockMappingFirstKey;
880        }
881        Ok(())
882    }
883
884    fn check_empty_document() -> bool {
885        false
886    }
887
888    fn check_empty_sequence(&self, event: &Event) -> bool {
889        if self.events.is_empty() {
890            return false;
891        }
892        let start = matches!(event.data, EventData::SequenceStart { .. });
893        let end = matches!(self.events[0].data, EventData::SequenceEnd);
894        start && end
895    }
896
897    fn check_empty_mapping(&self, event: &Event) -> bool {
898        if self.events.is_empty() {
899            return false;
900        }
901        let start = matches!(event.data, EventData::MappingStart { .. });
902        let end = matches!(self.events[0].data, EventData::MappingEnd);
903        start && end
904    }
905
906    fn check_simple_key(&self, event: &Event, analysis: &Analysis) -> bool {
907        let Analysis {
908            tag,
909            anchor,
910            scalar,
911        } = analysis;
912
913        let mut length = anchor.as_ref().map_or(0, |a| a.anchor.len())
914            + tag.as_ref().map_or(0, |t| t.handle.len() + t.suffix.len());
915
916        match event.data {
917            EventData::Alias { .. } => {
918                length = analysis.anchor.as_ref().map_or(0, |a| a.anchor.len());
919            }
920            EventData::Scalar { .. } => {
921                let scalar = match scalar {
922                    Some(scalar) => scalar,
923                    None => panic!("no analysis for scalar"),
924                };
925
926                if scalar.multiline {
927                    return false;
928                }
929                length += scalar.value.len();
930            }
931            EventData::SequenceStart { .. } => {
932                if !self.check_empty_sequence(event) {
933                    return false;
934                }
935            }
936            EventData::MappingStart { .. } => {
937                if !self.check_empty_mapping(event) {
938                    return false;
939                }
940            }
941            _ => return false,
942        }
943
944        if length > 128 {
945            return false;
946        }
947
948        true
949    }
950
951    fn select_scalar_style(
952        &mut self,
953        event: &Event,
954        scalar_analysis: &mut ScalarAnalysis,
955        tag_analysis: &mut Option<TagAnalysis>,
956    ) -> Result<()> {
957        let (plain_implicit, quoted_implicit, style) = match &event.data {
958            EventData::Scalar {
959                plain_implicit,
960                quoted_implicit,
961                style,
962                ..
963            } => (plain_implicit, quoted_implicit, style),
964            _ => unreachable!(),
965        };
966
967        let mut style: ScalarStyle = *style;
968        let no_tag = tag_analysis.is_none();
969        if no_tag && !*plain_implicit && !*quoted_implicit {
970            return Err(Error::emitter(
971                "neither tag nor implicit flags are specified",
972            ));
973        }
974        if style == ScalarStyle::Any {
975            style = ScalarStyle::Plain;
976        }
977        if self.canonical {
978            style = ScalarStyle::DoubleQuoted;
979        }
980        if self.simple_key_context && scalar_analysis.multiline {
981            style = ScalarStyle::DoubleQuoted;
982        }
983        if style == ScalarStyle::Plain {
984            if self.flow_level != 0 && !scalar_analysis.flow_plain_allowed
985                || self.flow_level == 0 && !scalar_analysis.block_plain_allowed
986            {
987                style = ScalarStyle::SingleQuoted;
988            }
989            if scalar_analysis.value.is_empty() && (self.flow_level != 0 || self.simple_key_context)
990            {
991                style = ScalarStyle::SingleQuoted;
992            }
993            if no_tag && !*plain_implicit {
994                style = ScalarStyle::SingleQuoted;
995            }
996        }
997        if style == ScalarStyle::SingleQuoted && !scalar_analysis.single_quoted_allowed {
998            style = ScalarStyle::DoubleQuoted;
999        }
1000        if (style == ScalarStyle::Literal || style == ScalarStyle::Folded)
1001            && (!scalar_analysis.block_allowed || self.flow_level != 0 || self.simple_key_context)
1002        {
1003            style = ScalarStyle::DoubleQuoted;
1004        }
1005        if no_tag && !*quoted_implicit && style != ScalarStyle::Plain {
1006            *tag_analysis = Some(TagAnalysis {
1007                handle: "!",
1008                suffix: "",
1009            });
1010        }
1011        scalar_analysis.style = style;
1012        Ok(())
1013    }
1014
1015    fn process_anchor(&mut self, analysis: Option<&AnchorAnalysis>) -> Result<()> {
1016        let analysis = match analysis.as_ref() {
1017            Some(analysis) => analysis,
1018            None => return Ok(()),
1019        };
1020        self.write_indicator(if analysis.alias { "*" } else { "&" }, true, false, false)?;
1021        self.write_anchor(analysis.anchor)
1022    }
1023
1024    fn process_tag(&mut self, analysis: Option<&TagAnalysis>) -> Result<()> {
1025        let analysis = match analysis {
1026            Some(analysis) => analysis,
1027            None => return Ok(()),
1028        };
1029
1030        if analysis.handle.is_empty() && analysis.suffix.is_empty() {
1031            return Ok(());
1032        }
1033        if analysis.handle.is_empty() {
1034            self.write_indicator("!<", true, false, false)?;
1035            self.write_tag_content(analysis.suffix, false)?;
1036            self.write_indicator(">", false, false, false)?;
1037        } else {
1038            self.write_tag_handle(analysis.handle)?;
1039            if !analysis.suffix.is_empty() {
1040                self.write_tag_content(analysis.suffix, false)?;
1041            }
1042        }
1043        Ok(())
1044    }
1045
1046    fn process_scalar(&mut self, analysis: &ScalarAnalysis) -> Result<()> {
1047        match analysis.style {
1048            ScalarStyle::Plain => self.write_plain_scalar(analysis.value, !self.simple_key_context),
1049            ScalarStyle::SingleQuoted => {
1050                self.write_single_quoted_scalar(analysis.value, !self.simple_key_context)
1051            }
1052            ScalarStyle::DoubleQuoted => {
1053                self.write_double_quoted_scalar(analysis.value, !self.simple_key_context)
1054            }
1055            ScalarStyle::Literal => self.write_literal_scalar(analysis.value),
1056            ScalarStyle::Folded => self.write_folded_scalar(analysis.value),
1057            ScalarStyle::Any => unreachable!("No scalar style chosen"),
1058        }
1059    }
1060
1061    fn analyze_version_directive(version_directive: VersionDirective) -> Result<()> {
1062        if version_directive.major != 1
1063            || version_directive.minor != 1 && version_directive.minor != 2
1064        {
1065            return Err(Error::emitter("incompatible %YAML directive"));
1066        }
1067        Ok(())
1068    }
1069
1070    fn analyze_tag_directive(tag_directive: &TagDirective) -> Result<()> {
1071        if tag_directive.handle.is_empty() {
1072            return Err(Error::emitter("tag handle must not be empty"));
1073        }
1074        if !tag_directive.handle.starts_with('!') {
1075            return Err(Error::emitter("tag handle must start with '!'"));
1076        }
1077        if !tag_directive.handle.ends_with('!') {
1078            return Err(Error::emitter("tag handle must end with '!'"));
1079        }
1080        if tag_directive.handle.len() > 2 {
1081            let tag_content = &tag_directive.handle[1..tag_directive.handle.len() - 1];
1082            for ch in tag_content.chars() {
1083                if !is_alpha(ch) {
1084                    return Err(Error::emitter(
1085                        "tag handle must contain alphanumerical characters only",
1086                    ));
1087                }
1088            }
1089        }
1090
1091        if tag_directive.prefix.is_empty() {
1092            return Err(Error::emitter("tag prefix must not be empty"));
1093        }
1094
1095        Ok(())
1096    }
1097
1098    fn analyze_anchor(anchor: &str, alias: bool) -> Result<AnchorAnalysis<'_>> {
1099        if anchor.is_empty() {
1100            return Err(Error::emitter(if alias {
1101                "alias value must not be empty"
1102            } else {
1103                "anchor value must not be empty"
1104            }));
1105        }
1106
1107        for ch in anchor.chars() {
1108            if !is_alpha(ch) {
1109                return Err(Error::emitter(if alias {
1110                    "alias value must contain alphanumerical characters only"
1111                } else {
1112                    "anchor value must contain alphanumerical characters only"
1113                }));
1114            }
1115        }
1116
1117        Ok(AnchorAnalysis { anchor, alias })
1118    }
1119
1120    fn analyze_tag<'a>(
1121        tag: &'a str,
1122        tag_directives: &'a [TagDirective],
1123    ) -> Result<TagAnalysis<'a>> {
1124        if tag.is_empty() {
1125            return Err(Error::emitter("tag value must not be empty"));
1126        }
1127
1128        let mut handle = "";
1129        let mut suffix = tag;
1130
1131        for tag_directive in tag_directives {
1132            let prefix_len = tag_directive.prefix.len();
1133            if prefix_len < tag.len() && tag_directive.prefix == tag[0..prefix_len] {
1134                handle = &tag_directive.handle;
1135                suffix = &tag[prefix_len..];
1136                break;
1137            }
1138        }
1139
1140        Ok(TagAnalysis { handle, suffix })
1141    }
1142
1143    fn analyze_scalar<'a>(&mut self, value: &'a str) -> Result<ScalarAnalysis<'a>> {
1144        let mut block_indicators = false;
1145        let mut flow_indicators = false;
1146        let mut line_breaks = false;
1147        let mut special_characters = false;
1148        let mut leading_space = false;
1149        let mut leading_break = false;
1150        let mut trailing_space = false;
1151        let mut trailing_break = false;
1152        let mut break_space = false;
1153        let mut space_break = false;
1154        let mut preceded_by_whitespace;
1155        let mut previous_space = false;
1156        let mut previous_break = false;
1157
1158        if value.is_empty() {
1159            return Ok(ScalarAnalysis {
1160                value: "",
1161                multiline: false,
1162                flow_plain_allowed: false,
1163                block_plain_allowed: true,
1164                single_quoted_allowed: true,
1165                block_allowed: false,
1166                style: ScalarStyle::Any,
1167            });
1168        }
1169
1170        if value.starts_with("---") || value.starts_with("...") {
1171            block_indicators = true;
1172            flow_indicators = true;
1173        }
1174        preceded_by_whitespace = true;
1175
1176        let mut chars = value.chars();
1177        let mut first = true;
1178
1179        while let Some(ch) = chars.next() {
1180            let next = chars.clone().next();
1181            let followed_by_whitespace = is_blankz(next);
1182            if first {
1183                match ch {
1184                    '#' | ',' | '[' | ']' | '{' | '}' | '&' | '*' | '!' | '|' | '>' | '\''
1185                    | '"' | '%' | '@' | '`' => {
1186                        flow_indicators = true;
1187                        block_indicators = true;
1188                    }
1189                    '?' | ':' => {
1190                        flow_indicators = true;
1191                        if followed_by_whitespace {
1192                            block_indicators = true;
1193                        }
1194                    }
1195                    '-' if followed_by_whitespace => {
1196                        flow_indicators = true;
1197                        block_indicators = true;
1198                    }
1199                    _ => {}
1200                }
1201            } else {
1202                match ch {
1203                    ',' | '?' | '[' | ']' | '{' | '}' => {
1204                        flow_indicators = true;
1205                    }
1206                    ':' => {
1207                        flow_indicators = true;
1208                        if followed_by_whitespace {
1209                            block_indicators = true;
1210                        }
1211                    }
1212                    '#' if preceded_by_whitespace => {
1213                        flow_indicators = true;
1214                        block_indicators = true;
1215                    }
1216                    _ => {}
1217                }
1218            }
1219
1220            if !is_printable(ch) || !is_ascii(ch) && !self.unicode {
1221                special_characters = true;
1222            }
1223            if is_break(ch) {
1224                line_breaks = true;
1225            }
1226
1227            if is_space(ch) {
1228                if first {
1229                    leading_space = true;
1230                }
1231                if next.is_none() {
1232                    trailing_space = true;
1233                }
1234                if previous_break {
1235                    break_space = true;
1236                }
1237                previous_space = true;
1238                previous_break = false;
1239            } else if is_break(ch) {
1240                if first {
1241                    leading_break = true;
1242                }
1243                if next.is_none() {
1244                    trailing_break = true;
1245                }
1246                if previous_space {
1247                    space_break = true;
1248                }
1249                previous_space = false;
1250                previous_break = true;
1251            } else {
1252                previous_space = false;
1253                previous_break = false;
1254            }
1255
1256            preceded_by_whitespace = is_blankz(ch);
1257            first = false;
1258        }
1259
1260        let mut analysis = ScalarAnalysis {
1261            value,
1262            multiline: line_breaks,
1263            flow_plain_allowed: true,
1264            block_plain_allowed: true,
1265            single_quoted_allowed: true,
1266            block_allowed: true,
1267            style: ScalarStyle::Any,
1268        };
1269
1270        analysis.multiline = line_breaks;
1271        analysis.flow_plain_allowed = true;
1272        analysis.block_plain_allowed = true;
1273        analysis.single_quoted_allowed = true;
1274        analysis.block_allowed = true;
1275        if leading_space || leading_break || trailing_space || trailing_break {
1276            analysis.flow_plain_allowed = false;
1277            analysis.block_plain_allowed = false;
1278        }
1279        if trailing_space {
1280            analysis.block_allowed = false;
1281        }
1282        if break_space {
1283            analysis.flow_plain_allowed = false;
1284            analysis.block_plain_allowed = false;
1285            analysis.single_quoted_allowed = false;
1286        }
1287        if space_break || special_characters {
1288            analysis.flow_plain_allowed = false;
1289            analysis.block_plain_allowed = false;
1290            analysis.single_quoted_allowed = false;
1291            analysis.block_allowed = false;
1292        }
1293        if line_breaks {
1294            analysis.flow_plain_allowed = false;
1295            analysis.block_plain_allowed = false;
1296        }
1297        if flow_indicators {
1298            analysis.flow_plain_allowed = false;
1299        }
1300        if block_indicators {
1301            analysis.block_plain_allowed = false;
1302        }
1303        Ok(analysis)
1304    }
1305
1306    fn analyze_event<'a>(
1307        &mut self,
1308        event: &'a Event,
1309        tag_directives: &'a [TagDirective],
1310    ) -> Result<Analysis<'a>> {
1311        let mut analysis = Analysis::default();
1312
1313        match &event.data {
1314            EventData::Alias { anchor } => {
1315                analysis.anchor = Some(Self::analyze_anchor(anchor, true)?);
1316            }
1317            EventData::Scalar {
1318                anchor,
1319                tag,
1320                value,
1321                plain_implicit,
1322                quoted_implicit,
1323                ..
1324            } => {
1325                let (plain_implicit, quoted_implicit) = (*plain_implicit, *quoted_implicit);
1326                if let Some(anchor) = anchor {
1327                    analysis.anchor = Some(Self::analyze_anchor(anchor, false)?);
1328                }
1329                if tag.is_some() && (self.canonical || !plain_implicit && !quoted_implicit) {
1330                    analysis.tag =
1331                        Some(Self::analyze_tag(tag.as_deref().unwrap(), tag_directives)?);
1332                }
1333                analysis.scalar = Some(self.analyze_scalar(value)?);
1334            }
1335            EventData::SequenceStart {
1336                anchor,
1337                tag,
1338                implicit,
1339                ..
1340            }
1341            | EventData::MappingStart {
1342                anchor,
1343                tag,
1344                implicit,
1345                ..
1346            } => {
1347                if let Some(anchor) = anchor {
1348                    analysis.anchor = Some(Self::analyze_anchor(anchor, false)?);
1349                }
1350                if tag.is_some() && (self.canonical || !*implicit) {
1351                    analysis.tag =
1352                        Some(Self::analyze_tag(tag.as_deref().unwrap(), tag_directives)?);
1353                }
1354            }
1355            _ => {}
1356        }
1357
1358        Ok(analysis)
1359    }
1360
1361    fn write_bom(&mut self) -> Result<()> {
1362        self.flush_if_needed()?;
1363        self.buffer.push('\u{feff}');
1364        Ok(())
1365    }
1366
1367    fn write_indent(&mut self) -> Result<()> {
1368        let indent = if self.indent >= 0 { self.indent } else { 0 };
1369        if !self.indention || self.column > indent || self.column == indent && !self.whitespace {
1370            self.put_break()?;
1371        }
1372        while self.column < indent {
1373            self.put(' ')?;
1374        }
1375        self.whitespace = true;
1376        self.indention = true;
1377        Ok(())
1378    }
1379
1380    fn write_indicator(
1381        &mut self,
1382        indicator: &str,
1383        need_whitespace: bool,
1384        is_whitespace: bool,
1385        is_indention: bool,
1386    ) -> Result<()> {
1387        if need_whitespace && !self.whitespace {
1388            self.put(' ')?;
1389        }
1390        self.write_str(indicator)?;
1391        self.whitespace = is_whitespace;
1392        self.indention = self.indention && is_indention;
1393        Ok(())
1394    }
1395
1396    fn write_anchor(&mut self, value: &str) -> Result<()> {
1397        self.write_str(value)?;
1398        self.whitespace = false;
1399        self.indention = false;
1400        Ok(())
1401    }
1402
1403    fn write_tag_handle(&mut self, value: &str) -> Result<()> {
1404        if !self.whitespace {
1405            self.put(' ')?;
1406        }
1407        self.write_str(value)?;
1408        self.whitespace = false;
1409        self.indention = false;
1410        Ok(())
1411    }
1412
1413    fn write_tag_content(&mut self, value: &str, need_whitespace: bool) -> Result<()> {
1414        if need_whitespace && !self.whitespace {
1415            self.put(' ')?;
1416        }
1417
1418        for ch in value.chars() {
1419            if is_alpha(ch) {
1420                self.write_char(ch)?;
1421                continue;
1422            }
1423
1424            match ch {
1425                ';' | '/' | '?' | ':' | '@' | '&' | '=' | '+' | '$' | ',' | '_' | '.' | '~'
1426                | '*' | '\'' | '(' | ')' | '[' | ']' => {
1427                    self.write_char(ch)?;
1428                    continue;
1429                }
1430                _ => {}
1431            }
1432
1433            // URI escape
1434            let mut encode_buffer = [0u8; 4];
1435            let encoded_char = ch.encode_utf8(&mut encode_buffer);
1436            for value in encoded_char.bytes() {
1437                let upper = char::from_digit(value as u32 >> 4, 16)
1438                    .expect("invalid digit")
1439                    .to_ascii_uppercase();
1440                let lower = char::from_digit(value as u32 & 0x0F, 16)
1441                    .expect("invalid digit")
1442                    .to_ascii_uppercase();
1443                self.put('%')?;
1444                self.put(upper)?;
1445                self.put(lower)?;
1446            }
1447        }
1448
1449        self.whitespace = false;
1450        self.indention = false;
1451        Ok(())
1452    }
1453
1454    fn write_plain_scalar(&mut self, value: &str, allow_breaks: bool) -> Result<()> {
1455        let mut spaces = false;
1456        let mut breaks = false;
1457        if !self.whitespace && (!value.is_empty() || self.flow_level != 0) {
1458            self.put(' ')?;
1459        }
1460
1461        let mut chars = value.chars();
1462
1463        while let Some(ch) = chars.next() {
1464            let next = chars.clone().next();
1465            if is_space(ch) {
1466                if allow_breaks && !spaces && self.column > self.best_width && !is_space(next) {
1467                    self.write_indent()?;
1468                } else {
1469                    self.write_char(ch)?;
1470                }
1471                spaces = true;
1472            } else if is_break(ch) {
1473                if !breaks && ch == '\n' {
1474                    self.put_break()?;
1475                }
1476                self.write_break(ch)?;
1477                self.indention = true;
1478                breaks = true;
1479            } else {
1480                if breaks {
1481                    self.write_indent()?;
1482                }
1483                self.write_char(ch)?;
1484                self.indention = false;
1485                spaces = false;
1486                breaks = false;
1487            }
1488        }
1489        self.whitespace = false;
1490        self.indention = false;
1491        Ok(())
1492    }
1493
1494    fn write_single_quoted_scalar(&mut self, value: &str, allow_breaks: bool) -> Result<()> {
1495        let mut spaces = false;
1496        let mut breaks = false;
1497        self.write_indicator("'", true, false, false)?;
1498        let mut chars = value.chars();
1499        let mut is_first = true;
1500        while let Some(ch) = chars.next() {
1501            let next = chars.clone().next();
1502            let is_last = next.is_none();
1503
1504            if is_space(ch) {
1505                if allow_breaks
1506                    && !spaces
1507                    && self.column > self.best_width
1508                    && !is_first
1509                    && !is_last
1510                    && !is_space(next)
1511                {
1512                    self.write_indent()?;
1513                } else {
1514                    self.write_char(ch)?;
1515                }
1516                spaces = true;
1517            } else if is_break(ch) {
1518                if !breaks && ch == '\n' {
1519                    self.put_break()?;
1520                }
1521                self.write_break(ch)?;
1522                self.indention = true;
1523                breaks = true;
1524            } else {
1525                if breaks {
1526                    self.write_indent()?;
1527                }
1528                if ch == '\'' {
1529                    self.put('\'')?;
1530                }
1531                self.write_char(ch)?;
1532                self.indention = false;
1533                spaces = false;
1534                breaks = false;
1535            }
1536
1537            is_first = false;
1538        }
1539        if breaks {
1540            self.write_indent()?;
1541        }
1542        self.write_indicator("'", false, false, false)?;
1543        self.whitespace = false;
1544        self.indention = false;
1545        Ok(())
1546    }
1547
1548    fn write_double_quoted_scalar(&mut self, value: &str, allow_breaks: bool) -> Result<()> {
1549        let mut spaces = false;
1550        self.write_indicator("\"", true, false, false)?;
1551        let mut chars = value.chars();
1552        let mut first = true;
1553        while let Some(ch) = chars.next() {
1554            if !is_printable(ch)
1555                || !self.unicode && !is_ascii(ch)
1556                || is_bom(ch)
1557                || is_break(ch)
1558                || ch == '"'
1559                || ch == '\\'
1560            {
1561                self.put('\\')?;
1562                match ch {
1563                    // TODO: Double check these character mappings.
1564                    '\0' => {
1565                        self.put('0')?;
1566                    }
1567                    '\x07' => {
1568                        self.put('a')?;
1569                    }
1570                    '\x08' => {
1571                        self.put('b')?;
1572                    }
1573                    '\x09' => {
1574                        self.put('t')?;
1575                    }
1576                    '\x0A' => {
1577                        self.put('n')?;
1578                    }
1579                    '\x0B' => {
1580                        self.put('v')?;
1581                    }
1582                    '\x0C' => {
1583                        self.put('f')?;
1584                    }
1585                    '\x0D' => {
1586                        self.put('r')?;
1587                    }
1588                    '\x1B' => {
1589                        self.put('e')?;
1590                    }
1591                    '\x22' => {
1592                        self.put('"')?;
1593                    }
1594                    '\x5C' => {
1595                        self.put('\\')?;
1596                    }
1597                    '\u{0085}' => {
1598                        self.put('N')?;
1599                    }
1600                    '\u{00A0}' => {
1601                        self.put('_')?;
1602                    }
1603                    '\u{2028}' => {
1604                        self.put('L')?;
1605                    }
1606                    '\u{2029}' => {
1607                        self.put('P')?;
1608                    }
1609                    _ => {
1610                        let (prefix, width) = if ch <= '\u{00ff}' {
1611                            ('x', 2)
1612                        } else if ch <= '\u{ffff}' {
1613                            ('u', 4)
1614                        } else {
1615                            ('U', 8)
1616                        };
1617                        self.put(prefix)?;
1618                        let mut k = (width - 1) * 4;
1619                        let value_0 = ch as u32;
1620                        while k >= 0 {
1621                            let digit = (value_0 >> k) & 0x0F;
1622                            let digit_char = match char::from_digit(digit, 16) {
1623                                Some(digit_char) => digit_char,
1624                                None => unreachable!("digit out of range"),
1625                            };
1626                            // The libyaml emitter encodes unicode sequences as uppercase hex.
1627                            let digit_char = digit_char.to_ascii_uppercase();
1628                            self.put(digit_char)?;
1629                            k -= 4;
1630                        }
1631                    }
1632                }
1633                spaces = false;
1634            } else if is_space(ch) {
1635                if allow_breaks
1636                    && !spaces
1637                    && self.column > self.best_width
1638                    && !first
1639                    && chars.clone().next().is_some()
1640                {
1641                    self.write_indent()?;
1642                    if is_space(chars.clone().next()) {
1643                        self.put('\\')?;
1644                    }
1645                } else {
1646                    self.write_char(ch)?;
1647                }
1648                spaces = true;
1649            } else {
1650                self.write_char(ch)?;
1651                spaces = false;
1652            }
1653
1654            first = false;
1655        }
1656        self.write_indicator("\"", false, false, false)?;
1657        self.whitespace = false;
1658        self.indention = false;
1659        Ok(())
1660    }
1661
1662    fn write_block_scalar_hints(&mut self, string: &str) -> Result<()> {
1663        let mut chomp_hint: Option<&str> = None;
1664
1665        let first = string.chars().next();
1666        if is_space(first) || is_break(first) {
1667            let indent_hint = match char::from_digit(self.best_indent as u32, 10) {
1668                Some(indent_hint) => indent_hint,
1669                None => unreachable!("self.best_indent out of range"),
1670            };
1671            let mut indent_hint_buffer = [0u8; 1];
1672            let indent_hint = indent_hint.encode_utf8(&mut indent_hint_buffer);
1673            self.write_indicator(indent_hint, false, false, false)?;
1674        }
1675        self.open_ended = 0;
1676
1677        if string.is_empty() {
1678            chomp_hint = Some("-");
1679        } else {
1680            let mut chars_rev = string.chars().rev();
1681            let ch = chars_rev.next();
1682            let next = chars_rev.next();
1683
1684            if !is_break(ch) {
1685                chomp_hint = Some("-");
1686            } else if is_breakz(next) {
1687                chomp_hint = Some("+");
1688                self.open_ended = 2;
1689            }
1690        }
1691
1692        if let Some(chomp_hint) = chomp_hint {
1693            self.write_indicator(chomp_hint, false, false, false)?;
1694        }
1695        Ok(())
1696    }
1697
1698    fn write_literal_scalar(&mut self, value: &str) -> Result<()> {
1699        let mut breaks = true;
1700        self.write_indicator("|", true, false, false)?;
1701        self.write_block_scalar_hints(value)?;
1702        self.put_break()?;
1703        self.indention = true;
1704        self.whitespace = true;
1705        let chars = value.chars();
1706        for ch in chars {
1707            if is_break(ch) {
1708                self.write_break(ch)?;
1709                self.indention = true;
1710                breaks = true;
1711            } else {
1712                if breaks {
1713                    self.write_indent()?;
1714                }
1715                self.write_char(ch)?;
1716                self.indention = false;
1717                breaks = false;
1718            }
1719        }
1720        Ok(())
1721    }
1722
1723    fn write_folded_scalar(&mut self, value: &str) -> Result<()> {
1724        let mut breaks = true;
1725        let mut leading_spaces = true;
1726        self.write_indicator(">", true, false, false)?;
1727        self.write_block_scalar_hints(value)?;
1728        self.put_break()?;
1729        self.indention = true;
1730        self.whitespace = true;
1731
1732        let mut chars = value.chars();
1733
1734        while let Some(ch) = chars.next() {
1735            if is_break(ch) {
1736                if !breaks && !leading_spaces && ch == '\n' {
1737                    let mut skip_breaks = chars.clone();
1738                    while is_break(skip_breaks.next()) {}
1739                    if !is_blankz(skip_breaks.next()) {
1740                        self.put_break()?;
1741                    }
1742                }
1743                self.write_break(ch)?;
1744                self.indention = true;
1745                breaks = true;
1746            } else {
1747                if breaks {
1748                    self.write_indent()?;
1749                    leading_spaces = is_blank(ch);
1750                }
1751                if !breaks
1752                    && is_space(ch)
1753                    && !is_space(chars.clone().next())
1754                    && self.column > self.best_width
1755                {
1756                    self.write_indent()?;
1757                } else {
1758                    self.write_char(ch)?;
1759                }
1760                self.indention = false;
1761                breaks = false;
1762            }
1763        }
1764        Ok(())
1765    }
1766
1767    /// Flush the accumulated characters to the output.
1768    pub fn flush(&mut self) -> Result<()> {
1769        assert!((self.write_handler).is_some());
1770        assert_ne!(self.encoding, Encoding::Any);
1771
1772        if self.buffer.is_empty() {
1773            return Ok(());
1774        }
1775
1776        if self.encoding == Encoding::Utf8 {
1777            let to_emit = self.buffer.as_bytes();
1778            self.write_handler
1779                .as_mut()
1780                .expect("non-null writer")
1781                .write_all(to_emit)?;
1782            self.buffer.clear();
1783            return Ok(());
1784        }
1785
1786        let big_endian = match self.encoding {
1787            Encoding::Any | Encoding::Utf8 => {
1788                unreachable!("unhandled encoding")
1789            }
1790            Encoding::Utf16Le => false,
1791            Encoding::Utf16Be => true,
1792        };
1793
1794        for ch in self.buffer.encode_utf16() {
1795            let bytes = if big_endian {
1796                ch.to_be_bytes()
1797            } else {
1798                ch.to_le_bytes()
1799            };
1800            self.raw_buffer.extend(bytes);
1801        }
1802
1803        let to_emit = self.raw_buffer.as_slice();
1804
1805        self.write_handler
1806            .as_mut()
1807            .expect("non-null function pointer")
1808            .write_all(to_emit)?;
1809        self.buffer.clear();
1810        self.raw_buffer.clear();
1811        Ok(())
1812    }
1813
1814    pub(crate) fn reset_anchors(&mut self) {
1815        self.anchors.clear();
1816        self.last_anchor_id = 0;
1817    }
1818
1819    pub(crate) fn anchor_node_sub(&mut self, index: i32) {
1820        self.anchors[index as usize - 1].references += 1;
1821        if self.anchors[index as usize - 1].references == 2 {
1822            self.last_anchor_id += 1;
1823            self.anchors[index as usize - 1].anchor = self.last_anchor_id;
1824        }
1825    }
1826
1827    pub(crate) fn generate_anchor(anchor_id: i32) -> String {
1828        alloc::format!("id{anchor_id:03}")
1829    }
1830}