mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-05-02 05:34:46 +00:00
protocols: add support for Serde
rust-protobuf@3 does not support Serde natively anymore. So we need to do it by ourselves. Signed-off-by: Tim Zhang <tim@hyper.sh>
This commit is contained in:
parent
a6b4d92c84
commit
59568c79dd
1
src/libs/protocols/.gitignore
vendored
1
src/libs/protocols/.gitignore
vendored
@ -3,3 +3,4 @@ Cargo.lock
|
|||||||
src/*.rs
|
src/*.rs
|
||||||
!src/lib.rs
|
!src/lib.rs
|
||||||
!src/trans.rs
|
!src/trans.rs
|
||||||
|
!src/serde_config.rs
|
||||||
|
@ -8,7 +8,45 @@ use std::io::{BufRead, BufReader, Read, Write};
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
|
|
||||||
use ttrpc_codegen::{Codegen, Customize, ProtobufCustomize};
|
use protobuf::{
|
||||||
|
descriptor::field_descriptor_proto::Type,
|
||||||
|
reflect::{EnumDescriptor, FieldDescriptor, MessageDescriptor, OneofDescriptor},
|
||||||
|
};
|
||||||
|
use ttrpc_codegen::{Codegen, Customize, ProtobufCustomize, ProtobufCustomizeCallback};
|
||||||
|
|
||||||
|
struct GenSerde;
|
||||||
|
|
||||||
|
impl ProtobufCustomizeCallback for GenSerde {
|
||||||
|
fn message(&self, _message: &MessageDescriptor) -> ProtobufCustomize {
|
||||||
|
ProtobufCustomize::default().before("#[cfg_attr(feature = \"with-serde\", derive(::serde::Serialize, ::serde::Deserialize))]")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn enumeration(&self, _enum_type: &EnumDescriptor) -> ProtobufCustomize {
|
||||||
|
ProtobufCustomize::default().before("#[cfg_attr(feature = \"with-serde\", derive(::serde::Serialize, ::serde::Deserialize))]")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn oneof(&self, _oneof: &OneofDescriptor) -> ProtobufCustomize {
|
||||||
|
ProtobufCustomize::default().before("#[cfg_attr(feature = \"with-serde\", derive(::serde::Serialize, ::serde::Deserialize))]")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn field(&self, field: &FieldDescriptor) -> ProtobufCustomize {
|
||||||
|
if field.proto().type_() == Type::TYPE_ENUM {
|
||||||
|
ProtobufCustomize::default().before(
|
||||||
|
"#[cfg_attr(feature = \"with-serde\", serde(serialize_with = \"crate::serialize_enum_or_unknown\", deserialize_with = \"crate::deserialize_enum_or_unknown\"))]",
|
||||||
|
)
|
||||||
|
} else if field.proto().type_() == Type::TYPE_MESSAGE && field.is_singular() {
|
||||||
|
ProtobufCustomize::default().before(
|
||||||
|
"#[cfg_attr(feature = \"with-serde\", serde(serialize_with = \"crate::serialize_message_field\", deserialize_with = \"crate::deserialize_message_field\"))]",
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
ProtobufCustomize::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn special_field(&self, _message: &MessageDescriptor, _field: &str) -> ProtobufCustomize {
|
||||||
|
ProtobufCustomize::default().before("#[cfg_attr(feature = \"with-serde\", serde(skip))]")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn replace_text_in_file(file_name: &str, from: &str, to: &str) -> Result<(), std::io::Error> {
|
fn replace_text_in_file(file_name: &str, from: &str, to: &str) -> Result<(), std::io::Error> {
|
||||||
let mut src = File::open(file_name)?;
|
let mut src = File::open(file_name)?;
|
||||||
|
@ -17,5 +17,13 @@ pub mod health_ttrpc;
|
|||||||
#[cfg(feature = "async")]
|
#[cfg(feature = "async")]
|
||||||
pub mod health_ttrpc_async;
|
pub mod health_ttrpc_async;
|
||||||
pub mod oci;
|
pub mod oci;
|
||||||
|
#[cfg(feature = "with-serde")]
|
||||||
|
mod serde_config;
|
||||||
pub mod trans;
|
pub mod trans;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
|
||||||
|
#[cfg(feature = "with-serde")]
|
||||||
|
pub use serde_config::{
|
||||||
|
deserialize_enum_or_unknown, deserialize_message_field, serialize_enum_or_unknown,
|
||||||
|
serialize_message_field,
|
||||||
|
};
|
||||||
|
38
src/libs/protocols/src/serde_config.rs
Normal file
38
src/libs/protocols/src/serde_config.rs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright (c) 2023 Ant Group
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
use protobuf::{EnumOrUnknown, MessageField};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[cfg(feature = "with-serde")]
|
||||||
|
pub fn serialize_enum_or_unknown<E: protobuf::EnumFull, S: serde::Serializer>(
|
||||||
|
e: &protobuf::EnumOrUnknown<E>,
|
||||||
|
s: S,
|
||||||
|
) -> Result<S::Ok, S::Error> {
|
||||||
|
e.value().serialize(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn serialize_message_field<E: Serialize, S: serde::Serializer>(
|
||||||
|
e: &protobuf::MessageField<E>,
|
||||||
|
s: S,
|
||||||
|
) -> Result<S::Ok, S::Error> {
|
||||||
|
if e.is_some() {
|
||||||
|
e.as_ref().unwrap().serialize(s)
|
||||||
|
} else {
|
||||||
|
s.serialize_unit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deserialize_enum_or_unknown<'de, E: Deserialize<'de>, D: serde::Deserializer<'de>>(
|
||||||
|
d: D,
|
||||||
|
) -> Result<protobuf::EnumOrUnknown<E>, D::Error> {
|
||||||
|
i32::deserialize(d).map(EnumOrUnknown::from_i32)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deserialize_message_field<'de, E: Deserialize<'de>, D: serde::Deserializer<'de>>(
|
||||||
|
d: D,
|
||||||
|
) -> Result<protobuf::MessageField<E>, D::Error> {
|
||||||
|
Option::deserialize(d).map(MessageField::from_option)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user