Skip to main content

protobuf_core/field/
read.rs

1// Copyright 2021 Google LLC
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
15//! Field reading utilities for Protocol Buffers
16//!
17//! This module provides low-level utilities for reading raw protobuf fields from various sources.
18//! It supports both owned data (`Field<Vec<u8>>`) for streaming sources like `std::io::Read`
19//! and borrowed references (`Field<&'a [u8]>`) for slice-based sources.
20
21use crate::field::{Field, FieldValue};
22use crate::tag::Tag;
23use crate::varint::{DecodeOutcome, Varint};
24use crate::wire_format::WireType;
25use crate::{ProtobufError, Result};
26use ::std::convert::AsRef;
27use ::std::io::Read;
28
29// ============================================================================
30// Common parsing infrastructure
31// ============================================================================
32
33/// Trait for reading field values from different data sources
34///
35/// This trait abstracts the reading operations needed to parse field values.
36/// Different implementations handle different data source types (Iterator, Read, slice, etc.)
37pub(crate) trait FieldValueReader<L> {
38    /// Read a tag (field number + wire type)
39    ///
40    /// Default implementation uses `read_varint` and converts the varint to a tag.
41    fn read_tag(&mut self) -> Result<Option<Tag>> {
42        match self.read_varint()? {
43            Some(varint) => Tag::from_encoded(varint).map(Some),
44            None => Ok(None),
45        }
46    }
47
48    /// Read a varint value (returns None when the stream is empty)
49    fn read_varint(&mut self) -> Result<Option<Varint>>;
50
51    /// Read exactly N bytes (for fixed-size wire types like Int32, Int64, Fixed32, Fixed64)
52    fn read_fixed<const N: usize>(&mut self) -> Result<[u8; N]>;
53
54    /// Read a length-delimited byte sequence
55    ///
56    /// The length parameter is the number of bytes to read after the length varint has been parsed.
57    fn read_length_delimited(&mut self, length: usize) -> Result<L>;
58}
59
60/// Parse a complete field (tag + value) from a field value reader
61///
62/// This is the common parsing logic for reading a complete field.
63/// The `L` type parameter represents the type used for length-delimited values
64/// (e.g., `Vec<u8>` for owned data, `&'a [u8]` for borrowed data).
65pub(crate) fn parse_field<L, R>(reader: &mut R) -> Result<Option<Field<L>>>
66where
67    R: FieldValueReader<L>,
68{
69    // Read tag
70    let Some(tag) = reader.read_tag()? else {
71        return Ok(None);
72    };
73
74    // Parse value based on wire type
75    let value = match tag.wire_type {
76        WireType::Varint => {
77            let varint = reader.read_varint()?.ok_or(ProtobufError::UnexpectedEof)?;
78            FieldValue::Varint(varint)
79        }
80        WireType::Int32 => {
81            let bytes = reader.read_fixed::<4>()?;
82            FieldValue::I32(bytes)
83        }
84        WireType::Int64 => {
85            let bytes = reader.read_fixed::<8>()?;
86            FieldValue::I64(bytes)
87        }
88        WireType::Len => {
89            // Read length prefix (varint)
90            let length_varint = reader.read_varint()?.ok_or(ProtobufError::UnexpectedEof)?;
91            let length = length_varint.try_to_uint32()? as usize;
92            let data = reader.read_length_delimited(length)?;
93            FieldValue::Len(data)
94        }
95        _ => {
96            return Err(ProtobufError::InvalidWireType {
97                value: tag.wire_type as u8,
98            });
99        }
100    };
101
102    Ok(Some(Field {
103        field_number: tag.field_number,
104        value,
105    }))
106}
107
108// ============================================================================
109// IteratorExtProtobuf
110// ============================================================================
111
112/// Helper struct implementing FieldValueReader for Iterator<Item = u8>
113struct IteratorReader<'a, I>(&'a mut I)
114where
115    I: Iterator<Item = u8>;
116
117impl<'a, I> FieldValueReader<Vec<u8>> for IteratorReader<'a, I>
118where
119    I: Iterator<Item = u8>,
120{
121    fn read_varint(&mut self) -> Result<Option<Varint>> {
122        use crate::varint::IteratorExtVarint;
123        match self.0.read_varint_partial()? {
124            DecodeOutcome::Complete(v) => Ok(Some(v)),
125            DecodeOutcome::Empty => Ok(None),
126            DecodeOutcome::Incomplete(_) => Err(ProtobufError::UnexpectedEof),
127        }
128    }
129
130    fn read_fixed<const N: usize>(&mut self) -> Result<[u8; N]> {
131        let mut bytes = [0u8; N];
132        for byte in bytes.iter_mut() {
133            *byte = self.0.next().ok_or(ProtobufError::UnexpectedEof)?;
134        }
135        Ok(bytes)
136    }
137
138    fn read_length_delimited(&mut self, length: usize) -> Result<Vec<u8>> {
139        let mut data = Vec::with_capacity(length);
140        for _ in 0..length {
141            data.push(self.0.next().ok_or(ProtobufError::UnexpectedEof)?);
142        }
143        Ok(data)
144    }
145}
146
147/// Iterator for reading raw protobuf fields sequentially from a byte iterator
148pub struct ProtobufFieldIteratorFromBytes<I> {
149    iter: I,
150}
151
152impl<I> Iterator for ProtobufFieldIteratorFromBytes<I>
153where
154    I: Iterator<Item = u8>,
155{
156    type Item = Result<Field<Vec<u8>>>;
157
158    fn next(&mut self) -> Option<Self::Item> {
159        let mut reader = IteratorReader(&mut self.iter);
160        match parse_field(&mut reader) {
161            Ok(Some(field)) => Some(Ok(field)),
162            Ok(None) => None,
163            Err(err) => Some(Err(err)),
164        }
165    }
166}
167
168/// Extension trait for reading raw Protocol Buffer fields from byte iterators.
169///
170/// This trait provides convenient methods to read fields directly from
171/// any iterator that yields bytes. Returns owned data (`Field<Vec<u8>>`).
172///
173/// # Example
174/// ```
175/// use ::protobuf_core::IteratorExtProtobuf;
176///
177/// let bytes = vec![0x08, 0x96, 0x01]; // field 1: 150
178/// let iter = bytes.into_iter();
179/// let fields: Vec<_> = iter.protobuf_fields().collect::<::std::result::Result<Vec<_>, _>>().unwrap();
180/// assert_eq!(fields[0].field_number.as_u32(), 1);
181/// ```
182pub trait IteratorExtProtobuf {
183    /// Convert this iterator into an iterator of protobuf fields.
184    ///
185    /// Returns an iterator that yields `Result<Field<Vec<u8>>>`.
186    /// Each field is parsed from the byte stream sequentially.
187    fn protobuf_fields(self) -> ProtobufFieldIteratorFromBytes<Self>
188    where
189        Self: Sized;
190}
191
192impl<I> IteratorExtProtobuf for I
193where
194    I: Iterator<Item = u8>,
195{
196    fn protobuf_fields(self) -> ProtobufFieldIteratorFromBytes<Self>
197    where
198        Self: Sized,
199    {
200        ProtobufFieldIteratorFromBytes { iter: self }
201    }
202}
203
204// ============================================================================
205// TryIteratorExtProtobuf
206// ============================================================================
207
208/// Helper struct implementing FieldValueReader for Iterator<Item = Result<u8, E>>
209struct TryIteratorReader<'a, I, E>(&'a mut I)
210where
211    I: Iterator<Item = ::std::result::Result<u8, E>>,
212    E: Into<ProtobufError>;
213
214impl<'a, I, E> FieldValueReader<Vec<u8>> for TryIteratorReader<'a, I, E>
215where
216    I: Iterator<Item = ::std::result::Result<u8, E>>,
217    E: Into<ProtobufError>,
218{
219    fn read_varint(&mut self) -> Result<Option<Varint>> {
220        use crate::varint::TryIteratorExtVarint;
221        match self.0.read_varint_partial()? {
222            DecodeOutcome::Complete(v) => Ok(Some(v)),
223            DecodeOutcome::Empty => Ok(None),
224            DecodeOutcome::Incomplete(_) => Err(ProtobufError::UnexpectedEof),
225        }
226    }
227
228    fn read_fixed<const N: usize>(&mut self) -> Result<[u8; N]> {
229        let mut bytes = [0u8; N];
230        for byte in bytes.iter_mut() {
231            *byte = self
232                .0
233                .next()
234                .ok_or(ProtobufError::UnexpectedEof)?
235                .map_err(Into::into)?;
236        }
237        Ok(bytes)
238    }
239
240    fn read_length_delimited(&mut self, length: usize) -> Result<Vec<u8>> {
241        let mut data = Vec::with_capacity(length);
242        for _ in 0..length {
243            data.push(
244                self.0
245                    .next()
246                    .ok_or(ProtobufError::UnexpectedEof)?
247                    .map_err(Into::into)?,
248            );
249        }
250        Ok(data)
251    }
252}
253
254/// Iterator for reading raw protobuf fields sequentially from a byte iterator that yields `Result<u8, E>`
255pub struct ProtobufFieldIteratorFromTryBytes<I> {
256    iter: I,
257}
258
259impl<I, E> Iterator for ProtobufFieldIteratorFromTryBytes<I>
260where
261    I: Iterator<Item = ::std::result::Result<u8, E>>,
262    E: Into<ProtobufError>,
263{
264    type Item = Result<Field<Vec<u8>>>;
265
266    fn next(&mut self) -> Option<Self::Item> {
267        let mut reader = TryIteratorReader(&mut self.iter);
268        match parse_field(&mut reader) {
269            Ok(Some(field)) => Some(Ok(field)),
270            Ok(None) => None,
271            Err(err) => Some(Err(err)),
272        }
273    }
274}
275
276/// Extension trait for reading raw Protocol Buffer fields from byte iterators that yield `Result<u8, E>`.
277///
278/// This trait provides convenient methods to read fields directly from
279/// any iterator that yields `Result<u8, E>`, allowing proper error propagation
280/// from I/O operations. Returns owned data (`Field<Vec<u8>>`).
281///
282/// # Example
283/// ```
284/// use ::std::io::{Cursor, Read};
285/// use ::protobuf_core::TryIteratorExtProtobuf;
286///
287/// let data = vec![0x08, 0x96, 0x01]; // field 1: 150
288/// let mut reader = Cursor::new(data);
289/// let iter = reader.bytes(); // Iterator<Item = Result<u8, io::Error>>
290/// let fields: Vec<_> = iter.protobuf_fields().collect::<Result<Vec<_>, _>>().unwrap();
291/// assert_eq!(fields[0].field_number.as_u32(), 1);
292/// ```
293pub trait TryIteratorExtProtobuf {
294    /// Convert this iterator into an iterator of protobuf fields.
295    ///
296    /// Returns an iterator that yields `Result<Field<Vec<u8>>>`.
297    /// Each field is parsed from the byte stream sequentially.
298    /// I/O errors from the underlying iterator are properly propagated.
299    fn protobuf_fields(self) -> ProtobufFieldIteratorFromTryBytes<Self>
300    where
301        Self: Sized;
302}
303
304impl<I, E> TryIteratorExtProtobuf for I
305where
306    I: Iterator<Item = ::std::result::Result<u8, E>>,
307    E: Into<ProtobufError>,
308{
309    fn protobuf_fields(self) -> ProtobufFieldIteratorFromTryBytes<Self>
310    where
311        Self: Sized,
312    {
313        ProtobufFieldIteratorFromTryBytes { iter: self }
314    }
315}
316
317// ============================================================================
318// ReadExtProtobuf
319// ============================================================================
320
321/// Helper struct implementing FieldValueReader for Read
322struct ReadReader<'a, R>(&'a mut R)
323where
324    R: Read;
325
326impl<'a, R> FieldValueReader<Vec<u8>> for ReadReader<'a, R>
327where
328    R: Read,
329{
330    fn read_varint(&mut self) -> Result<Option<Varint>> {
331        use crate::varint::ReadExtVarint;
332        self.0.read_varint()
333    }
334
335    fn read_fixed<const N: usize>(&mut self) -> Result<[u8; N]> {
336        let mut bytes = [0u8; N];
337        self.0.read_exact(&mut bytes)?;
338        Ok(bytes)
339    }
340
341    fn read_length_delimited(&mut self, length: usize) -> Result<Vec<u8>> {
342        let mut data = vec![0u8; length];
343        self.0.read_exact(&mut data)?;
344        Ok(data)
345    }
346}
347
348/// Iterator for reading raw protobuf fields sequentially from a reader
349pub struct ProtobufFieldIterator<R> {
350    reader: R,
351}
352
353impl<R> Iterator for ProtobufFieldIterator<R>
354where
355    R: Read,
356{
357    type Item = Result<Field<Vec<u8>>>; // Owned data from Read
358
359    fn next(&mut self) -> Option<Self::Item> {
360        let mut reader = ReadReader(&mut self.reader);
361        match parse_field(&mut reader) {
362            Ok(Some(field)) => Some(Ok(field)),
363            Ok(None) => None,
364            Err(err) => Some(Err(err)),
365        }
366    }
367}
368
369/// Extension trait for reading raw Protocol Buffer fields from `Read` types
370///
371/// This trait provides low-level utilities for reading field-by-field from a byte stream.
372/// It returns owned data (`Field<Vec<u8>>`) suitable for streaming sources.
373/// It does not provide semantic interpretation - that is the caller's responsibility.
374///
375/// # Example
376/// ```
377/// use ::protobuf_core::{ReadExtProtobuf, Field, FieldValue};
378///
379/// fn main() -> Result<(), Box<dyn ::std::error::Error>> {
380///     let reader = &[0x08, 0x96, 0x01, 0x12, 0x03, 0x48, 0x65, 0x6c][..];
381///
382///     for field in reader.read_protobuf_fields() {
383///         let field = field?;
384///         match field.value {
385///             FieldValue::Varint(varint) => {
386///                 println!("Field {}: {}", field.field_number.as_u32(), varint.to_uint64());
387///             },
388///             FieldValue::Len(data) => {
389///                 println!("Field {}: {:?}", field.field_number.as_u32(), data);
390///             },
391///             _ => {}
392///         }
393///     }
394///     Ok(())
395/// }
396/// ```
397pub trait ReadExtProtobuf {
398    /// Read raw protobuf fields from the reader, returning an iterator
399    ///
400    /// This consumes the reader and returns an iterator that yields fields sequentially.
401    /// Each field contains raw bytes that must be interpreted by the caller.
402    /// Returns owned data (`Field<Vec<u8>>`).
403    fn read_protobuf_fields(self) -> ProtobufFieldIterator<Self>
404    where
405        Self: Sized;
406}
407
408impl<R> ReadExtProtobuf for R
409where
410    R: Read,
411{
412    fn read_protobuf_fields(self) -> ProtobufFieldIterator<Self>
413    where
414        Self: Sized,
415    {
416        ProtobufFieldIterator { reader: self }
417    }
418}
419
420// ============================================================================
421// AsRefExtProtobuf
422// ============================================================================
423
424/// Helper struct implementing FieldValueReader for slice-based readers
425pub(crate) struct SliceReader<'a, 'b> {
426    pub(crate) slice: &'b mut &'a [u8],
427}
428
429impl<'a, 'b> FieldValueReader<&'a [u8]> for SliceReader<'a, 'b> {
430    fn read_varint(&mut self) -> Result<Option<Varint>> {
431        use crate::varint::ReadExtVarint;
432        self.slice.read_varint()
433    }
434
435    fn read_fixed<const N: usize>(&mut self) -> Result<[u8; N]> {
436        let (bytes, remaining) = self
437            .slice
438            .split_first_chunk::<N>()
439            .ok_or(ProtobufError::UnexpectedEof)?;
440        *self.slice = remaining;
441        Ok(*bytes)
442    }
443
444    fn read_length_delimited(&mut self, length: usize) -> Result<&'a [u8]> {
445        let (value_slice, remaining) = self
446            .slice
447            .split_at_checked(length)
448            .ok_or(ProtobufError::UnexpectedEof)?;
449        *self.slice = remaining;
450        Ok(value_slice)
451    }
452}
453
454/// Iterator for reading raw protobuf fields sequentially from a slice
455pub struct ProtobufFieldSliceIterator<'a> {
456    slice: &'a [u8],
457}
458
459impl<'a> Iterator for ProtobufFieldSliceIterator<'a> {
460    type Item = Result<Field<&'a [u8]>>;
461
462    fn next(&mut self) -> Option<Self::Item> {
463        let mut reader = SliceReader {
464            slice: &mut self.slice,
465        };
466        parse_field(&mut reader).transpose()
467    }
468}
469
470/// Extension trait for reading raw Protocol Buffer fields from slice types
471///
472/// This trait provides low-level utilities for reading field-by-field from a byte slice.
473/// It returns borrowed references (`Field<&'a [u8]>`) suitable for slice sources.
474/// It does not provide semantic interpretation - that is the caller's responsibility.
475///
476/// # Example
477/// ```
478/// use ::protobuf_core::AsRefExtProtobuf;
479///
480/// let slice = &[0x08, 0x96, 0x01, 0x12, 0x03, 0x48, 0x65, 0x6c][..];
481///
482/// for field_result in slice.read_protobuf_fields() {
483///     let field = field_result?;
484///     // Process field...
485/// }
486/// # Ok::<(), protobuf_core::ProtobufError>(())
487/// ```
488pub trait AsRefExtProtobuf: AsRef<[u8]> {
489    /// Read raw protobuf fields from the slice, returning an iterator
490    ///
491    /// This returns an iterator that yields fields sequentially.
492    /// Each field contains raw bytes that must be interpreted by the caller.
493    /// Returns borrowed references (`Field<&'a [u8]>`).
494    ///
495    /// This method is available for all types implementing `AsRef<[u8]>`.
496    fn read_protobuf_fields(&self) -> ProtobufFieldSliceIterator<'_> {
497        ProtobufFieldSliceIterator {
498            slice: self.as_ref(),
499        }
500    }
501}
502
503impl<T> AsRefExtProtobuf for T where T: AsRef<[u8]> + ?Sized {}
504
505// ============================================================================
506// Tests
507// ============================================================================
508
509#[cfg(test)]
510mod tests {
511    use crate::field::FieldValue;
512
513    // ============================================================================
514    // AsRefExtProtobuf tests (borrowed references)
515    // ============================================================================
516
517    #[test]
518    fn test_as_ref_ext_read_varint_field() {
519        use super::AsRefExtProtobuf;
520
521        let reader = &[0x08, 0x96, 0x01][..]; // field 1: 150
522
523        let fields: Vec<_> = reader
524            .read_protobuf_fields()
525            .collect::<::std::result::Result<Vec<_>, _>>()
526            .unwrap();
527        assert_eq!(fields.len(), 1);
528        assert_eq!(fields[0].field_number.as_u32(), 1);
529        match &fields[0].value {
530            FieldValue::Varint(varint) => {
531                assert_eq!(varint.to_uint64(), 150);
532            }
533            _ => panic!("Expected Varint field"),
534        }
535    }
536
537    #[test]
538    fn test_as_ref_ext_read_len_field() {
539        use super::AsRefExtProtobuf;
540
541        let reader = &[0x12, 0x03, 0x48, 0x65, 0x6c][..]; // field 2: "Hel"
542
543        let fields: Vec<_> = reader
544            .read_protobuf_fields()
545            .collect::<::std::result::Result<Vec<_>, _>>()
546            .unwrap();
547        assert_eq!(fields.len(), 1);
548
549        let field = &fields[0];
550        assert_eq!(field.field_number.as_u32(), 2);
551        match &field.value {
552            FieldValue::Len(data) => {
553                assert_eq!(&data[..], b"Hel");
554            }
555            _ => panic!("Expected Len field"),
556        }
557    }
558
559    #[test]
560    fn test_as_ref_ext_read_i32_field() {
561        use super::AsRefExtProtobuf;
562
563        let reader = &[0x15, 0x78, 0x56, 0x34, 0x12][..]; // field 2: 0x12345678 (Fixed32)
564
565        let fields: Vec<_> = reader
566            .read_protobuf_fields()
567            .collect::<::std::result::Result<Vec<_>, _>>()
568            .unwrap();
569        assert_eq!(fields.len(), 1);
570
571        let field = &fields[0];
572        assert_eq!(field.field_number.as_u32(), 2);
573        match &field.value {
574            FieldValue::I32(bytes) => {
575                assert_eq!(*bytes, [0x78, 0x56, 0x34, 0x12]);
576            }
577            _ => panic!("Expected I32 field"),
578        }
579    }
580
581    #[test]
582    fn test_as_ref_ext_read_i64_field() {
583        use super::AsRefExtProtobuf;
584
585        let reader = &[0x19, 0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12][..]; // field 3: 0x1234567890ABCDEF (Fixed64)
586
587        let fields: Vec<_> = reader
588            .read_protobuf_fields()
589            .collect::<::std::result::Result<Vec<_>, _>>()
590            .unwrap();
591        assert_eq!(fields.len(), 1);
592
593        let field = &fields[0];
594        assert_eq!(field.field_number.as_u32(), 3);
595        match &field.value {
596            FieldValue::I64(bytes) => {
597                assert_eq!(*bytes, [0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12]);
598            }
599            _ => panic!("Expected I64 field"),
600        }
601    }
602
603    #[test]
604    fn test_as_ref_ext_read_multiple_fields() {
605        use super::AsRefExtProtobuf;
606
607        let reader = &[
608            0x08, 0x96, 0x01, // field 1: 150
609            0x12, 0x03, 0x48, 0x65, 0x6c, // field 2: "Hel"
610        ][..];
611
612        let fields: Vec<_> = reader
613            .read_protobuf_fields()
614            .collect::<::std::result::Result<Vec<_>, _>>()
615            .unwrap();
616        assert_eq!(fields.len(), 2);
617
618        // Check first field
619        let field = &fields[0];
620        assert_eq!(field.field_number.as_u32(), 1);
621        match &field.value {
622            FieldValue::Varint(varint) => {
623                assert_eq!(varint.to_uint64(), 150);
624            }
625            _ => panic!("Expected Varint field"),
626        }
627
628        // Check second field
629        let field = &fields[1];
630        assert_eq!(field.field_number.as_u32(), 2);
631        match &field.value {
632            FieldValue::Len(data) => {
633                assert_eq!(&data[..], b"Hel");
634            }
635            _ => panic!("Expected Len field"),
636        }
637    }
638
639    #[test]
640    fn test_as_ref_ext_read_empty_stream() {
641        use super::AsRefExtProtobuf;
642
643        let reader = &[][..];
644
645        let fields: Vec<_> = reader
646            .read_protobuf_fields()
647            .collect::<::std::result::Result<Vec<_>, _>>()
648            .unwrap();
649        assert_eq!(fields.len(), 0);
650    }
651
652    #[test]
653    fn test_as_ref_ext_works_with_unsized_type() {
654        use super::AsRefExtProtobuf;
655
656        // This test verifies that ?Sized bound allows the trait to work with unsized types
657        // Without ?Sized, this would fail to compile because [u8] is unsized
658        fn accepts_unsized<T: AsRefExtProtobuf + ?Sized>(x: &T) {
659            let _ = x.read_protobuf_fields();
660        }
661
662        let data = [0x08, 0x96, 0x01]; // field 1: 150
663        accepts_unsized(&data[..]); // &[u8] - unsized type slice
664
665        // Also test with direct unsized slice
666        let slice: &[u8] = &[0x08, 0x96, 0x01];
667        let fields: Vec<_> = slice
668            .read_protobuf_fields()
669            .collect::<::std::result::Result<Vec<_>, _>>()
670            .unwrap();
671        assert_eq!(fields.len(), 1);
672        assert_eq!(fields[0].field_number.as_u32(), 1);
673    }
674
675    // ============================================================================
676    // ReadExtProtobuf tests (owned data from Read)
677    // ============================================================================
678
679    #[test]
680    fn test_read_ext_read_varint_field() {
681        use super::ReadExtProtobuf;
682        use ::std::io::Cursor;
683
684        let data = vec![0x08, 0x96, 0x01]; // field 1: 150
685        let reader = Cursor::new(data);
686        let fields: Vec<_> = reader
687            .read_protobuf_fields()
688            .collect::<::std::result::Result<Vec<_>, _>>()
689            .unwrap();
690        assert_eq!(fields.len(), 1);
691        assert_eq!(fields[0].field_number.as_u32(), 1);
692        match &fields[0].value {
693            FieldValue::Varint(varint) => {
694                assert_eq!(varint.to_uint64(), 150);
695            }
696            _ => panic!("Expected Varint field"),
697        }
698    }
699
700    #[test]
701    fn test_read_ext_read_multiple_fields() {
702        use super::ReadExtProtobuf;
703        use ::std::io::Cursor;
704
705        let data = vec![
706            0x08, 0x96, 0x01, // field 1: 150
707            0x12, 0x03, 0x48, 0x65, 0x6c, // field 2: "Hel"
708        ];
709        let reader = Cursor::new(data);
710        let fields: Vec<_> = reader
711            .read_protobuf_fields()
712            .collect::<::std::result::Result<Vec<_>, _>>()
713            .unwrap();
714        assert_eq!(fields.len(), 2);
715
716        // Check first field
717        assert_eq!(fields[0].field_number.as_u32(), 1);
718        match &fields[0].value {
719            FieldValue::Varint(varint) => {
720                assert_eq!(varint.to_uint64(), 150);
721            }
722            _ => panic!("Expected Varint field"),
723        }
724
725        // Check second field
726        assert_eq!(fields[1].field_number.as_u32(), 2);
727        match &fields[1].value {
728            FieldValue::Len(data) => {
729                assert_eq!(&data[..], b"Hel");
730            }
731            _ => panic!("Expected Len field"),
732        }
733    }
734
735    #[test]
736    fn test_read_ext_read_i32_field() {
737        use super::ReadExtProtobuf;
738        use ::std::io::Cursor;
739
740        let data = vec![0x15, 0x78, 0x56, 0x34, 0x12]; // field 2: 0x12345678 (Fixed32)
741        let reader = Cursor::new(data);
742        let fields: Vec<_> = reader
743            .read_protobuf_fields()
744            .collect::<::std::result::Result<Vec<_>, _>>()
745            .unwrap();
746        assert_eq!(fields.len(), 1);
747        assert_eq!(fields[0].field_number.as_u32(), 2);
748        match &fields[0].value {
749            FieldValue::I32(bytes) => {
750                assert_eq!(*bytes, [0x78, 0x56, 0x34, 0x12]);
751            }
752            _ => panic!("Expected I32 field"),
753        }
754    }
755
756    #[test]
757    fn test_read_ext_read_len_field() {
758        use super::ReadExtProtobuf;
759        use ::std::io::Cursor;
760
761        let data = vec![0x12, 0x03, 0x48, 0x65, 0x6c]; // field 2: "Hel"
762        let reader = Cursor::new(data);
763        let fields: Vec<_> = reader
764            .read_protobuf_fields()
765            .collect::<::std::result::Result<Vec<_>, _>>()
766            .unwrap();
767        assert_eq!(fields.len(), 1);
768        assert_eq!(fields[0].field_number.as_u32(), 2);
769        match &fields[0].value {
770            FieldValue::Len(data) => {
771                assert_eq!(&data[..], b"Hel");
772            }
773            _ => panic!("Expected Len field"),
774        }
775    }
776
777    #[test]
778    fn test_read_ext_read_i64_field() {
779        use super::ReadExtProtobuf;
780        use ::std::io::Cursor;
781
782        let data = vec![0x19, 0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12]; // field 3: 0x1234567890ABCDEF (Fixed64)
783        let reader = Cursor::new(data);
784        let fields: Vec<_> = reader
785            .read_protobuf_fields()
786            .collect::<::std::result::Result<Vec<_>, _>>()
787            .unwrap();
788        assert_eq!(fields.len(), 1);
789        assert_eq!(fields[0].field_number.as_u32(), 3);
790        match &fields[0].value {
791            FieldValue::I64(bytes) => {
792                assert_eq!(*bytes, [0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12]);
793            }
794            _ => panic!("Expected I64 field"),
795        }
796    }
797
798    #[test]
799    fn test_read_ext_read_empty_stream() {
800        use super::ReadExtProtobuf;
801        use ::std::io::Cursor;
802
803        let data = vec![];
804        let reader = Cursor::new(data);
805        let fields: Vec<_> = reader
806            .read_protobuf_fields()
807            .collect::<::std::result::Result<Vec<_>, _>>()
808            .unwrap();
809        assert_eq!(fields.len(), 0);
810    }
811
812    // ============================================================================
813    // IteratorExtProtobuf tests
814    // ============================================================================
815
816    #[test]
817    fn test_iterator_ext_read_varint_field() {
818        use super::IteratorExtProtobuf;
819
820        let bytes = vec![0x08, 0x96, 0x01]; // field 1: 150
821        let iter = bytes.into_iter();
822        let fields: Vec<_> = iter
823            .protobuf_fields()
824            .collect::<::std::result::Result<Vec<_>, _>>()
825            .unwrap();
826        assert_eq!(fields.len(), 1);
827        assert_eq!(fields[0].field_number.as_u32(), 1);
828        match &fields[0].value {
829            FieldValue::Varint(varint) => {
830                assert_eq!(varint.to_uint64(), 150);
831            }
832            _ => panic!("Expected Varint field"),
833        }
834    }
835
836    #[test]
837    fn test_iterator_ext_read_multiple_fields() {
838        use super::IteratorExtProtobuf;
839
840        let bytes = vec![
841            0x08, 0x96, 0x01, // field 1: 150
842            0x12, 0x03, 0x48, 0x65, 0x6c, // field 2: "Hel"
843        ];
844        let iter = bytes.into_iter();
845        let fields: Vec<_> = iter
846            .protobuf_fields()
847            .collect::<::std::result::Result<Vec<_>, _>>()
848            .unwrap();
849        assert_eq!(fields.len(), 2);
850
851        // Check first field
852        assert_eq!(fields[0].field_number.as_u32(), 1);
853        match &fields[0].value {
854            FieldValue::Varint(varint) => {
855                assert_eq!(varint.to_uint64(), 150);
856            }
857            _ => panic!("Expected Varint field"),
858        }
859
860        // Check second field
861        assert_eq!(fields[1].field_number.as_u32(), 2);
862        match &fields[1].value {
863            FieldValue::Len(data) => {
864                assert_eq!(&data[..], b"Hel");
865            }
866            _ => panic!("Expected Len field"),
867        }
868    }
869
870    #[test]
871    fn test_iterator_ext_read_len_field() {
872        use super::IteratorExtProtobuf;
873
874        let bytes = vec![0x12, 0x03, 0x48, 0x65, 0x6c]; // field 2: "Hel"
875        let iter = bytes.into_iter();
876        let fields: Vec<_> = iter
877            .protobuf_fields()
878            .collect::<::std::result::Result<Vec<_>, _>>()
879            .unwrap();
880        assert_eq!(fields.len(), 1);
881        assert_eq!(fields[0].field_number.as_u32(), 2);
882        match &fields[0].value {
883            FieldValue::Len(data) => {
884                assert_eq!(&data[..], b"Hel");
885            }
886            _ => panic!("Expected Len field"),
887        }
888    }
889
890    #[test]
891    fn test_iterator_ext_read_i32_field() {
892        use super::IteratorExtProtobuf;
893
894        let bytes = vec![0x15, 0x78, 0x56, 0x34, 0x12]; // field 2: 0x12345678 (Fixed32)
895        let iter = bytes.into_iter();
896        let fields: Vec<_> = iter
897            .protobuf_fields()
898            .collect::<::std::result::Result<Vec<_>, _>>()
899            .unwrap();
900        assert_eq!(fields.len(), 1);
901        assert_eq!(fields[0].field_number.as_u32(), 2);
902        match &fields[0].value {
903            FieldValue::I32(bytes) => {
904                assert_eq!(*bytes, [0x78, 0x56, 0x34, 0x12]);
905            }
906            _ => panic!("Expected I32 field"),
907        }
908    }
909
910    #[test]
911    fn test_iterator_ext_read_i64_field() {
912        use super::IteratorExtProtobuf;
913
914        let bytes = vec![0x19, 0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12]; // field 3: 0x1234567890ABCDEF (Fixed64)
915        let iter = bytes.into_iter();
916        let fields: Vec<_> = iter
917            .protobuf_fields()
918            .collect::<::std::result::Result<Vec<_>, _>>()
919            .unwrap();
920        assert_eq!(fields.len(), 1);
921        assert_eq!(fields[0].field_number.as_u32(), 3);
922        match &fields[0].value {
923            FieldValue::I64(bytes) => {
924                assert_eq!(*bytes, [0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12]);
925            }
926            _ => panic!("Expected I64 field"),
927        }
928    }
929
930    #[test]
931    fn test_iterator_ext_read_empty_stream() {
932        use super::IteratorExtProtobuf;
933
934        let bytes = vec![];
935        let iter = bytes.into_iter();
936        let fields: Vec<_> = iter
937            .protobuf_fields()
938            .collect::<::std::result::Result<Vec<_>, _>>()
939            .unwrap();
940        assert_eq!(fields.len(), 0);
941    }
942
943    // ============================================================================
944    // TryIteratorExtProtobuf tests
945    // ============================================================================
946
947    #[test]
948    fn test_try_iterator_ext_read_varint_field() {
949        use super::TryIteratorExtProtobuf;
950        use ::std::io::{Cursor, Read};
951
952        let data = vec![0x08, 0x96, 0x01]; // field 1: 150
953        let reader = Cursor::new(data);
954        let iter = reader.bytes();
955        let fields: Vec<_> = iter
956            .protobuf_fields()
957            .collect::<::std::result::Result<Vec<_>, _>>()
958            .unwrap();
959        assert_eq!(fields.len(), 1);
960        assert_eq!(fields[0].field_number.as_u32(), 1);
961        match &fields[0].value {
962            FieldValue::Varint(varint) => {
963                assert_eq!(varint.to_uint64(), 150);
964            }
965            _ => panic!("Expected Varint field"),
966        }
967    }
968
969    #[test]
970    fn test_try_iterator_ext_read_multiple_fields() {
971        use super::TryIteratorExtProtobuf;
972        use ::std::io::{Cursor, Read};
973
974        let data = vec![
975            0x08, 0x96, 0x01, // field 1: 150
976            0x12, 0x03, 0x48, 0x65, 0x6c, // field 2: "Hel"
977        ];
978        let reader = Cursor::new(data);
979        let iter = reader.bytes();
980        let fields: Vec<_> = iter
981            .protobuf_fields()
982            .collect::<::std::result::Result<Vec<_>, _>>()
983            .unwrap();
984        assert_eq!(fields.len(), 2);
985
986        // Check first field
987        assert_eq!(fields[0].field_number.as_u32(), 1);
988        match &fields[0].value {
989            FieldValue::Varint(varint) => {
990                assert_eq!(varint.to_uint64(), 150);
991            }
992            _ => panic!("Expected Varint field"),
993        }
994
995        // Check second field
996        assert_eq!(fields[1].field_number.as_u32(), 2);
997        match &fields[1].value {
998            FieldValue::Len(data) => {
999                assert_eq!(&data[..], b"Hel");
1000            }
1001            _ => panic!("Expected Len field"),
1002        }
1003    }
1004
1005    #[test]
1006    fn test_try_iterator_ext_read_len_field() {
1007        use super::TryIteratorExtProtobuf;
1008        use ::std::io::{Cursor, Read};
1009
1010        let data = vec![0x12, 0x03, 0x48, 0x65, 0x6c]; // field 2: "Hel"
1011        let reader = Cursor::new(data);
1012        let iter = reader.bytes();
1013        let fields: Vec<_> = iter
1014            .protobuf_fields()
1015            .collect::<::std::result::Result<Vec<_>, _>>()
1016            .unwrap();
1017        assert_eq!(fields.len(), 1);
1018        assert_eq!(fields[0].field_number.as_u32(), 2);
1019        match &fields[0].value {
1020            FieldValue::Len(data) => {
1021                assert_eq!(&data[..], b"Hel");
1022            }
1023            _ => panic!("Expected Len field"),
1024        }
1025    }
1026
1027    #[test]
1028    fn test_try_iterator_ext_read_i32_field() {
1029        use super::TryIteratorExtProtobuf;
1030        use ::std::io::{Cursor, Read};
1031
1032        let data = vec![0x15, 0x78, 0x56, 0x34, 0x12]; // field 2: 0x12345678 (Fixed32)
1033        let reader = Cursor::new(data);
1034        let iter = reader.bytes();
1035        let fields: Vec<_> = iter
1036            .protobuf_fields()
1037            .collect::<::std::result::Result<Vec<_>, _>>()
1038            .unwrap();
1039        assert_eq!(fields.len(), 1);
1040        assert_eq!(fields[0].field_number.as_u32(), 2);
1041        match &fields[0].value {
1042            FieldValue::I32(bytes) => {
1043                assert_eq!(*bytes, [0x78, 0x56, 0x34, 0x12]);
1044            }
1045            _ => panic!("Expected I32 field"),
1046        }
1047    }
1048
1049    #[test]
1050    fn test_try_iterator_ext_read_i64_field() {
1051        use super::TryIteratorExtProtobuf;
1052        use ::std::io::{Cursor, Read};
1053
1054        let data = vec![0x19, 0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12]; // field 3: 0x1234567890ABCDEF (Fixed64)
1055        let reader = Cursor::new(data);
1056        let iter = reader.bytes();
1057        let fields: Vec<_> = iter
1058            .protobuf_fields()
1059            .collect::<::std::result::Result<Vec<_>, _>>()
1060            .unwrap();
1061        assert_eq!(fields.len(), 1);
1062        assert_eq!(fields[0].field_number.as_u32(), 3);
1063        match &fields[0].value {
1064            FieldValue::I64(bytes) => {
1065                assert_eq!(*bytes, [0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12]);
1066            }
1067            _ => panic!("Expected I64 field"),
1068        }
1069    }
1070
1071    #[test]
1072    fn test_try_iterator_ext_read_empty_stream() {
1073        use super::TryIteratorExtProtobuf;
1074        use ::std::io::{Cursor, Read};
1075
1076        let data = vec![];
1077        let reader = Cursor::new(data);
1078        let iter = reader.bytes();
1079        let fields: Vec<_> = iter
1080            .protobuf_fields()
1081            .collect::<::std::result::Result<Vec<_>, _>>()
1082            .unwrap();
1083        assert_eq!(fields.len(), 0);
1084    }
1085}