Skip to main content

fory_core/serializer/
skip.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use crate::ensure;
19use crate::error::Error;
20use crate::meta::FieldType;
21use crate::resolver::context::ReadContext;
22use crate::serializer::collection::{DECL_ELEMENT_TYPE, HAS_NULL, IS_SAME_TYPE};
23use crate::serializer::util;
24use crate::serializer::Serializer;
25use crate::types;
26use crate::types::RefFlag;
27use crate::util::ENABLE_FORY_DEBUG_OUTPUT;
28use chrono::{NaiveDate, NaiveDateTime};
29use std::rc::Rc;
30use std::time::Duration;
31
32#[allow(unreachable_code)]
33pub fn skip_field_value(
34    context: &mut ReadContext,
35    field_type: &FieldType,
36    read_ref_flag: bool,
37) -> Result<(), Error> {
38    skip_value(context, field_type, read_ref_flag, true, &None)
39}
40
41const UNKNOWN_FIELD_TYPE: FieldType = FieldType {
42    type_id: types::UNKNOWN,
43    user_type_id: u32::MAX,
44    nullable: true,
45    track_ref: false,
46    generics: vec![],
47};
48
49pub fn skip_any_value(context: &mut ReadContext, read_ref_flag: bool) -> Result<(), Error> {
50    // Handle ref flag first if needed
51    if read_ref_flag {
52        let ref_flag = context.reader.read_i8()?;
53        if ref_flag == (RefFlag::Null as i8) {
54            return Ok(());
55        }
56        if ref_flag == (RefFlag::Ref as i8) {
57            // Reference to already-seen object, skip the reference index
58            let _ref_index = context.reader.read_varuint32()?;
59            return Ok(());
60        }
61        // RefValue (0) or NotNullValue (-1) means we need to read the actual object
62    }
63
64    // Read type_id first
65    let type_id = context.reader.read_u8()? as u32;
66    let internal_id = type_id;
67    let _user_type_id = if types::needs_user_type_id(type_id) && type_id != types::COMPATIBLE_STRUCT
68    {
69        Some(context.reader.read_varuint32()?)
70    } else {
71        None
72    };
73
74    // NONE type has no data - return early
75    if internal_id == types::NONE {
76        return Ok(());
77    }
78
79    // For struct-like types, also read meta_index to get type_info
80    // This is critical for polymorphic collections where elements are struct types.
81    let (field_type, type_info_opt) = match internal_id {
82        types::LIST | types::SET => (
83            FieldType {
84                type_id,
85                user_type_id: u32::MAX,
86                nullable: true,
87                track_ref: false,
88                generics: vec![UNKNOWN_FIELD_TYPE],
89            },
90            None,
91        ),
92        types::MAP => (
93            FieldType {
94                type_id,
95                user_type_id: u32::MAX,
96                nullable: true,
97                track_ref: false,
98                generics: vec![UNKNOWN_FIELD_TYPE, UNKNOWN_FIELD_TYPE],
99            },
100            None,
101        ),
102        types::COMPATIBLE_STRUCT | types::NAMED_COMPATIBLE_STRUCT => {
103            // For compatible struct types, read type meta inline using streaming protocol
104            let type_info = context.read_type_meta()?;
105            (
106                FieldType {
107                    type_id,
108                    user_type_id: u32::MAX,
109                    nullable: true,
110                    track_ref: false,
111                    generics: vec![],
112                },
113                Some(type_info),
114            )
115        }
116        types::NAMED_ENUM | types::NAMED_EXT | types::NAMED_STRUCT | types::NAMED_UNION => {
117            if context.is_share_meta() {
118                let type_info = context.read_type_meta()?;
119                (
120                    FieldType {
121                        type_id,
122                        user_type_id: u32::MAX,
123                        nullable: true,
124                        track_ref: false,
125                        generics: vec![],
126                    },
127                    Some(type_info),
128                )
129            } else {
130                let namespace = context.read_meta_string()?.to_owned();
131                let type_name = context.read_meta_string()?.to_owned();
132                let rc_namespace = Rc::from(namespace);
133                let rc_type_name = Rc::from(type_name);
134                let type_info = context
135                    .get_type_resolver()
136                    .get_type_info_by_meta_string_name(rc_namespace, rc_type_name)
137                    .ok_or_else(|| crate::Error::type_error("Name harness not found"))?;
138                (
139                    FieldType {
140                        type_id,
141                        user_type_id: u32::MAX,
142                        nullable: true,
143                        track_ref: false,
144                        generics: vec![],
145                    },
146                    Some(type_info),
147                )
148            }
149        }
150        _ => {
151            let type_info = if let Some(user_type_id) = _user_type_id {
152                context
153                    .get_type_resolver()
154                    .get_user_type_info_by_id(user_type_id)
155            } else {
156                None
157            };
158            (
159                FieldType {
160                    type_id,
161                    user_type_id: _user_type_id.unwrap_or(u32::MAX),
162                    nullable: true,
163                    track_ref: false,
164                    generics: vec![],
165                },
166                type_info,
167            )
168        }
169    };
170    // Don't read ref flag again in skip_value since we already handled it.
171    // Pass type_info so skip_struct doesn't try to read type_id/meta_index again.
172    skip_value(context, &field_type, false, false, &type_info_opt)
173}
174
175fn skip_collection(context: &mut ReadContext, field_type: &FieldType) -> Result<(), Error> {
176    let length = context.reader.read_varuint32()? as usize;
177    if length == 0 {
178        return Ok(());
179    }
180    let header = context.reader.read_u8()?;
181    let has_null = (header & HAS_NULL) != 0;
182    let is_same_type = (header & IS_SAME_TYPE) != 0;
183    let skip_ref_flag = is_same_type && !has_null;
184    let is_declared = (header & DECL_ELEMENT_TYPE) != 0;
185    let default_elem_type = field_type.generics.first().unwrap();
186    let (type_info, elem_field_type);
187    let elem_type = if is_same_type && !is_declared {
188        let type_info_rc = context.read_any_type_info()?;
189        elem_field_type = FieldType {
190            type_id: type_info_rc.get_type_id() as u32,
191            user_type_id: type_info_rc.get_user_type_id(),
192            nullable: has_null,
193            track_ref: false,
194            generics: vec![],
195        };
196        type_info = Some(type_info_rc);
197        &elem_field_type
198    } else {
199        type_info = None;
200        default_elem_type
201    };
202    context.inc_depth()?;
203    for _ in 0..length {
204        skip_value(context, elem_type, !skip_ref_flag, false, &type_info)?;
205    }
206    context.dec_depth();
207    Ok(())
208}
209
210fn skip_map(context: &mut ReadContext, field_type: &FieldType) -> Result<(), Error> {
211    let length = context.reader.read_varuint32()?;
212    if length == 0 {
213        return Ok(());
214    }
215    let mut len_counter = 0;
216    let default_key_type = field_type.generics.first().unwrap();
217    let default_value_type = field_type.generics.get(1).unwrap();
218    loop {
219        if len_counter == length {
220            break;
221        }
222        let header = context.reader.read_u8()?;
223        if header & crate::serializer::map::KEY_NULL != 0
224            && header & crate::serializer::map::VALUE_NULL != 0
225        {
226            len_counter += 1;
227            continue;
228        }
229        if header & crate::serializer::map::KEY_NULL != 0 {
230            // Read value type info if not declared
231            let value_declared = (header & crate::serializer::map::DECL_VALUE_TYPE) != 0;
232            let (value_type_info, value_field_type);
233            let value_type = if !value_declared {
234                let type_info = context.read_any_type_info()?;
235                value_field_type = FieldType {
236                    type_id: type_info.get_type_id() as u32,
237                    user_type_id: type_info.get_user_type_id(),
238                    nullable: true,
239                    track_ref: false,
240                    generics: vec![],
241                };
242                value_type_info = Some(type_info);
243                &value_field_type
244            } else {
245                value_type_info = None;
246                default_value_type
247            };
248            context.inc_depth()?;
249            skip_value(context, value_type, false, false, &value_type_info)?;
250            context.dec_depth();
251            len_counter += 1;
252            continue;
253        }
254        if header & crate::serializer::map::VALUE_NULL != 0 {
255            // Read key type info if not declared
256            let key_declared = (header & crate::serializer::map::DECL_KEY_TYPE) != 0;
257            let (key_type_info, key_field_type);
258            let key_type = if !key_declared {
259                let type_info = context.read_any_type_info()?;
260                key_field_type = FieldType {
261                    type_id: type_info.get_type_id() as u32,
262                    user_type_id: type_info.get_user_type_id(),
263                    nullable: true,
264                    track_ref: false,
265                    generics: vec![],
266                };
267                key_type_info = Some(type_info);
268                &key_field_type
269            } else {
270                key_type_info = None;
271                default_key_type
272            };
273            context.inc_depth()?;
274            skip_value(context, key_type, false, false, &key_type_info)?;
275            context.dec_depth();
276            len_counter += 1;
277            continue;
278        }
279        // Both key and value are non-null
280        let chunk_size = context.reader.read_u8()?;
281        let key_declared = (header & crate::serializer::map::DECL_KEY_TYPE) != 0;
282        let value_declared = (header & crate::serializer::map::DECL_VALUE_TYPE) != 0;
283
284        // Read key type info if not declared
285        let (key_type_info, key_field_type);
286        let key_type = if !key_declared {
287            let type_info = context.read_any_type_info()?;
288            key_field_type = FieldType {
289                type_id: type_info.get_type_id() as u32,
290                user_type_id: type_info.get_user_type_id(),
291                nullable: true,
292                track_ref: false,
293                generics: vec![],
294            };
295            key_type_info = Some(type_info);
296            &key_field_type
297        } else {
298            key_type_info = None;
299            default_key_type
300        };
301
302        // Read value type info if not declared
303        let (value_type_info, value_field_type);
304        let value_type = if !value_declared {
305            let type_info = context.read_any_type_info()?;
306            value_field_type = FieldType {
307                type_id: type_info.get_type_id() as u32,
308                user_type_id: type_info.get_user_type_id(),
309                nullable: true,
310                track_ref: false,
311                generics: vec![],
312            };
313            value_type_info = Some(type_info);
314            &value_field_type
315        } else {
316            value_type_info = None;
317            default_value_type
318        };
319
320        context.inc_depth()?;
321        for _ in 0..chunk_size {
322            skip_value(context, key_type, false, false, &key_type_info)?;
323            skip_value(context, value_type, false, false, &value_type_info)?;
324        }
325        context.dec_depth();
326        len_counter += chunk_size as u32;
327    }
328    Ok(())
329}
330
331fn skip_struct(
332    context: &mut ReadContext,
333    type_id_num: u32,
334    type_info: &Option<Rc<crate::TypeInfo>>,
335) -> Result<(), Error> {
336    let type_info_rc: Option<Rc<crate::TypeInfo>>;
337    let type_info_value = if type_info.is_none() {
338        let remote_type_info = context.read_any_type_info()?;
339        let remote_type_id = remote_type_info.get_type_id() as u32;
340        if type_id_num != types::UNKNOWN && remote_type_id != types::UNKNOWN {
341            ensure!(
342                type_id_num == remote_type_id,
343                Error::type_mismatch(type_id_num, remote_type_id)
344            );
345        }
346        type_info_rc = Some(remote_type_info);
347        type_info_rc.as_ref().unwrap()
348    } else {
349        type_info.as_ref().unwrap()
350    };
351    let type_meta = type_info_value.get_type_meta();
352    if ENABLE_FORY_DEBUG_OUTPUT {
353        eprintln!(
354            "[skip_struct] type_name: {:?}, num_fields: {}",
355            type_meta.get_type_name(),
356            type_meta.get_field_infos().len()
357        );
358    }
359    let field_infos = type_meta.get_field_infos().to_vec();
360    context.inc_depth()?;
361    for field_info in field_infos.iter() {
362        if ENABLE_FORY_DEBUG_OUTPUT {
363            eprintln!(
364                "[skip_struct] field: {:?}, type_id: {}, internal_id: {}",
365                field_info.field_name, field_info.field_type.type_id, field_info.field_type.type_id
366            );
367        }
368        let read_ref_flag = util::field_need_write_ref_into(
369            field_info.field_type.type_id,
370            field_info.field_type.nullable,
371        );
372        skip_value(context, &field_info.field_type, read_ref_flag, true, &None)?;
373    }
374    context.dec_depth();
375    Ok(())
376}
377
378fn skip_ext(
379    context: &mut ReadContext,
380    type_id_num: u32,
381    type_info: &Option<Rc<crate::TypeInfo>>,
382) -> Result<(), Error> {
383    let type_info_rc: Option<Rc<crate::TypeInfo>>;
384    let type_info_value = if type_info.is_none() {
385        let remote_type_info = context.read_any_type_info()?;
386        let remote_type_id = remote_type_info.get_type_id() as u32;
387        ensure!(
388            type_id_num == remote_type_id,
389            Error::type_mismatch(type_id_num, remote_type_id)
390        );
391        type_info_rc = Some(remote_type_info);
392        type_info_rc.as_ref().unwrap()
393    } else {
394        type_info.as_ref().unwrap()
395    };
396    type_info_value.get_harness().get_read_data_fn()(context)?;
397    Ok(())
398}
399
400// call when is_field && is_compatible_mode
401#[allow(unreachable_code)]
402fn skip_value(
403    context: &mut ReadContext,
404    field_type: &FieldType,
405    read_ref_flag: bool,
406    _is_field: bool,
407    type_info: &Option<Rc<crate::TypeInfo>>,
408) -> Result<(), Error> {
409    if read_ref_flag {
410        let ref_flag = context.reader.read_i8()?;
411        if ref_flag == (RefFlag::Null as i8) {
412            return Ok(());
413        }
414        if ref_flag == (RefFlag::Ref as i8) {
415            // Reference to already-seen object, skip the reference index
416            let _ref_index = context.reader.read_varuint32()?;
417            return Ok(());
418        }
419        // RefValue (0) or NotNullValue (-1) means we need to read the actual object
420    }
421    let type_id_num = field_type.type_id;
422
423    if type_id_num == types::UNKNOWN {
424        return skip_any_value(context, false);
425    }
426
427    // Handle user-defined types (struct/enum/ext/union)
428    if types::is_user_type(type_id_num) {
429        if type_id_num == types::COMPATIBLE_STRUCT
430            || type_id_num == types::STRUCT
431            || type_id_num == types::NAMED_STRUCT
432            || type_id_num == types::NAMED_COMPATIBLE_STRUCT
433        {
434            return skip_struct(context, type_id_num, type_info);
435        } else if type_id_num == types::ENUM
436            || type_id_num == types::NAMED_ENUM
437            || type_id_num == types::UNION
438            || type_id_num == types::TYPED_UNION
439            || type_id_num == types::NAMED_UNION
440        {
441            let _ordinal = context.reader.read_varuint32()?;
442            return Ok(());
443        } else if type_id_num == types::EXT || type_id_num == types::NAMED_EXT {
444            return skip_ext(context, type_id_num, type_info);
445        } else {
446            return Err(Error::type_error(format!(
447                "Unknown type id: {} (type_info provided: {})",
448                type_id_num,
449                type_info.is_some()
450            )));
451        }
452    }
453
454    // Match on built-in types (ordered by TypeId enum values)
455    match type_id_num {
456        // ============ UNKNOWN (TypeId = 0) ============
457        types::UNKNOWN => {
458            // UNKNOWN is used for polymorphic types in cross-language serialization
459            return skip_any_value(context, false);
460        }
461
462        // ============ BOOL (TypeId = 1) ============
463        types::BOOL => {
464            <bool as Serializer>::fory_read_data(context)?;
465        }
466
467        // ============ INT8 (TypeId = 2) ============
468        types::INT8 => {
469            <i8 as Serializer>::fory_read_data(context)?;
470        }
471
472        // ============ INT16 (TypeId = 3) ============
473        types::INT16 => {
474            <i16 as Serializer>::fory_read_data(context)?;
475        }
476
477        // ============ INT32 (TypeId = 4) ============
478        types::INT32 => {
479            context.reader.read_i32()?;
480        }
481
482        // ============ VARINT32 (TypeId = 5) ============
483        types::VARINT32 => {
484            <i32 as Serializer>::fory_read_data(context)?;
485        }
486
487        // ============ INT64 (TypeId = 6) ============
488        types::INT64 => {
489            context.reader.read_i64()?;
490        }
491
492        // ============ VARINT64 (TypeId = 7) ============
493        types::VARINT64 => {
494            <i64 as Serializer>::fory_read_data(context)?;
495        }
496
497        // ============ TAGGED_INT64 (TypeId = 8) ============
498        types::TAGGED_INT64 => {
499            context.reader.read_tagged_i64()?;
500        }
501
502        // ============ UINT8 (TypeId = 9) ============
503        types::UINT8 => {
504            <u8 as Serializer>::fory_read_data(context)?;
505        }
506
507        // ============ UINT16 (TypeId = 10) ============
508        types::UINT16 => {
509            <u16 as Serializer>::fory_read_data(context)?;
510        }
511
512        // ============ UINT32 (TypeId = 11) ============
513        types::UINT32 => {
514            context.reader.read_u32()?;
515        }
516
517        // ============ VAR_UINT32 (TypeId = 12) ============
518        types::VAR_UINT32 => {
519            <u32 as Serializer>::fory_read_data(context)?;
520        }
521
522        // ============ UINT64 (TypeId = 13) ============
523        types::UINT64 => {
524            context.reader.read_u64()?;
525        }
526
527        // ============ VAR_UINT64 (TypeId = 14) ============
528        types::VAR_UINT64 => {
529            <u64 as Serializer>::fory_read_data(context)?;
530        }
531
532        // ============ TAGGED_UINT64 (TypeId = 15) ============
533        types::TAGGED_UINT64 => {
534            context.reader.read_tagged_u64()?;
535        }
536
537        // ============ FLOAT32 (TypeId = 17) ============
538        types::FLOAT32 => {
539            <f32 as Serializer>::fory_read_data(context)?;
540        }
541
542        // ============ FLOAT64 (TypeId = 18) ============
543        types::FLOAT64 => {
544            <f64 as Serializer>::fory_read_data(context)?;
545        }
546
547        // ============ STRING (TypeId = 19) ============
548        types::STRING => {
549            <String as Serializer>::fory_read_data(context)?;
550        }
551
552        // ============ LIST (TypeId = 20) ============
553        // ============ SET (TypeId = 21) ============
554        types::LIST | types::SET => {
555            return skip_collection(context, field_type);
556        }
557
558        // ============ MAP (TypeId = 22) ============
559        types::MAP => {
560            return skip_map(context, field_type);
561        }
562
563        // ============ ENUM (TypeId = 23) ============
564        types::ENUM => {
565            let _ordinal = context.reader.read_varuint32()?;
566        }
567
568        // ============ NAMED_ENUM (TypeId = 24) ============
569        types::NAMED_ENUM => {
570            let _ordinal = context.reader.read_varuint32()?;
571        }
572
573        // ============ STRUCT (TypeId = 25) ============
574        types::STRUCT => {
575            return skip_struct(context, type_id_num, type_info);
576        }
577
578        // ============ COMPATIBLE_STRUCT (TypeId = 26) ============
579        types::COMPATIBLE_STRUCT => {
580            return skip_struct(context, type_id_num, type_info);
581        }
582
583        // ============ NAMED_STRUCT (TypeId = 27) ============
584        types::NAMED_STRUCT => {
585            return skip_struct(context, type_id_num, type_info);
586        }
587
588        // ============ NAMED_COMPATIBLE_STRUCT (TypeId = 28) ============
589        types::NAMED_COMPATIBLE_STRUCT => {
590            return skip_struct(context, type_id_num, type_info);
591        }
592
593        // ============ EXT (TypeId = 29) ============
594        types::EXT => {
595            return skip_ext(context, type_id_num, type_info);
596        }
597
598        // ============ NAMED_EXT (TypeId = 30) ============
599        types::NAMED_EXT => {
600            return skip_ext(context, type_id_num, type_info);
601        }
602
603        // ============ UNION (TypeId = 31) ============
604        types::UNION => {
605            let _ = context.reader.read_varuint32()?;
606            return skip_any_value(context, true);
607        }
608
609        // ============ TYPED_UNION (TypeId = 32) ============
610        types::TYPED_UNION => {
611            let _ = context.reader.read_varuint32()?;
612            return skip_any_value(context, true);
613        }
614
615        // ============ NAMED_UNION (TypeId = 33) ============
616        types::NAMED_UNION => {
617            let _ = context.reader.read_varuint32()?;
618            return skip_any_value(context, true);
619        }
620
621        // ============ NONE (TypeId = 34) ============
622        types::NONE => {
623            return Ok(());
624        }
625
626        // ============ DURATION (TypeId = 35) ============
627        types::DURATION => {
628            <Duration as Serializer>::fory_read_data(context)?;
629        }
630
631        // ============ TIMESTAMP (TypeId = 36) ============
632        types::TIMESTAMP => {
633            <NaiveDateTime as Serializer>::fory_read_data(context)?;
634        }
635
636        // ============ DATE (TypeId = 37) ============
637        types::DATE => {
638            <NaiveDate as Serializer>::fory_read_data(context)?;
639        }
640
641        // ============ BINARY (TypeId = 39) ============
642        types::BINARY => {
643            <Vec<u8> as Serializer>::fory_read_data(context)?;
644        }
645
646        // ============ BOOL_ARRAY (TypeId = 41) ============
647        types::BOOL_ARRAY => {
648            <Vec<bool> as Serializer>::fory_read_data(context)?;
649        }
650
651        // ============ INT8_ARRAY (TypeId = 42) ============
652        types::INT8_ARRAY => {
653            <Vec<i8> as Serializer>::fory_read_data(context)?;
654        }
655
656        // ============ INT16_ARRAY (TypeId = 43) ============
657        types::INT16_ARRAY => {
658            <Vec<i16> as Serializer>::fory_read_data(context)?;
659        }
660
661        // ============ INT32_ARRAY (TypeId = 44) ============
662        types::INT32_ARRAY => {
663            <Vec<i32> as Serializer>::fory_read_data(context)?;
664        }
665
666        // ============ INT64_ARRAY (TypeId = 45) ============
667        types::INT64_ARRAY => {
668            <Vec<i64> as Serializer>::fory_read_data(context)?;
669        }
670
671        // ============ UINT8_ARRAY (TypeId = 46) ============
672        types::UINT8_ARRAY => {
673            <Vec<u8> as Serializer>::fory_read_data(context)?;
674        }
675
676        // ============ UINT16_ARRAY (TypeId = 47) ============
677        types::UINT16_ARRAY => {
678            <Vec<u16> as Serializer>::fory_read_data(context)?;
679        }
680
681        // ============ UINT32_ARRAY (TypeId = 48) ============
682        types::UINT32_ARRAY => {
683            <Vec<u32> as Serializer>::fory_read_data(context)?;
684        }
685
686        // ============ UINT64_ARRAY (TypeId = 49) ============
687        types::UINT64_ARRAY => {
688            <Vec<u64> as Serializer>::fory_read_data(context)?;
689        }
690
691        // ============ FLOAT32_ARRAY (TypeId = 51) ============
692        types::FLOAT32_ARRAY => {
693            <Vec<f32> as Serializer>::fory_read_data(context)?;
694        }
695
696        // ============ FLOAT64_ARRAY (TypeId = 52) ============
697        types::FLOAT64_ARRAY => {
698            <Vec<f64> as Serializer>::fory_read_data(context)?;
699        }
700
701        // ============ Rust-specific types ============
702
703        // ============ U128 (TypeId = 64) ============
704        types::U128 => {
705            <u128 as Serializer>::fory_read_data(context)?;
706        }
707
708        // ============ INT128 (TypeId = 65) ============
709        types::INT128 => {
710            <i128 as Serializer>::fory_read_data(context)?;
711        }
712
713        // ============ USIZE (TypeId = 66) ============
714        types::USIZE => {
715            <usize as Serializer>::fory_read_data(context)?;
716        }
717
718        // ============ ISIZE (TypeId = 67) ============
719        types::ISIZE => {
720            <isize as Serializer>::fory_read_data(context)?;
721        }
722
723        // ============ U128_ARRAY (TypeId = 68) ============
724        types::U128_ARRAY => {
725            <Vec<u128> as Serializer>::fory_read_data(context)?;
726        }
727
728        // ============ INT128_ARRAY (TypeId = 69) ============
729        types::INT128_ARRAY => {
730            <Vec<i128> as Serializer>::fory_read_data(context)?;
731        }
732
733        // ============ USIZE_ARRAY (TypeId = 70) ============
734        types::USIZE_ARRAY => {
735            <Vec<usize> as Serializer>::fory_read_data(context)?;
736        }
737
738        // ============ ISIZE_ARRAY (TypeId = 71) ============
739        types::ISIZE_ARRAY => {
740            <Vec<isize> as Serializer>::fory_read_data(context)?;
741        }
742
743        _ => {
744            return Err(Error::type_error(format!(
745                "Unimplemented type id: {}",
746                type_id_num
747            )));
748        }
749    }
750    Ok(())
751}
752
753/// Skip enum variant data in compatible mode based on variant type.
754///
755/// # Arguments
756/// * `context` - The read context
757/// * `variant_type` - The variant type encoded in lower 2 bits:
758///   - 0b0 = Unit variant (no data to skip)
759///   - 0b1 = Unnamed variant (tuple data)
760///   - 0b10 = Named variant (struct-like data)
761/// * `type_info` - Optional type info for named variants (must be provided for 0b10)
762pub fn skip_enum_variant(
763    context: &mut ReadContext,
764    variant_type: u32,
765    type_info: &Option<Rc<crate::TypeInfo>>,
766) -> Result<(), Error> {
767    match variant_type {
768        0b0 => {
769            // Unit variant, no data to skip
770            Ok(())
771        }
772        0b1 => {
773            // Unnamed variant, skip tuple data (which is serialized as a collection)
774            // Tuple uses collection format but doesn't write type info, so skip directly
775            let field_type = FieldType {
776                type_id: types::LIST,
777                user_type_id: u32::MAX,
778                nullable: false,
779                track_ref: false,
780                generics: vec![UNKNOWN_FIELD_TYPE],
781            };
782            skip_collection(context, &field_type)
783        }
784        0b10 => {
785            // Named variant, skip struct-like data using skip_struct
786            // For named variants, we need the type_info which should have been read already
787            if type_info.is_some() {
788                let type_id = type_info.as_ref().unwrap().get_type_id() as u32;
789                skip_struct(context, type_id, type_info)
790            } else {
791                // If no type_info provided, read it inline using streaming protocol
792                let type_info_rc = context.read_type_meta()?;
793                let type_id = type_info_rc.get_type_id() as u32;
794                let type_info_opt = Some(type_info_rc);
795                skip_struct(context, type_id, &type_info_opt)
796            }
797        }
798        _ => {
799            // Invalid variant type
800            Err(Error::type_error(format!(
801                "Invalid enum variant type: {}",
802                variant_type
803            )))
804        }
805    }
806}