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