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]> {}
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    // ============================================================================
649    // ReadExtProtobuf tests (owned data from Read)
650    // ============================================================================
651
652    #[test]
653    fn test_read_ext_read_varint_field() {
654        use super::ReadExtProtobuf;
655        use ::std::io::Cursor;
656
657        let data = vec![0x08, 0x96, 0x01]; // field 1: 150
658        let reader = Cursor::new(data);
659        let fields: Vec<_> = reader
660            .read_protobuf_fields()
661            .collect::<::std::result::Result<Vec<_>, _>>()
662            .unwrap();
663        assert_eq!(fields.len(), 1);
664        assert_eq!(fields[0].field_number.as_u32(), 1);
665        match &fields[0].value {
666            FieldValue::Varint(varint) => {
667                assert_eq!(varint.to_uint64(), 150);
668            }
669            _ => panic!("Expected Varint field"),
670        }
671    }
672
673    #[test]
674    fn test_read_ext_read_multiple_fields() {
675        use super::ReadExtProtobuf;
676        use ::std::io::Cursor;
677
678        let data = vec![
679            0x08, 0x96, 0x01, // field 1: 150
680            0x12, 0x03, 0x48, 0x65, 0x6c, // field 2: "Hel"
681        ];
682        let reader = Cursor::new(data);
683        let fields: Vec<_> = reader
684            .read_protobuf_fields()
685            .collect::<::std::result::Result<Vec<_>, _>>()
686            .unwrap();
687        assert_eq!(fields.len(), 2);
688
689        // Check first field
690        assert_eq!(fields[0].field_number.as_u32(), 1);
691        match &fields[0].value {
692            FieldValue::Varint(varint) => {
693                assert_eq!(varint.to_uint64(), 150);
694            }
695            _ => panic!("Expected Varint field"),
696        }
697
698        // Check second field
699        assert_eq!(fields[1].field_number.as_u32(), 2);
700        match &fields[1].value {
701            FieldValue::Len(data) => {
702                assert_eq!(&data[..], b"Hel");
703            }
704            _ => panic!("Expected Len field"),
705        }
706    }
707
708    #[test]
709    fn test_read_ext_read_i32_field() {
710        use super::ReadExtProtobuf;
711        use ::std::io::Cursor;
712
713        let data = vec![0x15, 0x78, 0x56, 0x34, 0x12]; // field 2: 0x12345678 (Fixed32)
714        let reader = Cursor::new(data);
715        let fields: Vec<_> = reader
716            .read_protobuf_fields()
717            .collect::<::std::result::Result<Vec<_>, _>>()
718            .unwrap();
719        assert_eq!(fields.len(), 1);
720        assert_eq!(fields[0].field_number.as_u32(), 2);
721        match &fields[0].value {
722            FieldValue::I32(bytes) => {
723                assert_eq!(*bytes, [0x78, 0x56, 0x34, 0x12]);
724            }
725            _ => panic!("Expected I32 field"),
726        }
727    }
728
729    #[test]
730    fn test_read_ext_read_len_field() {
731        use super::ReadExtProtobuf;
732        use ::std::io::Cursor;
733
734        let data = vec![0x12, 0x03, 0x48, 0x65, 0x6c]; // field 2: "Hel"
735        let reader = Cursor::new(data);
736        let fields: Vec<_> = reader
737            .read_protobuf_fields()
738            .collect::<::std::result::Result<Vec<_>, _>>()
739            .unwrap();
740        assert_eq!(fields.len(), 1);
741        assert_eq!(fields[0].field_number.as_u32(), 2);
742        match &fields[0].value {
743            FieldValue::Len(data) => {
744                assert_eq!(&data[..], b"Hel");
745            }
746            _ => panic!("Expected Len field"),
747        }
748    }
749
750    #[test]
751    fn test_read_ext_read_i64_field() {
752        use super::ReadExtProtobuf;
753        use ::std::io::Cursor;
754
755        let data = vec![0x19, 0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12]; // field 3: 0x1234567890ABCDEF (Fixed64)
756        let reader = Cursor::new(data);
757        let fields: Vec<_> = reader
758            .read_protobuf_fields()
759            .collect::<::std::result::Result<Vec<_>, _>>()
760            .unwrap();
761        assert_eq!(fields.len(), 1);
762        assert_eq!(fields[0].field_number.as_u32(), 3);
763        match &fields[0].value {
764            FieldValue::I64(bytes) => {
765                assert_eq!(*bytes, [0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12]);
766            }
767            _ => panic!("Expected I64 field"),
768        }
769    }
770
771    #[test]
772    fn test_read_ext_read_empty_stream() {
773        use super::ReadExtProtobuf;
774        use ::std::io::Cursor;
775
776        let data = vec![];
777        let reader = Cursor::new(data);
778        let fields: Vec<_> = reader
779            .read_protobuf_fields()
780            .collect::<::std::result::Result<Vec<_>, _>>()
781            .unwrap();
782        assert_eq!(fields.len(), 0);
783    }
784
785    // ============================================================================
786    // IteratorExtProtobuf tests
787    // ============================================================================
788
789    #[test]
790    fn test_iterator_ext_read_varint_field() {
791        use super::IteratorExtProtobuf;
792
793        let bytes = vec![0x08, 0x96, 0x01]; // field 1: 150
794        let iter = bytes.into_iter();
795        let fields: Vec<_> = iter
796            .protobuf_fields()
797            .collect::<::std::result::Result<Vec<_>, _>>()
798            .unwrap();
799        assert_eq!(fields.len(), 1);
800        assert_eq!(fields[0].field_number.as_u32(), 1);
801        match &fields[0].value {
802            FieldValue::Varint(varint) => {
803                assert_eq!(varint.to_uint64(), 150);
804            }
805            _ => panic!("Expected Varint field"),
806        }
807    }
808
809    #[test]
810    fn test_iterator_ext_read_multiple_fields() {
811        use super::IteratorExtProtobuf;
812
813        let bytes = vec![
814            0x08, 0x96, 0x01, // field 1: 150
815            0x12, 0x03, 0x48, 0x65, 0x6c, // field 2: "Hel"
816        ];
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(), 2);
823
824        // Check first field
825        assert_eq!(fields[0].field_number.as_u32(), 1);
826        match &fields[0].value {
827            FieldValue::Varint(varint) => {
828                assert_eq!(varint.to_uint64(), 150);
829            }
830            _ => panic!("Expected Varint field"),
831        }
832
833        // Check second field
834        assert_eq!(fields[1].field_number.as_u32(), 2);
835        match &fields[1].value {
836            FieldValue::Len(data) => {
837                assert_eq!(&data[..], b"Hel");
838            }
839            _ => panic!("Expected Len field"),
840        }
841    }
842
843    #[test]
844    fn test_iterator_ext_read_len_field() {
845        use super::IteratorExtProtobuf;
846
847        let bytes = vec![0x12, 0x03, 0x48, 0x65, 0x6c]; // field 2: "Hel"
848        let iter = bytes.into_iter();
849        let fields: Vec<_> = iter
850            .protobuf_fields()
851            .collect::<::std::result::Result<Vec<_>, _>>()
852            .unwrap();
853        assert_eq!(fields.len(), 1);
854        assert_eq!(fields[0].field_number.as_u32(), 2);
855        match &fields[0].value {
856            FieldValue::Len(data) => {
857                assert_eq!(&data[..], b"Hel");
858            }
859            _ => panic!("Expected Len field"),
860        }
861    }
862
863    #[test]
864    fn test_iterator_ext_read_i32_field() {
865        use super::IteratorExtProtobuf;
866
867        let bytes = vec![0x15, 0x78, 0x56, 0x34, 0x12]; // field 2: 0x12345678 (Fixed32)
868        let iter = bytes.into_iter();
869        let fields: Vec<_> = iter
870            .protobuf_fields()
871            .collect::<::std::result::Result<Vec<_>, _>>()
872            .unwrap();
873        assert_eq!(fields.len(), 1);
874        assert_eq!(fields[0].field_number.as_u32(), 2);
875        match &fields[0].value {
876            FieldValue::I32(bytes) => {
877                assert_eq!(*bytes, [0x78, 0x56, 0x34, 0x12]);
878            }
879            _ => panic!("Expected I32 field"),
880        }
881    }
882
883    #[test]
884    fn test_iterator_ext_read_i64_field() {
885        use super::IteratorExtProtobuf;
886
887        let bytes = vec![0x19, 0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12]; // field 3: 0x1234567890ABCDEF (Fixed64)
888        let iter = bytes.into_iter();
889        let fields: Vec<_> = iter
890            .protobuf_fields()
891            .collect::<::std::result::Result<Vec<_>, _>>()
892            .unwrap();
893        assert_eq!(fields.len(), 1);
894        assert_eq!(fields[0].field_number.as_u32(), 3);
895        match &fields[0].value {
896            FieldValue::I64(bytes) => {
897                assert_eq!(*bytes, [0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12]);
898            }
899            _ => panic!("Expected I64 field"),
900        }
901    }
902
903    #[test]
904    fn test_iterator_ext_read_empty_stream() {
905        use super::IteratorExtProtobuf;
906
907        let bytes = vec![];
908        let iter = bytes.into_iter();
909        let fields: Vec<_> = iter
910            .protobuf_fields()
911            .collect::<::std::result::Result<Vec<_>, _>>()
912            .unwrap();
913        assert_eq!(fields.len(), 0);
914    }
915
916    // ============================================================================
917    // TryIteratorExtProtobuf tests
918    // ============================================================================
919
920    #[test]
921    fn test_try_iterator_ext_read_varint_field() {
922        use super::TryIteratorExtProtobuf;
923        use ::std::io::{Cursor, Read};
924
925        let data = vec![0x08, 0x96, 0x01]; // field 1: 150
926        let reader = Cursor::new(data);
927        let iter = reader.bytes();
928        let fields: Vec<_> = iter
929            .protobuf_fields()
930            .collect::<::std::result::Result<Vec<_>, _>>()
931            .unwrap();
932        assert_eq!(fields.len(), 1);
933        assert_eq!(fields[0].field_number.as_u32(), 1);
934        match &fields[0].value {
935            FieldValue::Varint(varint) => {
936                assert_eq!(varint.to_uint64(), 150);
937            }
938            _ => panic!("Expected Varint field"),
939        }
940    }
941
942    #[test]
943    fn test_try_iterator_ext_read_multiple_fields() {
944        use super::TryIteratorExtProtobuf;
945        use ::std::io::{Cursor, Read};
946
947        let data = vec![
948            0x08, 0x96, 0x01, // field 1: 150
949            0x12, 0x03, 0x48, 0x65, 0x6c, // field 2: "Hel"
950        ];
951        let reader = Cursor::new(data);
952        let iter = reader.bytes();
953        let fields: Vec<_> = iter
954            .protobuf_fields()
955            .collect::<::std::result::Result<Vec<_>, _>>()
956            .unwrap();
957        assert_eq!(fields.len(), 2);
958
959        // Check first field
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        // Check second field
969        assert_eq!(fields[1].field_number.as_u32(), 2);
970        match &fields[1].value {
971            FieldValue::Len(data) => {
972                assert_eq!(&data[..], b"Hel");
973            }
974            _ => panic!("Expected Len field"),
975        }
976    }
977
978    #[test]
979    fn test_try_iterator_ext_read_len_field() {
980        use super::TryIteratorExtProtobuf;
981        use ::std::io::{Cursor, Read};
982
983        let data = vec![0x12, 0x03, 0x48, 0x65, 0x6c]; // field 2: "Hel"
984        let reader = Cursor::new(data);
985        let iter = reader.bytes();
986        let fields: Vec<_> = iter
987            .protobuf_fields()
988            .collect::<::std::result::Result<Vec<_>, _>>()
989            .unwrap();
990        assert_eq!(fields.len(), 1);
991        assert_eq!(fields[0].field_number.as_u32(), 2);
992        match &fields[0].value {
993            FieldValue::Len(data) => {
994                assert_eq!(&data[..], b"Hel");
995            }
996            _ => panic!("Expected Len field"),
997        }
998    }
999
1000    #[test]
1001    fn test_try_iterator_ext_read_i32_field() {
1002        use super::TryIteratorExtProtobuf;
1003        use ::std::io::{Cursor, Read};
1004
1005        let data = vec![0x15, 0x78, 0x56, 0x34, 0x12]; // field 2: 0x12345678 (Fixed32)
1006        let reader = Cursor::new(data);
1007        let iter = reader.bytes();
1008        let fields: Vec<_> = iter
1009            .protobuf_fields()
1010            .collect::<::std::result::Result<Vec<_>, _>>()
1011            .unwrap();
1012        assert_eq!(fields.len(), 1);
1013        assert_eq!(fields[0].field_number.as_u32(), 2);
1014        match &fields[0].value {
1015            FieldValue::I32(bytes) => {
1016                assert_eq!(*bytes, [0x78, 0x56, 0x34, 0x12]);
1017            }
1018            _ => panic!("Expected I32 field"),
1019        }
1020    }
1021
1022    #[test]
1023    fn test_try_iterator_ext_read_i64_field() {
1024        use super::TryIteratorExtProtobuf;
1025        use ::std::io::{Cursor, Read};
1026
1027        let data = vec![0x19, 0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12]; // field 3: 0x1234567890ABCDEF (Fixed64)
1028        let reader = Cursor::new(data);
1029        let iter = reader.bytes();
1030        let fields: Vec<_> = iter
1031            .protobuf_fields()
1032            .collect::<::std::result::Result<Vec<_>, _>>()
1033            .unwrap();
1034        assert_eq!(fields.len(), 1);
1035        assert_eq!(fields[0].field_number.as_u32(), 3);
1036        match &fields[0].value {
1037            FieldValue::I64(bytes) => {
1038                assert_eq!(*bytes, [0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12]);
1039            }
1040            _ => panic!("Expected I64 field"),
1041        }
1042    }
1043
1044    #[test]
1045    fn test_try_iterator_ext_read_empty_stream() {
1046        use super::TryIteratorExtProtobuf;
1047        use ::std::io::{Cursor, Read};
1048
1049        let data = vec![];
1050        let reader = Cursor::new(data);
1051        let iter = reader.bytes();
1052        let fields: Vec<_> = iter
1053            .protobuf_fields()
1054            .collect::<::std::result::Result<Vec<_>, _>>()
1055            .unwrap();
1056        assert_eq!(fields.len(), 0);
1057    }
1058}