fory_core/serializer/
enum_.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::resolver::context::{ReadContext, WriteContext};
21use crate::serializer::{ForyDefault, Serializer};
22use crate::types::{RefFlag, TypeId};
23
24#[inline(always)]
25pub fn actual_type_id(type_id: u32, register_by_name: bool, _compatible: bool) -> u32 {
26    if register_by_name {
27        TypeId::NAMED_ENUM as u32
28    } else {
29        (type_id << 8) + TypeId::ENUM as u32
30    }
31}
32
33#[inline(always)]
34pub fn write<T: Serializer>(
35    this: &T,
36    context: &mut WriteContext,
37    write_ref_info: bool,
38    write_type_info: bool,
39) -> Result<(), Error> {
40    if write_ref_info {
41        context.writer.write_i8(RefFlag::NotNullValue as i8);
42    }
43    if write_type_info {
44        T::fory_write_type_info(context)?;
45    }
46    this.fory_write_data(context)
47}
48
49#[inline(always)]
50pub fn write_type_info<T: Serializer>(context: &mut WriteContext) -> Result<(), Error> {
51    let type_id = T::fory_get_type_id(context.get_type_resolver())?;
52    context.writer.write_varuint32(type_id);
53    let is_named_enum = type_id & 0xff == TypeId::NAMED_ENUM as u32;
54    if !is_named_enum {
55        return Ok(());
56    }
57    let rs_type_id = std::any::TypeId::of::<T>();
58    if context.is_share_meta() {
59        let meta_index = context.push_meta(rs_type_id)? as u32;
60        context.writer.write_varuint32(meta_index);
61    } else {
62        let type_info = context.get_type_resolver().get_type_info(&rs_type_id)?;
63        let namespace = type_info.get_namespace();
64        let type_name = type_info.get_type_name();
65        context.write_meta_string_bytes(namespace)?;
66        context.write_meta_string_bytes(type_name)?;
67    }
68    Ok(())
69}
70
71#[inline(always)]
72pub fn read<T: Serializer + ForyDefault>(
73    context: &mut ReadContext,
74    read_ref_info: bool,
75    read_type_info: bool,
76) -> Result<T, Error> {
77    let ref_flag = if read_ref_info {
78        context.reader.read_i8()?
79    } else {
80        RefFlag::NotNullValue as i8
81    };
82    if ref_flag == RefFlag::Null as i8 {
83        Ok(T::fory_default())
84    } else if ref_flag == (RefFlag::NotNullValue as i8) || ref_flag == (RefFlag::RefValue as i8) {
85        if read_type_info {
86            T::fory_read_type_info(context)?;
87        }
88        T::fory_read_data(context)
89    } else if ref_flag == (RefFlag::Ref as i8) {
90        Err(Error::invalid_ref("Invalid ref, enum type is not a ref"))
91    } else {
92        Err(Error::invalid_data(format!(
93            "Unknown ref flag: {}",
94            ref_flag
95        )))
96    }
97}
98
99#[inline(always)]
100pub fn read_type_info<T: Serializer>(context: &mut ReadContext) -> Result<(), Error> {
101    let local_type_id = T::fory_get_type_id(context.get_type_resolver())?;
102    let remote_type_id = context.reader.read_varuint32()?;
103    ensure!(
104        local_type_id == remote_type_id,
105        Error::type_mismatch(local_type_id, remote_type_id)
106    );
107    let is_named_enum = local_type_id & 0xff == TypeId::NAMED_ENUM as u32;
108    if !is_named_enum {
109        return Ok(());
110    }
111    if context.is_share_meta() {
112        let _meta_index = context.reader.read_varuint32()?;
113    } else {
114        let _namespace_msb = context.read_meta_string()?;
115        let _type_name_msb = context.read_meta_string()?;
116    }
117    Ok(())
118}