Skip to main content

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::context::{ReadContext, WriteContext};
19use crate::ensure;
20use crate::error::Error;
21use crate::meta::FieldInfo;
22use crate::resolver::{RefFlag, RefMode, TypeResolver};
23use crate::serializer::Serializer;
24use crate::type_id::TypeId;
25
26#[inline(always)]
27pub fn actual_type_id(_type_id: u32, register_by_name: bool, _compatible: bool) -> u32 {
28    if register_by_name {
29        TypeId::NAMED_ENUM as u32
30    } else {
31        TypeId::ENUM as u32
32    }
33}
34
35#[inline(always)]
36pub fn write<S: Serializer>(
37    value: &S::Target,
38    context: &mut WriteContext,
39    ref_mode: RefMode,
40    write_type_info: bool,
41) -> Result<(), Error> {
42    if ref_mode != RefMode::None {
43        context.writer.write_i8(RefFlag::NotNullValue as i8);
44    }
45    if write_type_info {
46        S::write_type_info(context)?;
47    }
48    S::write_data(value, context)
49}
50
51#[inline(always)]
52pub fn write_type_info<S: Serializer>(context: &mut WriteContext) -> Result<(), Error> {
53    let provider_type_id = std::any::TypeId::of::<S>();
54    let type_info = context
55        .get_type_resolver()
56        .get_provider_type_info(&provider_type_id)?;
57    let type_id = type_info.get_type_id();
58    context.writer.write_u8(type_id as u8);
59    if type_id == TypeId::ENUM {
60        context.writer.write_var_u32(type_info.get_user_type_id());
61        return Ok(());
62    }
63    if context.is_share_meta() {
64        // Write type meta inline using streaming protocol
65        context.write_type_meta(provider_type_id)?;
66    } else {
67        let namespace = type_info.get_namespace();
68        let type_name = type_info.get_type_name();
69        context.write_meta_string_bytes(namespace)?;
70        context.write_meta_string_bytes(type_name)?;
71    }
72    Ok(())
73}
74
75#[inline(always)]
76pub fn read<S: Serializer>(
77    context: &mut ReadContext,
78    ref_mode: RefMode,
79    read_type_info: bool,
80) -> Result<S::Target, Error> {
81    let ref_flag = if ref_mode != RefMode::None {
82        context.reader.read_i8()?
83    } else {
84        RefFlag::NotNullValue as i8
85    };
86    if ref_flag == RefFlag::Null as i8 {
87        S::default_value(context)
88    } else if ref_flag == (RefFlag::NotNullValue as i8) || ref_flag == (RefFlag::RefValue as i8) {
89        if read_type_info {
90            S::read_type_info(context)?;
91        }
92        S::read_data(context)
93    } else if ref_flag == (RefFlag::Ref as i8) {
94        Err(Error::invalid_ref("Invalid ref, enum type is not a ref"))
95    } else {
96        Err(Error::invalid_data(format!(
97            "Unknown ref flag: {}",
98            ref_flag
99        )))
100    }
101}
102
103#[inline(always)]
104pub fn read_type_info<S: Serializer>(context: &mut ReadContext) -> Result<(), Error> {
105    let local_type_id = context
106        .get_type_resolver()
107        .get_provider_type_info(&std::any::TypeId::of::<S>())?
108        .get_type_id();
109    let remote_type_id = context.reader.read_u8()?;
110    ensure!(
111        local_type_id as u8 == remote_type_id,
112        Error::type_mismatch(local_type_id as u32, remote_type_id as u32)
113    );
114    if remote_type_id == TypeId::NAMED_ENUM as u8 {
115        if context.is_share_meta() {
116            // Read type meta inline using streaming protocol
117            let _type_info = context.read_type_meta()?;
118        } else {
119            let _namespace_msb = context.read_meta_string()?;
120            let _type_name_msb = context.read_meta_string()?;
121        }
122    } else {
123        context.reader.read_var_u32()?;
124    }
125    Ok(())
126}
127
128pub trait NamedEnumVariantMetaTrait: 'static {
129    fn sorted_field_names() -> &'static [&'static str] {
130        &[]
131    }
132
133    #[allow(unused_variables)]
134    fn fields_info(type_resolver: &TypeResolver) -> Result<Vec<FieldInfo>, Error> {
135        Ok(Vec::default())
136    }
137}