swimos_form/structural/read/recognizer/
mod.rs

1// Copyright 2015-2024 Swim Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::structural::bridge::RecognizerBridge;
16use crate::structural::generic::coproduct::{CCons, CNil, Unify};
17use crate::structural::read::error::ExpectedEvent;
18use crate::structural::read::event::ReadEvent;
19use crate::structural::read::from_model::{
20    AttrBodyMaterializer, DelegateBodyMaterializer, ValueMaterializer,
21};
22use crate::structural::read::recognizer::primitive::DataRecognizer;
23use crate::structural::read::ReadError;
24use crate::structural::write::StructuralWritable;
25use crate::structural::Tag;
26use std::borrow::Borrow;
27use std::marker::PhantomData;
28use std::num::NonZeroUsize;
29use std::option::Option::None;
30use std::sync::Arc;
31use swimos_model::{BigInt, BigUint};
32use swimos_model::{Blob, Text, Value, ValueKind};
33
34/// [`Recognizer`] implementations for config types.
35mod impls;
36/// [`Recognizer`] implementations for basic types.
37mod primitive;
38#[cfg(test)]
39mod tests;
40
41/// Trait for types that can be recognized by a [`Recognizer`] state machine.
42pub trait RecognizerReadable: Sized {
43    type Rec: Recognizer<Target = Self>;
44    type AttrRec: Recognizer<Target = Self>;
45    type BodyRec: Recognizer<Target = Self>;
46
47    /// Create a state machine that will recognize the representation of the type as a stream of
48    /// [`ReadEvent`]s.
49    fn make_recognizer() -> Self::Rec;
50
51    /// Create a state machine that will recognize the representation of the type as a stream of
52    /// [`ReadEvent`]s from the body of an attribute. (In most cases this will be identical
53    /// to the `make_recognizer` state machine, followed by an end attribute event. However,
54    /// for types that can be represented as records with no attributes, this may be more complex
55    /// as it is permissible for the record to be collapsed into the body of the attribute.)
56    fn make_attr_recognizer() -> Self::AttrRec;
57
58    /// Create a state machine that will recognize the representation of the type as a stream of
59    /// [`ReadEvent`]s where the read process has been delegated to a sub-value. This will
60    /// be identical to the `make_recognizer` state machine save where the type is simple or
61    /// is the generic model type [`Value`].
62    fn make_body_recognizer() -> Self::BodyRec;
63
64    /// If this value is expected as the value of a record field but was not present a default
65    /// value will be used if provided here. For example, [`Option`] values are set to `None` if
66    /// not provided.
67    fn on_absent() -> Option<Self> {
68        None
69    }
70
71    /// A value is simple if it can be represented by a single [`ReadEvent`].
72    fn is_simple() -> bool {
73        false
74    }
75
76    /// Attempt to write a value of a ['StructuralWritable'] type into an instance of this type.
77    fn try_read_from<T: StructuralWritable>(writable: &T) -> Result<Self, ReadError> {
78        let bridge = RecognizerBridge::new(Self::make_recognizer());
79        writable.write_with(bridge)
80    }
81
82    /// Attempt to transform a value of a ['StructuralWritable'] type into an instance of this type.
83    fn try_transform<T: StructuralWritable>(writable: T) -> Result<Self, ReadError> {
84        let bridge = RecognizerBridge::new(Self::make_recognizer());
85        writable.write_into(bridge)
86    }
87
88    /// Attempt to create an instance of thist type from a [`Value`] model.
89    fn try_interpret_structure(value: &Value) -> Result<Self, ReadError> {
90        Self::try_read_from(value)
91    }
92
93    /// Attempt to create an instance of thist type from a [`Value`] model, possibly consuming
94    /// the model.
95    fn try_from_structure(value: Value) -> Result<Self, ReadError> {
96        Self::try_transform(value)
97    }
98}
99
100/// Trait for state machines that can recognize a type from a stream of [`ReadEvent`]s. A
101/// recognizer maybe be used multiple times but the `reset` method must be called between each
102/// use.
103pub trait Recognizer {
104    /// The type that is produced by the state machine.
105    type Target;
106
107    /// Feed a single event into the state machine. The result will return nothing if more
108    /// events are required. Otherwise it will return the completed value or an error if the
109    /// event provided was invalid for the type.
110    fn feed_event(&mut self, input: ReadEvent<'_>) -> Option<Result<Self::Target, ReadError>>;
111
112    /// Attempt the produce a value based on the events that have already been provided, if possible.
113    fn try_flush(&mut self) -> Option<Result<Self::Target, ReadError>> {
114        None
115    }
116
117    /// Reset the state machine so that it can be used again.
118    fn reset(&mut self);
119}
120
121macro_rules! simple_readable {
122    ($target:ty, $recog:ident) => {
123        impl RecognizerReadable for $target {
124            type Rec = primitive::$recog;
125            type AttrRec = SimpleAttrBody<primitive::$recog>;
126            type BodyRec = SimpleRecBody<primitive::$recog>;
127
128            fn make_recognizer() -> Self::Rec {
129                primitive::$recog
130            }
131
132            fn make_attr_recognizer() -> Self::AttrRec {
133                SimpleAttrBody::new(primitive::$recog)
134            }
135
136            fn make_body_recognizer() -> Self::BodyRec {
137                SimpleRecBody::new(primitive::$recog)
138            }
139
140            fn is_simple() -> bool {
141                true
142            }
143        }
144    };
145}
146
147simple_readable!((), UnitRecognizer);
148simple_readable!(i32, I32Recognizer);
149simple_readable!(i64, I64Recognizer);
150simple_readable!(u32, U32Recognizer);
151simple_readable!(u64, U64Recognizer);
152simple_readable!(usize, UsizeRecognizer);
153simple_readable!(NonZeroUsize, NonZeroUsizeRecognizer);
154simple_readable!(f64, F64Recognizer);
155simple_readable!(BigInt, BigIntRecognizer);
156simple_readable!(BigUint, BigUintRecognizer);
157simple_readable!(String, StringRecognizer);
158simple_readable!(Text, TextRecognizer);
159simple_readable!(Vec<u8>, DataRecognizer);
160simple_readable!(bool, BoolRecognizer);
161
162impl RecognizerReadable for Blob {
163    type Rec = MappedRecognizer<DataRecognizer, fn(Vec<u8>) -> Blob>;
164    type AttrRec = SimpleAttrBody<Self::Rec>;
165    type BodyRec = SimpleRecBody<Self::Rec>;
166
167    fn make_recognizer() -> Self::Rec {
168        MappedRecognizer::new(DataRecognizer, Blob::from_vec)
169    }
170
171    fn make_attr_recognizer() -> Self::AttrRec {
172        SimpleAttrBody::new(Self::make_recognizer())
173    }
174
175    fn make_body_recognizer() -> Self::BodyRec {
176        SimpleRecBody::new(Self::make_recognizer())
177    }
178
179    fn is_simple() -> bool {
180        true
181    }
182}
183
184type BoxU8Vec = fn(Vec<u8>) -> Box<[u8]>;
185
186impl RecognizerReadable for Box<[u8]> {
187    type Rec = MappedRecognizer<DataRecognizer, BoxU8Vec>;
188    type AttrRec = SimpleAttrBody<Self::Rec>;
189    type BodyRec = SimpleRecBody<Self::Rec>;
190
191    fn make_recognizer() -> Self::Rec {
192        MappedRecognizer::new(DataRecognizer, Vec::into_boxed_slice)
193    }
194
195    fn make_attr_recognizer() -> Self::AttrRec {
196        SimpleAttrBody::new(Self::make_recognizer())
197    }
198
199    fn make_body_recognizer() -> Self::BodyRec {
200        SimpleRecBody::new(Self::make_recognizer())
201    }
202
203    fn is_simple() -> bool {
204        true
205    }
206}
207
208type Selector<Flds> = for<'a> fn(&mut Flds, u32, ReadEvent<'a>) -> Option<Result<(), ReadError>>;
209
210struct Bitset(u32, u64);
211
212impl Bitset {
213    fn new(cap: u32) -> Self {
214        Bitset(cap, 0)
215    }
216
217    fn set(&mut self, index: u32) {
218        let Bitset(cap, bits) = self;
219        if index <= *cap {
220            *bits |= 1 << index
221        }
222    }
223
224    fn get(&self, index: u32) -> Option<bool> {
225        let Bitset(cap, bits) = self;
226        if index <= *cap {
227            Some((*bits >> index) & 0x1 != 0)
228        } else {
229            None
230        }
231    }
232
233    fn clear(&mut self) {
234        self.1 = 0
235    }
236}
237
238enum BodyFieldState {
239    Init,
240    Between,
241    ExpectingSlot,
242    SlotValue,
243}
244
245/// A [`Recognizer`] that can be configured to recognize any type that can be represented as a
246/// record consisting of named fields. The `Flds` type is the state of the state machine that
247/// stores the value for each named field as it is encountered in the output. Another function is then
248/// called to transform this state into the final result.
249#[doc(hidden)]
250pub struct NamedFieldsRecognizer<T, Flds> {
251    is_attr_body: bool,
252    state: BodyFieldState,
253    fields: Flds,
254    progress: Bitset,
255    select_index: fn(&str) -> Option<u32>,
256    index: u32,
257    select_recog: Selector<Flds>,
258    on_done: fn(&mut Flds) -> Result<T, ReadError>,
259    reset: fn(&mut Flds),
260}
261
262impl<T, Flds> NamedFieldsRecognizer<T, Flds> {
263    /// Configure a recognizer.
264    ///
265    /// # Arguments
266    ///
267    /// * `fields` - The state for the state machine.
268    /// * `select_index` - Map the field names of the type to integer indicies.
269    /// * `num_fields` - The total number of named fields in the representation.
270    /// * `select_recog` - Attempt to update the state with the next read event.
271    /// * `on_done` - Called when the recognizer is complete to convert the state to the output type.
272    /// * `reset` - Called to reset the state to its initial value.
273    pub fn new(
274        fields: Flds,
275        select_index: fn(&str) -> Option<u32>,
276        num_fields: u32,
277        select_recog: Selector<Flds>,
278        on_done: fn(&mut Flds) -> Result<T, ReadError>,
279        reset: fn(&mut Flds),
280    ) -> Self {
281        NamedFieldsRecognizer {
282            is_attr_body: false,
283            state: BodyFieldState::Init,
284            fields,
285            progress: Bitset::new(num_fields),
286            select_index,
287            index: 0,
288            select_recog,
289            on_done,
290            reset,
291        }
292    }
293
294    /// Configure a recognizer for the type unpacked into an attribute body.
295    ///
296    /// # Arguments
297    ///
298    /// * `fields` - The state for the state machine.
299    /// * `select_index` - Map the field names of the type to integer indicies.
300    /// * `num_fields` - The total number of named fields in the representation.
301    /// * `select_recog` - Attempt to update the state with the next read event.
302    /// * `on_done` - Called when the recognizer is complete to convert the state to the output type.
303    /// * `reset` - Called to reset the state to its initial value.
304    pub fn new_attr(
305        fields: Flds,
306        select_index: fn(&str) -> Option<u32>,
307        num_fields: u32,
308        select_recog: Selector<Flds>,
309        on_done: fn(&mut Flds) -> Result<T, ReadError>,
310        reset: fn(&mut Flds),
311    ) -> Self {
312        NamedFieldsRecognizer {
313            is_attr_body: true,
314            state: BodyFieldState::Between,
315            fields,
316            progress: Bitset::new(num_fields),
317            select_index,
318            index: 0,
319            select_recog,
320            on_done,
321            reset,
322        }
323    }
324}
325
326impl<T, Flds> Recognizer for NamedFieldsRecognizer<T, Flds> {
327    type Target = T;
328
329    fn feed_event(&mut self, input: ReadEvent<'_>) -> Option<Result<Self::Target, ReadError>> {
330        let NamedFieldsRecognizer {
331            is_attr_body,
332            state,
333            fields,
334            progress,
335            select_index,
336            index,
337            select_recog,
338            on_done,
339            ..
340        } = self;
341        match state {
342            BodyFieldState::Init => {
343                if matches!(input, ReadEvent::StartBody) {
344                    *state = BodyFieldState::Between;
345                    None
346                } else {
347                    Some(Err(input.kind_error(ExpectedEvent::RecordBody)))
348                }
349            }
350            BodyFieldState::Between => match input {
351                ReadEvent::EndRecord if !*is_attr_body => Some(on_done(fields)),
352                ReadEvent::EndAttribute if *is_attr_body => Some(on_done(fields)),
353                ReadEvent::TextValue(name) => {
354                    if let Some(i) = select_index(name.borrow()) {
355                        if progress.get(i).unwrap_or(false) {
356                            Some(Err(ReadError::DuplicateField(Text::from(name))))
357                        } else {
358                            *index = i;
359                            *state = BodyFieldState::ExpectingSlot;
360                            None
361                        }
362                    } else {
363                        Some(Err(ReadError::UnexpectedSlot))
364                    }
365                }
366                ow => {
367                    let mut expected = vec![];
368                    if *is_attr_body {
369                        expected.push(ExpectedEvent::EndOfAttribute);
370                    } else {
371                        expected.push(ExpectedEvent::EndOfRecord);
372                    }
373                    expected.push(ExpectedEvent::ValueEvent(ValueKind::Text));
374                    Some(Err(ow.kind_error(ExpectedEvent::Or(expected))))
375                }
376            },
377            BodyFieldState::ExpectingSlot => {
378                if matches!(input, ReadEvent::Slot) {
379                    *state = BodyFieldState::SlotValue;
380                    None
381                } else {
382                    Some(Err(ReadError::unexpected_kind(
383                        ValueKind::Text,
384                        Some(ExpectedEvent::Slot),
385                    )))
386                }
387            }
388            BodyFieldState::SlotValue => {
389                let r = select_recog(fields, *index, input)?;
390                if let Err(e) = r {
391                    Some(Err(e))
392                } else {
393                    progress.set(*index);
394                    *state = BodyFieldState::Between;
395                    None
396                }
397            }
398        }
399    }
400
401    fn reset(&mut self) {
402        self.progress.clear();
403        self.state = BodyFieldState::Init;
404        (self.reset)(&mut self.fields)
405    }
406}
407
408#[derive(Debug, Clone, Copy)]
409enum BodyStage {
410    Init,
411    Item,
412    Between,
413}
414
415/// A [`Recognizer`] that can be configured to recognize any type that can be represented as a
416/// record consisting of a tuple of values. The `Flds` type is the state of the state machine that
417/// stores the value for each named field as it is encountered in the output. Another function is then
418/// called to transform this state into the final result.
419#[doc(hidden)]
420pub struct OrdinalFieldsRecognizer<T, Flds> {
421    is_attr_body: bool,
422    state: BodyStage,
423    fields: Flds,
424    num_fields: u32,
425    index: u32,
426    select_recog: Selector<Flds>,
427    on_done: fn(&mut Flds) -> Result<T, ReadError>,
428    reset: fn(&mut Flds),
429}
430
431impl<T, Flds> OrdinalFieldsRecognizer<T, Flds> {
432    /// Configure a recognizer.
433    ///
434    /// # Arguments
435    ///
436    /// * `fields` - The state for the state machine.
437    /// * `num_fields` - The total number of named fields in the representation.
438    /// * `select_recog` - Attempt to update the state with the next read event.
439    /// * `on_done` - Called when the recognizer is complete to convert the state to the output type.
440    /// * `reset` - Called to reset the state to its initial value.
441    pub fn new(
442        fields: Flds,
443        num_fields: u32,
444        select_recog: Selector<Flds>,
445        on_done: fn(&mut Flds) -> Result<T, ReadError>,
446        reset: fn(&mut Flds),
447    ) -> Self {
448        OrdinalFieldsRecognizer {
449            is_attr_body: false,
450            state: BodyStage::Init,
451            fields,
452            num_fields,
453            index: 0,
454            select_recog,
455            on_done,
456            reset,
457        }
458    }
459
460    /// Configure a recognizer for the type unpacked into an attribute body.
461    ///
462    /// # Arguments
463    ///
464    /// * `fields` - The state for the state machine.
465    /// * `num_fields` - The total number of named fields in the representation.
466    /// * `select_recog` - Attempt to update the state with the next read event.
467    /// * `on_done` - Called when the recognizer is complete to convert the state to the output type.
468    /// * `reset` - Called to reset the state to its initial value.
469    pub fn new_attr(
470        fields: Flds,
471        num_fields: u32,
472        select_recog: Selector<Flds>,
473        on_done: fn(&mut Flds) -> Result<T, ReadError>,
474        reset: fn(&mut Flds),
475    ) -> Self {
476        OrdinalFieldsRecognizer {
477            is_attr_body: true,
478            state: BodyStage::Between,
479            fields,
480            num_fields,
481            index: 0,
482            select_recog,
483            on_done,
484            reset,
485        }
486    }
487}
488
489impl<T, Flds> Recognizer for OrdinalFieldsRecognizer<T, Flds> {
490    type Target = T;
491
492    fn feed_event(&mut self, input: ReadEvent<'_>) -> Option<Result<Self::Target, ReadError>> {
493        let OrdinalFieldsRecognizer {
494            is_attr_body,
495            state,
496            fields,
497            num_fields,
498            index,
499            select_recog,
500            on_done,
501            ..
502        } = self;
503        if matches!(state, BodyStage::Init) {
504            if matches!(input, ReadEvent::StartBody) {
505                *state = BodyStage::Between;
506                None
507            } else {
508                Some(Err(input.kind_error(ExpectedEvent::RecordBody)))
509            }
510        } else if matches!(state, BodyStage::Between)
511            && ((!*is_attr_body && matches!(&input, ReadEvent::EndRecord))
512                || (*is_attr_body && matches!(&input, ReadEvent::EndAttribute)))
513        {
514            Some(on_done(fields))
515        } else if *index == *num_fields {
516            Some(Err(ReadError::UnexpectedItem))
517        } else {
518            *state = BodyStage::Item;
519            let r = select_recog(fields, *index, input)?;
520            if let Err(e) = r {
521                Some(Err(e))
522            } else {
523                *index += 1;
524                *state = BodyStage::Between;
525                None
526            }
527        }
528    }
529
530    fn reset(&mut self) {
531        self.index = 0;
532        self.state = BodyStage::Init;
533        (self.reset)(&mut self.fields)
534    }
535}
536
537/// Wraps another [`Recognizer`] to recognize the same type as an attribute body (terminated by
538/// a final end attribute event).
539#[doc(hidden)]
540#[derive(Debug)]
541pub struct SimpleAttrBody<R: Recognizer> {
542    after_content: bool,
543    value: Option<R::Target>,
544    delegate: R,
545}
546
547impl<R: Recognizer> SimpleAttrBody<R> {
548    pub fn new(rec: R) -> Self {
549        SimpleAttrBody {
550            after_content: false,
551            value: None,
552            delegate: rec,
553        }
554    }
555}
556
557impl<R: Recognizer> Recognizer for SimpleAttrBody<R> {
558    type Target = R::Target;
559
560    fn feed_event(&mut self, input: ReadEvent<'_>) -> Option<Result<Self::Target, ReadError>> {
561        if self.after_content {
562            if matches!(&input, ReadEvent::EndAttribute) {
563                if let Some(t) = self.value.take() {
564                    Some(Ok(t))
565                } else {
566                    Some(Err(ReadError::IncompleteRecord))
567                }
568            } else {
569                Some(Err(input.kind_error(ExpectedEvent::EndOfAttribute)))
570            }
571        } else {
572            let r = self.delegate.feed_event(input)?;
573            self.after_content = true;
574            match r {
575                Ok(t) => {
576                    self.value = Some(t);
577                    None
578                }
579                Err(e) => Some(Err(e)),
580            }
581        }
582    }
583
584    fn reset(&mut self) {
585        self.after_content = false;
586        self.value = None;
587        self.delegate.reset();
588    }
589}
590
591/// Runs two [`Recognizer`]s in parallel returning the result of the first that completes
592/// successfully. If both complete with an error, the error from the recognizer that failed
593/// last is returned.
594#[doc(hidden)]
595#[derive(Debug)]
596pub struct FirstOf<R1, R2> {
597    first_active: bool,
598    second_active: bool,
599    recognizer1: R1,
600    recognizer2: R2,
601}
602
603impl<R1, R2> FirstOf<R1, R2>
604where
605    R1: Recognizer,
606    R2: Recognizer<Target = R1::Target>,
607{
608    pub fn new(recognizer1: R1, recognizer2: R2) -> Self {
609        FirstOf {
610            first_active: true,
611            second_active: true,
612            recognizer1,
613            recognizer2,
614        }
615    }
616}
617
618impl<R1, R2> Recognizer for FirstOf<R1, R2>
619where
620    R1: Recognizer,
621    R2: Recognizer<Target = R1::Target>,
622{
623    type Target = R1::Target;
624
625    fn feed_event(&mut self, input: ReadEvent<'_>) -> Option<Result<Self::Target, ReadError>> {
626        let FirstOf {
627            first_active,
628            second_active,
629            recognizer1,
630            recognizer2,
631        } = self;
632        if *first_active && *second_active {
633            match recognizer1.feed_event(input.clone()) {
634                r @ Some(Ok(_)) => {
635                    *first_active = false;
636                    *second_active = false;
637                    return r;
638                }
639                Some(Err(_)) => {
640                    *first_active = false;
641                }
642                _ => {}
643            }
644            match recognizer2.feed_event(input) {
645                r @ Some(Ok(_)) => {
646                    *first_active = false;
647                    *second_active = false;
648                    r
649                }
650                r @ Some(Err(_)) => {
651                    *second_active = false;
652                    if *first_active {
653                        None
654                    } else {
655                        r
656                    }
657                }
658                _ => None,
659            }
660        } else if *first_active {
661            let r = recognizer1.feed_event(input)?;
662            *first_active = false;
663            Some(r)
664        } else if *second_active {
665            let r = recognizer2.feed_event(input)?;
666            *second_active = false;
667            Some(r)
668        } else {
669            Some(Err(ReadError::InconsistentState))
670        }
671    }
672
673    fn reset(&mut self) {
674        self.first_active = true;
675        self.second_active = true;
676        self.recognizer1.reset();
677        self.recognizer2.reset();
678    }
679}
680
681/// A key to specify the field that has been encountered in the stream of events when reading
682/// a type with labelled body fields.
683#[doc(hidden)]
684#[derive(Clone, Copy)]
685pub enum LabelledFieldKey<'a> {
686    /// The name of the tag when this is used to populate a field.
687    Tag,
688    Header,
689    /// Another attribute after the tag.
690    Attr(&'a str),
691    /// A labelled slot in the body of the record.
692    Item(&'a str),
693}
694
695#[derive(Clone, Copy)]
696enum LabelledStructState {
697    Init,
698    Header,
699    NoHeader,
700    AttrBetween,
701    AttrItem,
702    BodyBetween,
703    BodyExpectingSlot,
704    BodyItem,
705}
706
707#[derive(Clone, Copy)]
708enum OrdinalStructState {
709    Init,
710    Header,
711    NoHeader,
712    AttrBetween,
713    AttrItem,
714    BodyBetween,
715    BodyItem,
716}
717
718/// A key to specify the field that has been encountered in the stream of events when reading
719/// a type with un-labelled body fields.
720#[derive(Clone, Copy)]
721#[doc(hidden)]
722pub enum OrdinalFieldKey<'a> {
723    /// The name of the tag when this is used to populate a field.
724    Tag,
725    Header,
726    /// Another attribute after the tag.
727    Attr(&'a str),
728    /// The first field in the body of the record. All other body fields are assumed to ocurr
729    /// sequentially after the first.
730    FirstItem,
731}
732
733/// Specifies whether the tag attribute for a record is expected to be a fixed string or should
734/// be used to populate one of the fields.
735#[doc(hidden)]
736pub enum TagSpec {
737    Fixed(&'static str),
738    Field,
739}
740
741/// This type is used to encode the standard encoding of Rust structs, with labelled fields, as
742/// generated by the derivation macro for [`RecognizerReadable`]. It should not generally be
743/// necessary to use this type explicitly.
744#[doc(hidden)]
745pub struct LabelledStructRecognizer<T, Flds> {
746    tag: TagSpec,
747    state: LabelledStructState,
748    fields: Flds,
749    progress: Bitset,
750    index: u32,
751    vtable: LabelledVTable<T, Flds>,
752}
753
754/// The derivation macro produces the functions that are used to populate this table to provide
755/// the specific parts of the implementation.
756#[doc(hidden)]
757pub struct LabelledVTable<T, Flds> {
758    select_index: for<'a> fn(LabelledFieldKey<'a>) -> Option<u32>,
759    select_recog: Selector<Flds>,
760    on_done: fn(&mut Flds) -> Result<T, ReadError>,
761    reset: fn(&mut Flds),
762}
763
764impl<T, Flds> LabelledVTable<T, Flds> {
765    pub fn new(
766        select_index: for<'a> fn(LabelledFieldKey<'a>) -> Option<u32>,
767        select_recog: Selector<Flds>,
768        on_done: fn(&mut Flds) -> Result<T, ReadError>,
769        reset: fn(&mut Flds),
770    ) -> Self {
771        LabelledVTable {
772            select_index,
773            select_recog,
774            on_done,
775            reset,
776        }
777    }
778}
779
780/// The derivation macro produces the functions that are used to populate this table to provide
781/// the specific parts of the implementation.
782#[doc(hidden)]
783pub struct OrdinalVTable<T, Flds> {
784    select_index: for<'a> fn(OrdinalFieldKey<'a>) -> Option<u32>,
785    select_recog: Selector<Flds>,
786    on_done: fn(&mut Flds) -> Result<T, ReadError>,
787    reset: fn(&mut Flds),
788}
789
790impl<T, Flds> OrdinalVTable<T, Flds> {
791    pub fn new(
792        select_index: for<'a> fn(OrdinalFieldKey<'a>) -> Option<u32>,
793        select_recog: Selector<Flds>,
794        on_done: fn(&mut Flds) -> Result<T, ReadError>,
795        reset: fn(&mut Flds),
796    ) -> Self {
797        OrdinalVTable {
798            select_index,
799            select_recog,
800            on_done,
801            reset,
802        }
803    }
804}
805
806impl<T, Flds> LabelledStructRecognizer<T, Flds> {
807    /// # Arguments
808    /// * `tag` - The expected name of the first attribute or an indication that it should be used
809    ///   to populate a field.
810    /// * `fields` - The state of the recognizer state machine (specified by the macro).
811    /// * `num_fields` - The total numer of (non-skipped) fields that the recognizer expects.
812    /// * `vtable` - Functions that are generated by the macro that determine how incoming events
813    ///   modify the state.
814    pub fn new(
815        tag: TagSpec,
816        fields: Flds,
817        num_fields: u32,
818        vtable: LabelledVTable<T, Flds>,
819    ) -> Self {
820        LabelledStructRecognizer {
821            tag,
822            state: LabelledStructState::Init,
823            fields,
824            progress: Bitset::new(num_fields),
825            index: 0,
826            vtable,
827        }
828    }
829
830    /// This constructor is used for enumeration variants. The primary different is that the tag
831    /// of the record has already been read before this recognizers is called so the initial state
832    /// is skipped.
833    ///
834    /// # Arguments
835    /// * `fields` - The state of the recognizer state machine (specified by the macro).
836    /// * `num_fields` - The total numer of (non-skipped) fields that the recognizer expects.
837    /// * `vtable` - Functions that are generated by the macro that determine how incoming events
838    ///   modify the state.
839    pub fn variant(fields: Flds, num_fields: u32, vtable: LabelledVTable<T, Flds>) -> Self {
840        let (state, index) = if let Some(i) = (vtable.select_index)(LabelledFieldKey::Header) {
841            (LabelledStructState::Header, i)
842        } else {
843            (LabelledStructState::NoHeader, 0)
844        };
845        LabelledStructRecognizer {
846            tag: TagSpec::Fixed(""),
847            state,
848            fields,
849            progress: Bitset::new(num_fields),
850            index,
851            vtable,
852        }
853    }
854}
855
856impl<T, Flds> OrdinalStructRecognizer<T, Flds> {
857    /// # Arguments
858    /// * `tag` - The expected name of the first attribute or an inidcation that it should be used
859    ///   to populate a field.
860    /// * `fields` - The state of the recognizer state machine (specified by the macro).
861    /// * `num_fields` - The total numer of (non-skipped) fields that the recognizer expects.
862    /// * `vtable` - Functions that are generated by the macro that determine how incoming events
863    ///   modify the state.
864    pub fn new(
865        tag: TagSpec,
866        fields: Flds,
867        num_fields: u32,
868        vtable: OrdinalVTable<T, Flds>,
869    ) -> Self {
870        OrdinalStructRecognizer {
871            tag,
872            state: OrdinalStructState::Init,
873            fields,
874            progress: Bitset::new(num_fields),
875            index: 0,
876            vtable,
877        }
878    }
879
880    /// This constructor is used for enumeration variants. The primary different is that the tag
881    /// of the record has already been read before this recognizers is called so the initial state
882    /// is skipped.
883    ///
884    /// # Arguments
885    /// * `fields` - The state of the recognizer state machine (specified by the macro).
886    /// * `num_fields` - The total numer of (non-skipped) fields that the recognizer expects.
887    /// * `vtable` - Functions that are generated by the macro that determine how incoming events
888    ///   modify the state.
889    pub fn variant(fields: Flds, num_fields: u32, vtable: OrdinalVTable<T, Flds>) -> Self {
890        let (state, index) = if let Some(i) = (vtable.select_index)(OrdinalFieldKey::Header) {
891            (OrdinalStructState::Header, i)
892        } else {
893            (OrdinalStructState::NoHeader, 0)
894        };
895        OrdinalStructRecognizer {
896            tag: TagSpec::Fixed(""),
897            state,
898            fields,
899            progress: Bitset::new(num_fields),
900            index,
901            vtable,
902        }
903    }
904}
905
906impl<T, Flds> Recognizer for LabelledStructRecognizer<T, Flds> {
907    type Target = T;
908
909    fn feed_event(&mut self, input: ReadEvent<'_>) -> Option<Result<Self::Target, ReadError>> {
910        let LabelledStructRecognizer {
911            tag,
912            state,
913            fields,
914            progress,
915            index,
916            vtable:
917                LabelledVTable {
918                    select_index,
919                    select_recog,
920                    on_done,
921                    ..
922                },
923            ..
924        } = self;
925
926        match state {
927            LabelledStructState::Init => match input {
928                ReadEvent::StartAttribute(name) => match tag {
929                    TagSpec::Fixed(tag) => {
930                        if name == *tag {
931                            if let Some(i) = select_index(LabelledFieldKey::Header) {
932                                *index = i;
933                                *state = LabelledStructState::Header;
934                            } else {
935                                *state = LabelledStructState::NoHeader;
936                            }
937                            None
938                        } else {
939                            Some(Err(ReadError::UnexpectedAttribute(name.into())))
940                        }
941                    }
942                    TagSpec::Field => {
943                        if let Some(i) = select_index(LabelledFieldKey::Tag) {
944                            if let Err(e) = select_recog(fields, i, ReadEvent::TextValue(name))? {
945                                Some(Err(e))
946                            } else {
947                                if let Some(i) = select_index(LabelledFieldKey::Header) {
948                                    *index = i;
949                                    *state = LabelledStructState::Header;
950                                } else {
951                                    *state = LabelledStructState::NoHeader;
952                                }
953                                None
954                            }
955                        } else {
956                            Some(Err(ReadError::InconsistentState))
957                        }
958                    }
959                },
960                ow => {
961                    let name = if let TagSpec::Fixed(name) = tag {
962                        Some(Text::new(name))
963                    } else {
964                        None
965                    };
966                    Some(Err(ow.kind_error(ExpectedEvent::Attribute(name))))
967                }
968            },
969            LabelledStructState::Header => {
970                if let Err(e) = select_recog(fields, *index, input)? {
971                    Some(Err(e))
972                } else {
973                    *state = LabelledStructState::AttrBetween;
974                    None
975                }
976            }
977            LabelledStructState::NoHeader => match input {
978                ReadEvent::Extant => None,
979                ReadEvent::EndAttribute => {
980                    *state = LabelledStructState::AttrBetween;
981                    None
982                }
983                ow => Some(Err(ow.kind_error(ExpectedEvent::EndOfAttribute))),
984            },
985            LabelledStructState::AttrBetween => match input {
986                ReadEvent::StartBody => {
987                    *state = LabelledStructState::BodyBetween;
988                    None
989                }
990                ReadEvent::StartAttribute(name) => {
991                    if let Some(i) = select_index(LabelledFieldKey::Attr(name.borrow())) {
992                        if progress.get(i).unwrap_or(false) {
993                            Some(Err(ReadError::DuplicateField(Text::new(name.borrow()))))
994                        } else {
995                            *index = i;
996                            *state = LabelledStructState::AttrItem;
997                            None
998                        }
999                    } else {
1000                        Some(Err(ReadError::UnexpectedField(name.into())))
1001                    }
1002                }
1003                ow => Some(Err(ow.kind_error(ExpectedEvent::Or(vec![
1004                    ExpectedEvent::RecordBody,
1005                    ExpectedEvent::Attribute(None),
1006                ])))),
1007            },
1008            LabelledStructState::AttrItem => {
1009                if let Err(e) = select_recog(fields, *index, input)? {
1010                    Some(Err(e))
1011                } else {
1012                    progress.set(*index);
1013                    *state = LabelledStructState::AttrBetween;
1014                    None
1015                }
1016            }
1017            LabelledStructState::BodyBetween => match input {
1018                ReadEvent::EndRecord => Some(on_done(fields)),
1019                ReadEvent::TextValue(name) => {
1020                    if let Some(i) = select_index(LabelledFieldKey::Item(name.borrow())) {
1021                        if progress.get(i).unwrap_or(false) {
1022                            Some(Err(ReadError::DuplicateField(Text::new(name.borrow()))))
1023                        } else {
1024                            *index = i;
1025                            *state = LabelledStructState::BodyExpectingSlot;
1026                            None
1027                        }
1028                    } else {
1029                        Some(Err(ReadError::UnexpectedField(name.into())))
1030                    }
1031                }
1032                ow => Some(Err(ow.kind_error(ExpectedEvent::Or(vec![
1033                    ExpectedEvent::EndOfRecord,
1034                    ExpectedEvent::ValueEvent(ValueKind::Text),
1035                ])))),
1036            },
1037            LabelledStructState::BodyExpectingSlot => {
1038                if matches!(&input, ReadEvent::Slot) {
1039                    *state = LabelledStructState::BodyItem;
1040                    None
1041                } else {
1042                    Some(Err(input.kind_error(ExpectedEvent::Slot)))
1043                }
1044            }
1045            LabelledStructState::BodyItem => {
1046                if let Err(e) = select_recog(fields, *index, input)? {
1047                    Some(Err(e))
1048                } else {
1049                    progress.set(*index);
1050                    *state = LabelledStructState::BodyBetween;
1051                    None
1052                }
1053            }
1054        }
1055    }
1056
1057    fn reset(&mut self) {
1058        self.state = LabelledStructState::Init;
1059        self.progress.clear();
1060        self.index = 0;
1061        (self.vtable.reset)(&mut self.fields);
1062    }
1063}
1064
1065/// This type is used to encode the standard encoding of Rust structs, with unlabelled fields, as
1066/// generated by the derivation macro for [`RecognizerReadable`]. It should not generally be
1067/// necessary to use this type explicitly.
1068#[doc(hidden)]
1069pub struct OrdinalStructRecognizer<T, Flds> {
1070    tag: TagSpec,
1071    state: OrdinalStructState,
1072    fields: Flds,
1073    progress: Bitset,
1074    index: u32,
1075    vtable: OrdinalVTable<T, Flds>,
1076}
1077
1078impl<T, Flds> Recognizer for OrdinalStructRecognizer<T, Flds> {
1079    type Target = T;
1080
1081    fn feed_event(&mut self, input: ReadEvent<'_>) -> Option<Result<Self::Target, ReadError>> {
1082        let OrdinalStructRecognizer {
1083            tag,
1084            state,
1085            fields,
1086            progress,
1087            index,
1088            vtable:
1089                OrdinalVTable {
1090                    select_index,
1091                    select_recog,
1092                    on_done,
1093                    ..
1094                },
1095            ..
1096        } = self;
1097
1098        match state {
1099            OrdinalStructState::Init => match input {
1100                ReadEvent::StartAttribute(name) => match tag {
1101                    TagSpec::Fixed(tag) => {
1102                        if name == *tag {
1103                            if let Some(i) = select_index(OrdinalFieldKey::Header) {
1104                                *index = i;
1105                                *state = OrdinalStructState::Header;
1106                            } else {
1107                                *state = OrdinalStructState::NoHeader;
1108                            }
1109                            None
1110                        } else {
1111                            Some(Err(ReadError::UnexpectedAttribute(name.into())))
1112                        }
1113                    }
1114                    TagSpec::Field => {
1115                        if let Some(i) = select_index(OrdinalFieldKey::Tag) {
1116                            if let Err(e) = select_recog(fields, i, ReadEvent::TextValue(name))? {
1117                                Some(Err(e))
1118                            } else {
1119                                if let Some(i) = select_index(OrdinalFieldKey::Header) {
1120                                    *index = i;
1121                                    *state = OrdinalStructState::Header;
1122                                } else {
1123                                    *state = OrdinalStructState::NoHeader;
1124                                }
1125                                None
1126                            }
1127                        } else {
1128                            Some(Err(ReadError::InconsistentState))
1129                        }
1130                    }
1131                },
1132                ow => {
1133                    let name = if let TagSpec::Fixed(name) = tag {
1134                        Some(Text::new(name))
1135                    } else {
1136                        None
1137                    };
1138                    Some(Err(ow.kind_error(ExpectedEvent::Attribute(name))))
1139                }
1140            },
1141            OrdinalStructState::Header => {
1142                if let Err(e) = select_recog(fields, *index, input)? {
1143                    Some(Err(e))
1144                } else {
1145                    *state = OrdinalStructState::AttrBetween;
1146                    None
1147                }
1148            }
1149            OrdinalStructState::NoHeader => match input {
1150                ReadEvent::Extant => None,
1151                ReadEvent::EndAttribute => {
1152                    *state = OrdinalStructState::AttrBetween;
1153                    None
1154                }
1155                ow => Some(Err(ow.kind_error(ExpectedEvent::EndOfAttribute))),
1156            },
1157            OrdinalStructState::AttrBetween => match &input {
1158                ReadEvent::StartBody => {
1159                    *state = OrdinalStructState::BodyBetween;
1160                    if let Some(i) = select_index(OrdinalFieldKey::FirstItem) {
1161                        *index = i;
1162                    }
1163                    None
1164                }
1165                ReadEvent::StartAttribute(name) => {
1166                    if let Some(i) = select_index(OrdinalFieldKey::Attr(name.borrow())) {
1167                        if progress.get(i).unwrap_or(false) {
1168                            Some(Err(ReadError::DuplicateField(Text::new(name.borrow()))))
1169                        } else {
1170                            *index = i;
1171                            *state = OrdinalStructState::AttrItem;
1172                            None
1173                        }
1174                    } else {
1175                        Some(Err(ReadError::UnexpectedField(Text::new(name.borrow()))))
1176                    }
1177                }
1178                _ => Some(Err(input.kind_error(ExpectedEvent::Or(vec![
1179                    ExpectedEvent::RecordBody,
1180                    ExpectedEvent::Attribute(None),
1181                ])))),
1182            },
1183            OrdinalStructState::AttrItem => {
1184                if let Err(e) = select_recog(fields, *index, input)? {
1185                    Some(Err(e))
1186                } else {
1187                    progress.set(*index);
1188                    *state = OrdinalStructState::AttrBetween;
1189                    None
1190                }
1191            }
1192            OrdinalStructState::BodyBetween => match &input {
1193                ReadEvent::EndRecord => Some(on_done(fields)),
1194                _ => {
1195                    *state = OrdinalStructState::BodyItem;
1196                    if let Err(e) = select_recog(fields, *index, input)? {
1197                        Some(Err(e))
1198                    } else {
1199                        progress.set(*index);
1200                        *index += 1;
1201                        *state = OrdinalStructState::BodyBetween;
1202                        None
1203                    }
1204                }
1205            },
1206            OrdinalStructState::BodyItem => {
1207                if let Err(e) = select_recog(fields, *index, input)? {
1208                    Some(Err(e))
1209                } else {
1210                    progress.set(*index);
1211                    *index += 1;
1212                    *state = OrdinalStructState::BodyBetween;
1213                    None
1214                }
1215            }
1216        }
1217    }
1218
1219    fn reset(&mut self) {
1220        self.state = OrdinalStructState::Init;
1221        self.progress.clear();
1222        self.index = 0;
1223        (self.vtable.reset)(&mut self.fields);
1224    }
1225}
1226
1227/// This type is used to encode the newtype encoding of Rust structs, with labelled fields, as
1228/// generated by the derivation macro for [`RecognizerReadable`]. It should not generally be
1229/// necessary to use this type explicitly.
1230#[doc(hidden)]
1231pub struct LabelledNewtypeRecognizer<T, Flds> {
1232    fields: Flds,
1233    vtable: LabelledVTable<T, Flds>,
1234}
1235
1236impl<T, Flds> LabelledNewtypeRecognizer<T, Flds> {
1237    /// # Arguments
1238    /// * `fields` - The state of the recognizer state machine (specified by the macro).
1239    /// * `vtable` - Functions that are generated by the macro that determine how incoming events
1240    ///   modify the state.
1241    pub fn new(fields: Flds, vtable: LabelledVTable<T, Flds>) -> Self {
1242        LabelledNewtypeRecognizer { fields, vtable }
1243    }
1244}
1245
1246impl<T, Flds> Recognizer for LabelledNewtypeRecognizer<T, Flds> {
1247    type Target = T;
1248
1249    fn feed_event(&mut self, input: ReadEvent<'_>) -> Option<Result<Self::Target, ReadError>> {
1250        let LabelledNewtypeRecognizer {
1251            fields,
1252            vtable:
1253                LabelledVTable {
1254                    select_recog,
1255                    on_done,
1256                    ..
1257                },
1258        } = self;
1259
1260        if let Err(e) = select_recog(fields, 0, input)? {
1261            Some(Err(e))
1262        } else {
1263            Some(on_done(fields))
1264        }
1265    }
1266
1267    fn reset(&mut self) {
1268        (self.vtable.reset)(&mut self.fields);
1269    }
1270}
1271
1272/// This type is used to encode the newtype encoding of Rust structs, with unlabelled fields, as
1273/// generated by the derivation macro for [`RecognizerReadable`]. It should not generally be
1274/// necessary to use this type explicitly.
1275#[doc(hidden)]
1276pub struct OrdinalNewtypeRecognizer<T, Flds> {
1277    fields: Flds,
1278    vtable: OrdinalVTable<T, Flds>,
1279}
1280
1281impl<T, Flds> OrdinalNewtypeRecognizer<T, Flds> {
1282    /// # Arguments
1283    /// * `fields` - The state of the recognizer state machine (specified by the macro).
1284    /// * `vtable` - Functions that are generated by the macro that determine how incoming events
1285    ///   modify the state.
1286    pub fn new(fields: Flds, vtable: OrdinalVTable<T, Flds>) -> Self {
1287        OrdinalNewtypeRecognizer { fields, vtable }
1288    }
1289}
1290
1291impl<T, Flds> Recognizer for OrdinalNewtypeRecognizer<T, Flds> {
1292    type Target = T;
1293
1294    fn feed_event(&mut self, input: ReadEvent<'_>) -> Option<Result<Self::Target, ReadError>> {
1295        let OrdinalNewtypeRecognizer {
1296            fields,
1297            vtable:
1298                OrdinalVTable {
1299                    select_recog,
1300                    on_done,
1301                    ..
1302                },
1303        } = self;
1304
1305        if let Err(e) = select_recog(fields, 0, input)? {
1306            Some(Err(e))
1307        } else {
1308            Some(on_done(fields))
1309        }
1310    }
1311
1312    fn reset(&mut self) {
1313        (self.vtable.reset)(&mut self.fields);
1314    }
1315}
1316
1317type MakeArc<T> = fn(T) -> Arc<T>;
1318
1319impl<T: RecognizerReadable> RecognizerReadable for Arc<T> {
1320    type Rec = MappedRecognizer<T::Rec, MakeArc<T>>;
1321    type AttrRec = MappedRecognizer<T::AttrRec, MakeArc<T>>;
1322    type BodyRec = MappedRecognizer<T::BodyRec, MakeArc<T>>;
1323
1324    fn make_recognizer() -> Self::Rec {
1325        MappedRecognizer::new(T::make_recognizer(), Arc::new)
1326    }
1327
1328    fn make_attr_recognizer() -> Self::AttrRec {
1329        MappedRecognizer::new(T::make_attr_recognizer(), Arc::new)
1330    }
1331
1332    fn make_body_recognizer() -> Self::BodyRec {
1333        MappedRecognizer::new(T::make_body_recognizer(), Arc::new)
1334    }
1335
1336    fn on_absent() -> Option<Self> {
1337        T::on_absent().map(Arc::new)
1338    }
1339
1340    fn is_simple() -> bool {
1341        T::is_simple()
1342    }
1343}
1344
1345/// Runs another recognizer and then transforms its result by applying a function to it.
1346pub struct MappedRecognizer<R, F> {
1347    inner: R,
1348    f: F,
1349}
1350
1351impl<R, F> MappedRecognizer<R, F> {
1352    pub fn new(inner: R, f: F) -> Self {
1353        MappedRecognizer { inner, f }
1354    }
1355}
1356
1357impl<U, R, F> Recognizer for MappedRecognizer<R, F>
1358where
1359    R: Recognizer,
1360    F: Fn(R::Target) -> U,
1361{
1362    type Target = U;
1363
1364    fn feed_event(&mut self, input: ReadEvent<'_>) -> Option<Result<Self::Target, ReadError>> {
1365        let MappedRecognizer { inner, f, .. } = self;
1366        inner.feed_event(input).map(|r| r.map(f))
1367    }
1368
1369    fn try_flush(&mut self) -> Option<Result<Self::Target, ReadError>> {
1370        let MappedRecognizer { inner, f } = self;
1371        inner.try_flush().map(|r| r.map(f))
1372    }
1373
1374    fn reset(&mut self) {
1375        self.inner.reset()
1376    }
1377}
1378
1379impl RecognizerReadable for Value {
1380    type Rec = ValueMaterializer;
1381    type AttrRec = AttrBodyMaterializer;
1382    type BodyRec = DelegateBodyMaterializer;
1383
1384    fn make_recognizer() -> Self::Rec {
1385        ValueMaterializer::default()
1386    }
1387
1388    fn make_attr_recognizer() -> Self::AttrRec {
1389        AttrBodyMaterializer::default()
1390    }
1391
1392    fn make_body_recognizer() -> Self::BodyRec {
1393        DelegateBodyMaterializer::default()
1394    }
1395
1396    fn try_interpret_structure(value: &Value) -> Result<Self, ReadError> {
1397        Ok(value.clone())
1398    }
1399
1400    fn try_from_structure(value: Value) -> Result<Self, ReadError> {
1401        Ok(value)
1402    }
1403}
1404
1405#[doc(hidden)]
1406pub fn feed_field<R>(
1407    name: &'static str,
1408    field: &mut Option<R::Target>,
1409    recognizer: &mut R,
1410    event: ReadEvent<'_>,
1411) -> Option<Result<(), ReadError>>
1412where
1413    R: Recognizer,
1414{
1415    if field.is_some() {
1416        Some(Err(ReadError::DuplicateField(Text::new(name))))
1417    } else {
1418        match recognizer.feed_event(event) {
1419            Some(Ok(t)) => {
1420                *field = Some(t);
1421                Some(Ok(()))
1422            }
1423            Some(Err(e)) => Some(Err(e)),
1424            _ => None,
1425        }
1426    }
1427}
1428
1429#[derive(Clone, Copy)]
1430enum DelegateStructState {
1431    Init,
1432    Header,
1433    NoHeader,
1434    AttrBetween,
1435    AttrItem,
1436    Delegated,
1437}
1438
1439/// This type is used to encode the standard encoding of Rust structs, where the body of the record
1440/// is determined by one of the fields, generated by the derivation macro for
1441/// [`RecognizerReadable`]. It should not generally be necessary to use this type explicitly.
1442#[doc(hidden)]
1443pub struct DelegateStructRecognizer<T, Flds> {
1444    tag: TagSpec,
1445    state: DelegateStructState,
1446    fields: Flds,
1447    progress: Bitset,
1448    select_index: for<'a> fn(OrdinalFieldKey<'a>) -> Option<u32>,
1449    index: u32,
1450    select_recog: Selector<Flds>,
1451    on_done: fn(&mut Flds) -> Result<T, ReadError>,
1452    reset: fn(&mut Flds),
1453}
1454
1455impl<T, Flds> DelegateStructRecognizer<T, Flds> {
1456    /// # Arguments
1457    /// * `tag` - The expected name of the first attribute or an indication that it should be used
1458    ///   to populate a field.
1459    /// * `fields` - The state of the recognizer state machine (specified by the macro).
1460    /// * `num_fields` - The total numer of (non-skipped) fields that the recognizer expects.
1461    /// * `vtable` - Functions that are generated by the macro that determine how incoming events
1462    ///   modify the state.
1463    pub fn new(
1464        tag: TagSpec,
1465        fields: Flds,
1466        num_fields: u32,
1467        vtable: OrdinalVTable<T, Flds>,
1468    ) -> Self {
1469        DelegateStructRecognizer {
1470            tag,
1471            state: DelegateStructState::Init,
1472            fields,
1473            progress: Bitset::new(num_fields),
1474            select_index: vtable.select_index,
1475            index: 0,
1476            select_recog: vtable.select_recog,
1477            on_done: vtable.on_done,
1478            reset: vtable.reset,
1479        }
1480    }
1481
1482    /// This constructor is used for enumeration variants. The primary different is that the tag
1483    /// of the record has already been read before this recognizers is called so the initial state
1484    /// is skipped.
1485    ///
1486    /// # Arguments
1487    /// * `fields` - The state of the recognizer state machine (specified by the macro).
1488    /// * `num_fields` - The total numer of (non-skipped) fields that the recognizer expects.
1489    /// * `vtable` - Functions that are generated by the macro that determine how incoming events
1490    ///   modify the state.
1491    pub fn variant(fields: Flds, num_fields: u32, vtable: OrdinalVTable<T, Flds>) -> Self {
1492        let (state, index) = if let Some(i) = (vtable.select_index)(OrdinalFieldKey::Header) {
1493            (DelegateStructState::Header, i)
1494        } else {
1495            (DelegateStructState::NoHeader, 0)
1496        };
1497        DelegateStructRecognizer {
1498            tag: TagSpec::Fixed(""),
1499            state,
1500            fields,
1501            progress: Bitset::new(num_fields),
1502            select_index: vtable.select_index,
1503            index,
1504            select_recog: vtable.select_recog,
1505            on_done: vtable.on_done,
1506            reset: vtable.reset,
1507        }
1508    }
1509}
1510
1511impl<T, Flds> Recognizer for DelegateStructRecognizer<T, Flds> {
1512    type Target = T;
1513
1514    fn feed_event(&mut self, input: ReadEvent<'_>) -> Option<Result<Self::Target, ReadError>> {
1515        let DelegateStructRecognizer {
1516            tag,
1517            state,
1518            fields,
1519            progress,
1520            select_index,
1521            index,
1522            select_recog,
1523            on_done,
1524            ..
1525        } = self;
1526
1527        match state {
1528            DelegateStructState::Init => match input {
1529                ReadEvent::StartAttribute(name) => match tag {
1530                    TagSpec::Fixed(tag) => {
1531                        if name == *tag {
1532                            if let Some(i) = select_index(OrdinalFieldKey::Header) {
1533                                *index = i;
1534                                *state = DelegateStructState::Header;
1535                            } else {
1536                                *state = DelegateStructState::NoHeader;
1537                            }
1538                            None
1539                        } else {
1540                            Some(Err(ReadError::UnexpectedAttribute(name.into())))
1541                        }
1542                    }
1543                    TagSpec::Field => {
1544                        if let Some(i) = select_index(OrdinalFieldKey::Tag) {
1545                            if let Err(e) = select_recog(fields, i, ReadEvent::TextValue(name))? {
1546                                Some(Err(e))
1547                            } else {
1548                                if let Some(i) = select_index(OrdinalFieldKey::Header) {
1549                                    *index = i;
1550                                    *state = DelegateStructState::Header;
1551                                } else {
1552                                    *state = DelegateStructState::NoHeader;
1553                                }
1554                                None
1555                            }
1556                        } else {
1557                            Some(Err(ReadError::InconsistentState))
1558                        }
1559                    }
1560                },
1561                ow => {
1562                    let name = if let TagSpec::Fixed(name) = tag {
1563                        Some(Text::new(name))
1564                    } else {
1565                        None
1566                    };
1567                    Some(Err(ow.kind_error(ExpectedEvent::Attribute(name))))
1568                }
1569            },
1570            DelegateStructState::Header => {
1571                if let Err(e) = select_recog(fields, *index, input)? {
1572                    Some(Err(e))
1573                } else {
1574                    *state = DelegateStructState::AttrBetween;
1575                    None
1576                }
1577            }
1578            DelegateStructState::NoHeader => match input {
1579                ReadEvent::Extant => None,
1580                ReadEvent::EndAttribute => {
1581                    *state = DelegateStructState::AttrBetween;
1582                    None
1583                }
1584                ow => Some(Err(ow.kind_error(ExpectedEvent::EndOfAttribute))),
1585            },
1586            DelegateStructState::AttrBetween => match input {
1587                ReadEvent::StartBody => {
1588                    if let Some(i) = select_index(OrdinalFieldKey::FirstItem) {
1589                        *index = i;
1590                        *state = DelegateStructState::Delegated;
1591                        if let Err(e) = select_recog(fields, *index, ReadEvent::StartBody)? {
1592                            Some(Err(e))
1593                        } else {
1594                            Some(Err(ReadError::InconsistentState))
1595                        }
1596                    } else {
1597                        Some(Err(ReadError::InconsistentState))
1598                    }
1599                }
1600                ReadEvent::StartAttribute(name) => {
1601                    if let Some(i) = select_index(OrdinalFieldKey::Attr(name.borrow())) {
1602                        if progress.get(i).unwrap_or(false) {
1603                            Some(Err(ReadError::DuplicateField(Text::new(name.borrow()))))
1604                        } else {
1605                            *index = i;
1606                            *state = DelegateStructState::AttrItem;
1607                            None
1608                        }
1609                    } else if let Some(i) = select_index(OrdinalFieldKey::FirstItem) {
1610                        *index = i;
1611                        *state = DelegateStructState::Delegated;
1612                        if let Err(e) =
1613                            select_recog(fields, *index, ReadEvent::StartAttribute(name))?
1614                        {
1615                            Some(Err(e))
1616                        } else {
1617                            Some(Err(ReadError::InconsistentState))
1618                        }
1619                    } else {
1620                        Some(Err(ReadError::UnexpectedField(name.into())))
1621                    }
1622                }
1623                ow => Some(Err(ow.kind_error(ExpectedEvent::Or(vec![
1624                    ExpectedEvent::RecordBody,
1625                    ExpectedEvent::Attribute(None),
1626                ])))),
1627            },
1628            DelegateStructState::AttrItem => {
1629                if let Err(e) = select_recog(fields, *index, input)? {
1630                    Some(Err(e))
1631                } else {
1632                    progress.set(*index);
1633                    *state = DelegateStructState::AttrBetween;
1634                    None
1635                }
1636            }
1637            DelegateStructState::Delegated => {
1638                if let Err(e) = select_recog(fields, *index, input)? {
1639                    Some(Err(e))
1640                } else {
1641                    Some(on_done(fields))
1642                }
1643            }
1644        }
1645    }
1646
1647    fn reset(&mut self) {
1648        self.state = DelegateStructState::Init;
1649        self.progress.clear();
1650        self.index = 0;
1651        (self.reset)(&mut self.fields);
1652    }
1653}
1654
1655impl Recognizer for CNil {
1656    type Target = CNil;
1657
1658    fn feed_event(&mut self, _input: ReadEvent<'_>) -> Option<Result<Self::Target, ReadError>> {
1659        self.explode()
1660    }
1661
1662    fn reset(&mut self) {}
1663}
1664
1665impl<H, T> Recognizer for CCons<H, T>
1666where
1667    H: Recognizer,
1668    T: Recognizer,
1669{
1670    type Target = CCons<H::Target, T::Target>;
1671
1672    fn feed_event(&mut self, input: ReadEvent<'_>) -> Option<Result<Self::Target, ReadError>> {
1673        match self {
1674            CCons::Head(h) => h.feed_event(input).map(|r| r.map(CCons::Head)),
1675            CCons::Tail(t) => t.feed_event(input).map(|r| r.map(CCons::Tail)),
1676        }
1677    }
1678
1679    fn try_flush(&mut self) -> Option<Result<Self::Target, ReadError>> {
1680        match self {
1681            CCons::Head(h) => h.try_flush().map(|r| r.map(CCons::Head)),
1682            CCons::Tail(t) => t.try_flush().map(|r| r.map(CCons::Tail)),
1683        }
1684    }
1685
1686    fn reset(&mut self) {
1687        match self {
1688            CCons::Head(h) => h.reset(),
1689            CCons::Tail(t) => t.reset(),
1690        }
1691    }
1692}
1693
1694/// This type is used to encode the standard encoding of Rust enums, generated by the derivation
1695/// macro for [`RecognizerReadable`]. It should not generally be necessary to use this type
1696/// explicitly. The type parameter `Var` is the type of a recognizer that can recognizer any of
1697/// the variants of the enum.
1698#[doc(hidden)]
1699pub struct TaggedEnumRecognizer<Var> {
1700    select_var: fn(&str) -> Option<Var>,
1701    variant: Option<Var>,
1702}
1703
1704impl<Var> TaggedEnumRecognizer<Var> {
1705    /// # Arguments
1706    /// * `select_var` - A function that configures the wrapped recognizer to expect the
1707    ///   representation of the appropriate variant, based on the name of the tag attribute.
1708    pub fn new(select_var: fn(&str) -> Option<Var>) -> Self {
1709        TaggedEnumRecognizer {
1710            select_var,
1711            variant: None,
1712        }
1713    }
1714}
1715
1716impl<Var> Recognizer for TaggedEnumRecognizer<Var>
1717where
1718    Var: Recognizer,
1719    Var::Target: Unify,
1720{
1721    type Target = <<Var as Recognizer>::Target as Unify>::Out;
1722
1723    fn feed_event(&mut self, input: ReadEvent<'_>) -> Option<Result<Self::Target, ReadError>> {
1724        let TaggedEnumRecognizer {
1725            select_var,
1726            variant,
1727        } = self;
1728        match variant {
1729            None => match input {
1730                ReadEvent::StartAttribute(name) => {
1731                    *variant = select_var(name.borrow());
1732                    if variant.is_some() {
1733                        None
1734                    } else {
1735                        Some(Err(ReadError::UnexpectedAttribute(name.into())))
1736                    }
1737                }
1738                ow => Some(Err(ow.kind_error(ExpectedEvent::Attribute(None)))),
1739            },
1740            Some(var) => var.feed_event(input).map(|r| r.map(Unify::unify)),
1741        }
1742    }
1743
1744    fn reset(&mut self) {
1745        self.variant = None;
1746    }
1747}
1748
1749#[derive(Clone, Copy)]
1750enum UnitStructState {
1751    Init,
1752    Tag,
1753    SeenExtant,
1754    AfterTag,
1755    Body,
1756}
1757
1758/// Simple [`Recognizer`] for unit structs and enum variants. This is used by the derive macros
1759/// to avoid generating superfluous code in the degenerate case.
1760#[doc(hidden)]
1761pub struct UnitStructRecognizer<T> {
1762    tag: &'static str,
1763    state: UnitStructState,
1764    on_done: fn() -> T,
1765}
1766
1767impl<T> UnitStructRecognizer<T> {
1768    /// # Arguments
1769    /// * `tag` - The expected name of the tag attribute.
1770    /// * `on_done` - Factory to create an instance.
1771    pub fn new(tag: &'static str, on_done: fn() -> T) -> Self {
1772        UnitStructRecognizer {
1773            tag,
1774            state: UnitStructState::Init,
1775            on_done,
1776        }
1777    }
1778
1779    /// For an enum variant, the wrapping [`Recognizer`] will already have read the tag name.
1780    /// # Arguments
1781    /// * `on_done` - Factory to create an instance.
1782    pub fn variant(on_done: fn() -> T) -> Self {
1783        UnitStructRecognizer {
1784            tag: "",
1785            state: UnitStructState::Tag,
1786            on_done,
1787        }
1788    }
1789}
1790
1791impl<T> Recognizer for UnitStructRecognizer<T> {
1792    type Target = T;
1793
1794    fn feed_event(&mut self, input: ReadEvent<'_>) -> Option<Result<Self::Target, ReadError>> {
1795        let UnitStructRecognizer {
1796            tag,
1797            state,
1798            on_done,
1799        } = self;
1800        match *state {
1801            UnitStructState::Init => {
1802                if let ReadEvent::StartAttribute(name) = input {
1803                    if name == *tag {
1804                        *state = UnitStructState::Tag;
1805                        None
1806                    } else {
1807                        Some(Err(ReadError::UnexpectedAttribute(name.into())))
1808                    }
1809                } else {
1810                    Some(Err(
1811                        input.kind_error(ExpectedEvent::Attribute(Some(Text::new(tag))))
1812                    ))
1813                }
1814            }
1815            UnitStructState::Tag => match input {
1816                ReadEvent::Extant => {
1817                    *state = UnitStructState::SeenExtant;
1818                    None
1819                }
1820                ReadEvent::EndAttribute => {
1821                    *state = UnitStructState::AfterTag;
1822                    None
1823                }
1824                ow => Some(Err(ow.kind_error(ExpectedEvent::EndOfAttribute))),
1825            },
1826            UnitStructState::SeenExtant => {
1827                if matches!(&input, ReadEvent::EndAttribute) {
1828                    *state = UnitStructState::AfterTag;
1829                    None
1830                } else {
1831                    Some(Err(input.kind_error(ExpectedEvent::EndOfAttribute)))
1832                }
1833            }
1834            UnitStructState::AfterTag => {
1835                if matches!(&input, ReadEvent::StartBody) {
1836                    *state = UnitStructState::Body;
1837                    None
1838                } else {
1839                    Some(Err(input.kind_error(ExpectedEvent::RecordBody)))
1840                }
1841            }
1842            UnitStructState::Body => {
1843                if matches!(&input, ReadEvent::EndRecord) {
1844                    Some(Ok(on_done()))
1845                } else {
1846                    Some(Err(input.kind_error(ExpectedEvent::EndOfRecord)))
1847                }
1848            }
1849        }
1850    }
1851
1852    fn reset(&mut self) {
1853        self.state = UnitStructState::Init
1854    }
1855}
1856
1857/// A recognizer that always fails (used for uninhabited types).
1858#[doc(hidden)]
1859pub struct RecognizeNothing<T>(PhantomData<T>);
1860
1861impl<T> Default for RecognizeNothing<T> {
1862    fn default() -> Self {
1863        RecognizeNothing(PhantomData)
1864    }
1865}
1866
1867impl<T> Recognizer for RecognizeNothing<T> {
1868    type Target = T;
1869
1870    fn feed_event(&mut self, _input: ReadEvent<'_>) -> Option<Result<Self::Target, ReadError>> {
1871        Some(Err(ReadError::Message(
1872            format!("{} is uninhabited.", std::any::type_name::<T>()).into(),
1873        )))
1874    }
1875
1876    fn reset(&mut self) {}
1877}
1878
1879#[doc(hidden)]
1880pub struct TagRecognizer<T>(PhantomData<fn(&str) -> T>);
1881
1882impl<T: Tag> Default for TagRecognizer<T> {
1883    fn default() -> Self {
1884        TagRecognizer(PhantomData)
1885    }
1886}
1887
1888impl<T: Tag> Recognizer for TagRecognizer<T> {
1889    type Target = T;
1890
1891    fn feed_event(&mut self, input: ReadEvent<'_>) -> Option<Result<Self::Target, ReadError>> {
1892        let result = if let ReadEvent::TextValue(txt) = input {
1893            T::from_str(txt.borrow()).map_err(|message| ReadError::Malformatted {
1894                text: txt.into(),
1895                message,
1896            })
1897        } else {
1898            Err(input.kind_error(ExpectedEvent::ValueEvent(ValueKind::Text)))
1899        };
1900        Some(result)
1901    }
1902
1903    fn reset(&mut self) {}
1904}
1905
1906enum HeaderState {
1907    Init,
1908    ExpectingBody,
1909    BodyItem,
1910    BetweenSlots,
1911    ExpectingSlot,
1912    SlotItem,
1913    End,
1914}
1915
1916/// A key to specify the field that has been encountered in the stream of events when reading
1917/// a header of a record.
1918#[doc(hidden)]
1919#[derive(Clone, Copy)]
1920pub enum HeaderFieldKey<'a> {
1921    /// The first value inside the tag attribute.
1922    HeaderBody,
1923    /// A labelled slot in the tag attribute.
1924    HeaderSlot(&'a str),
1925}
1926
1927/// The derivation macro produces the functions that are used to populate this table to provide
1928/// the specific parts of the implementation.
1929#[doc(hidden)]
1930pub struct HeaderVTable<T, Flds> {
1931    select_index: for<'a> fn(HeaderFieldKey<'a>) -> Option<u32>,
1932    select_recog: Selector<Flds>,
1933    on_done: fn(&mut Flds) -> Result<T, ReadError>,
1934    reset: fn(&mut Flds),
1935}
1936
1937impl<T, Flds> HeaderVTable<T, Flds> {
1938    pub fn new(
1939        select_index: for<'a> fn(HeaderFieldKey<'a>) -> Option<u32>,
1940        select_recog: Selector<Flds>,
1941        on_done: fn(&mut Flds) -> Result<T, ReadError>,
1942        reset: fn(&mut Flds),
1943    ) -> Self {
1944        HeaderVTable {
1945            select_index,
1946            select_recog,
1947            on_done,
1948            reset,
1949        }
1950    }
1951}
1952
1953impl<T, Flds> Clone for HeaderVTable<T, Flds> {
1954    fn clone(&self) -> Self {
1955        *self
1956    }
1957}
1958
1959impl<T, Flds> Copy for HeaderVTable<T, Flds> {}
1960
1961/// This type is used to recognize the header for types which lift fields into it. It is used
1962/// by the derivation macro for [`RecognizerReadable`]. It should not generally be necessary to use
1963/// this type explicitly.
1964#[doc(hidden)]
1965pub struct HeaderRecognizer<T, Flds> {
1966    has_body: bool,
1967    flattened: bool,
1968    state: HeaderState,
1969    fields: Flds,
1970    progress: Bitset,
1971    index: u32,
1972    vtable: HeaderVTable<T, Flds>,
1973}
1974
1975/// Create a recognizer for the body of the header attribute of a record.
1976///
1977/// # Arguments
1978/// * `has_body` - Whether there is a field lifted to be the body of the header.
1979/// * `make_fields` - Factory to construct the state of the recognizer.
1980/// * `num_slots` - The number of slots lifted into the header.
1981/// * `vtable` - Functions that are generated by the macro that determine how incoming events
1982/// modify the state.
1983#[doc(hidden)]
1984pub fn header_recognizer<T, Flds, MkFlds>(
1985    has_body: bool,
1986    make_fields: MkFlds,
1987    num_slots: u32,
1988    vtable: HeaderVTable<T, Flds>,
1989) -> FirstOf<HeaderRecognizer<T, Flds>, HeaderRecognizer<T, Flds>>
1990where
1991    MkFlds: Fn() -> Flds,
1992{
1993    let simple = HeaderRecognizer::new(has_body, true, num_slots, make_fields(), vtable);
1994    let flattened = HeaderRecognizer::new(has_body, false, num_slots, make_fields(), vtable);
1995    FirstOf::new(simple, flattened)
1996}
1997
1998/// # Arguments
1999/// * `has_body` - Whether there is a field lifted to be the body of the header.
2000/// * `flattened` - Whether the record containing the fields has been flattened into the attribute
2001///   body (and so does not have explicit record body delimiting).
2002/// * `num_slots` - The number of slots lifted into the header.
2003/// * `fields` - The state of the recognizer.
2004/// * `vtable` - Functions that are generated by the macro that determine how incoming events
2005///   modify the state.
2006impl<T, Flds> HeaderRecognizer<T, Flds> {
2007    pub fn new(
2008        has_body: bool,
2009        flattened: bool,
2010        num_slots: u32,
2011        fields: Flds,
2012        vtable: HeaderVTable<T, Flds>,
2013    ) -> Self {
2014        let state = if flattened {
2015            if !has_body {
2016                HeaderState::BetweenSlots
2017            } else {
2018                HeaderState::ExpectingBody
2019            }
2020        } else {
2021            HeaderState::Init
2022        };
2023
2024        let num_fields = if !has_body { num_slots } else { num_slots + 1 };
2025
2026        HeaderRecognizer {
2027            has_body,
2028            flattened,
2029            state,
2030            fields,
2031            progress: Bitset::new(num_fields),
2032            index: 0,
2033            vtable,
2034        }
2035    }
2036}
2037
2038impl<T, Flds> Recognizer for HeaderRecognizer<T, Flds> {
2039    type Target = T;
2040
2041    fn feed_event(&mut self, input: ReadEvent<'_>) -> Option<Result<Self::Target, ReadError>> {
2042        let HeaderRecognizer {
2043            has_body,
2044            flattened,
2045            state,
2046            fields,
2047            progress,
2048            index,
2049            vtable:
2050                HeaderVTable {
2051                    select_index,
2052                    select_recog,
2053                    on_done,
2054                    ..
2055                },
2056        } = self;
2057        match *state {
2058            HeaderState::Init => {
2059                if matches!(&input, ReadEvent::StartBody) {
2060                    *state = if !*has_body {
2061                        HeaderState::BetweenSlots
2062                    } else {
2063                        HeaderState::ExpectingBody
2064                    };
2065                    None
2066                } else {
2067                    Some(Err(input.kind_error(ExpectedEvent::RecordBody)))
2068                }
2069            }
2070            HeaderState::ExpectingBody => {
2071                if *flattened && matches!(&input, ReadEvent::EndAttribute) {
2072                    Some(on_done(fields))
2073                } else if !*flattened && matches!(&input, ReadEvent::EndRecord) {
2074                    *state = HeaderState::End;
2075                    None
2076                } else if let Some(i) = select_index(HeaderFieldKey::HeaderBody) {
2077                    *index = i;
2078                    *state = HeaderState::BodyItem;
2079                    if let Err(e) = select_recog(fields, *index, input)? {
2080                        Some(Err(e))
2081                    } else {
2082                        *state = HeaderState::BetweenSlots;
2083                        progress.set(*index);
2084                        None
2085                    }
2086                } else {
2087                    Some(Err(ReadError::InconsistentState))
2088                }
2089            }
2090            HeaderState::BodyItem | HeaderState::SlotItem => {
2091                if let Err(e) = select_recog(fields, *index, input)? {
2092                    Some(Err(e))
2093                } else {
2094                    *state = HeaderState::BetweenSlots;
2095                    progress.set(*index);
2096                    None
2097                }
2098            }
2099            HeaderState::BetweenSlots => match input {
2100                ReadEvent::EndAttribute if *flattened => Some(on_done(fields)),
2101                ReadEvent::EndRecord if !*flattened => {
2102                    *state = HeaderState::End;
2103                    None
2104                }
2105                ReadEvent::TextValue(name) => {
2106                    if let Some(i) = select_index(HeaderFieldKey::HeaderSlot(name.borrow())) {
2107                        if progress.get(i).unwrap_or(false) {
2108                            Some(Err(ReadError::DuplicateField(Text::from(name))))
2109                        } else {
2110                            *index = i;
2111                            *state = HeaderState::ExpectingSlot;
2112                            None
2113                        }
2114                    } else {
2115                        Some(Err(ReadError::UnexpectedField(name.into())))
2116                    }
2117                }
2118                ow => {
2119                    let mut expected = vec![];
2120                    if *flattened {
2121                        expected.push(ExpectedEvent::EndOfAttribute);
2122                    } else {
2123                        expected.push(ExpectedEvent::EndOfRecord);
2124                    }
2125                    expected.push(ExpectedEvent::ValueEvent(ValueKind::Text));
2126                    Some(Err(ow.kind_error(ExpectedEvent::Or(expected))))
2127                }
2128            },
2129            HeaderState::ExpectingSlot => {
2130                if matches!(&input, ReadEvent::Slot) {
2131                    *state = HeaderState::SlotItem;
2132                    None
2133                } else {
2134                    Some(Err(input.kind_error(ExpectedEvent::Slot)))
2135                }
2136            }
2137            HeaderState::End => {
2138                if matches!(&input, ReadEvent::EndAttribute) {
2139                    Some(on_done(fields))
2140                } else {
2141                    Some(Err(input.kind_error(ExpectedEvent::EndOfAttribute)))
2142                }
2143            }
2144        }
2145    }
2146
2147    fn reset(&mut self) {
2148        self.state = if self.flattened {
2149            if !self.has_body {
2150                HeaderState::BetweenSlots
2151            } else {
2152                HeaderState::ExpectingBody
2153            }
2154        } else {
2155            HeaderState::Init
2156        };
2157        (self.vtable.reset)(&mut self.fields);
2158        self.progress.clear();
2159        self.index = 0;
2160    }
2161}
2162
2163#[doc(hidden)]
2164pub fn take_fields<T: Default, U, V>(state: &mut (T, U, V)) -> Result<T, ReadError> {
2165    Ok(std::mem::take(&mut state.0))
2166}
2167
2168#[derive(Debug)]
2169enum SimpleRecBodyState {
2170    Init,
2171    ReadingValue,
2172    AfterValue,
2173}
2174
2175/// Wraps another simple [`Recognizer`] to recognize the same type as the single item in the body
2176/// of a record.
2177#[derive(Debug)]
2178#[doc(hidden)]
2179pub struct SimpleRecBody<R: Recognizer> {
2180    state: SimpleRecBodyState,
2181    value: Option<R::Target>,
2182    delegate: R,
2183}
2184
2185impl<R: Recognizer> SimpleRecBody<R> {
2186    pub fn new(wrapped: R) -> Self {
2187        SimpleRecBody {
2188            state: SimpleRecBodyState::Init,
2189            value: None,
2190            delegate: wrapped,
2191        }
2192    }
2193}
2194
2195impl<R: Recognizer> Recognizer for SimpleRecBody<R> {
2196    type Target = R::Target;
2197
2198    fn feed_event(&mut self, input: ReadEvent<'_>) -> Option<Result<Self::Target, ReadError>> {
2199        let SimpleRecBody {
2200            state,
2201            value,
2202            delegate,
2203        } = self;
2204
2205        match state {
2206            SimpleRecBodyState::Init => {
2207                if matches!(input, ReadEvent::StartBody) {
2208                    *state = SimpleRecBodyState::ReadingValue;
2209                    None
2210                } else {
2211                    Some(Err(input.kind_error(ExpectedEvent::RecordBody)))
2212                }
2213            }
2214            SimpleRecBodyState::ReadingValue => match delegate.feed_event(input)? {
2215                Ok(v) => {
2216                    *value = Some(v);
2217                    *state = SimpleRecBodyState::AfterValue;
2218                    None
2219                }
2220                Err(e) => Some(Err(e)),
2221            },
2222            SimpleRecBodyState::AfterValue => {
2223                if matches!(input, ReadEvent::EndRecord) {
2224                    value.take().map(Ok)
2225                } else {
2226                    Some(Err(input.kind_error(ExpectedEvent::EndOfRecord)))
2227                }
2228            }
2229        }
2230    }
2231
2232    fn reset(&mut self) {
2233        self.state = SimpleRecBodyState::Init;
2234        self.value = None;
2235        self.delegate.reset();
2236    }
2237}