如何使用 Serde 在序列化期间转换字段?
How to transform fields during serialization using Serde?
如何在序列化之前对字段应用转换?
例如,如何确保这个结构体定义中的字段lat
和lon
在被序列化之前四舍五入到最多6位小数?
#[derive(Debug, Serialize)]
struct NodeLocation {
#[serde(rename = "nodeId")]
id: u32,
lat: f32,
lon: f32,
}
serialize_with
属性
您可以将 serialize_with
attribute to provide a custom serialization function 用于您的字段:
use serde::{Serialize, Serializer}; // 1.0.104
fn round_serialize<S>(x: &f32, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
s.serialize_f32(x.round())
}
#[derive(Debug, Serialize)]
pub struct NodeLocation {
#[serde(rename = "nodeId")]
id: u32,
#[serde(serialize_with = "round_serialize")]
lat: f32,
#[serde(serialize_with = "round_serialize")]
lon: f32,
}
(我四舍五入到最接近的整数以避免话题"what is best way to round a float to k decimal places")。
实施serde::Serialize
另一种半手动方法是创建一个具有自动派生序列化的单独结构,并使用它实现序列化:
use serde::{Serialize, Serializer}; // 1.0.104
#[derive(Debug)]
pub struct NodeLocation {
id: u32,
lat: f32,
lon: f32,
}
impl serde::Serialize for NodeLocation {
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
// Implement your preprocessing in `from`.
RoundedNodeLocation::from(self).serialize(s)
}
}
#[derive(Debug, Serialize)]
pub struct RoundedNodeLocation {
#[serde(rename = "nodeId")]
id: u32,
lat: f32,
lon: f32,
}
impl<'a> From<&'a NodeLocation> for RoundedNodeLocation {
fn from(other: &'a NodeLocation) -> Self {
Self {
id: other.id,
lat: other.lat.round(),
lon: other.lon.round(),
}
}
}
值得注意的是,这还允许您添加或删除字段,因为 "inner" 序列化类型基本上可以做任何它想做的事情。
如何在序列化之前对字段应用转换?
例如,如何确保这个结构体定义中的字段lat
和lon
在被序列化之前四舍五入到最多6位小数?
#[derive(Debug, Serialize)]
struct NodeLocation {
#[serde(rename = "nodeId")]
id: u32,
lat: f32,
lon: f32,
}
serialize_with
属性
您可以将 serialize_with
attribute to provide a custom serialization function 用于您的字段:
use serde::{Serialize, Serializer}; // 1.0.104
fn round_serialize<S>(x: &f32, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
s.serialize_f32(x.round())
}
#[derive(Debug, Serialize)]
pub struct NodeLocation {
#[serde(rename = "nodeId")]
id: u32,
#[serde(serialize_with = "round_serialize")]
lat: f32,
#[serde(serialize_with = "round_serialize")]
lon: f32,
}
(我四舍五入到最接近的整数以避免话题"what is best way to round a float to k decimal places")。
实施serde::Serialize
另一种半手动方法是创建一个具有自动派生序列化的单独结构,并使用它实现序列化:
use serde::{Serialize, Serializer}; // 1.0.104
#[derive(Debug)]
pub struct NodeLocation {
id: u32,
lat: f32,
lon: f32,
}
impl serde::Serialize for NodeLocation {
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
// Implement your preprocessing in `from`.
RoundedNodeLocation::from(self).serialize(s)
}
}
#[derive(Debug, Serialize)]
pub struct RoundedNodeLocation {
#[serde(rename = "nodeId")]
id: u32,
lat: f32,
lon: f32,
}
impl<'a> From<&'a NodeLocation> for RoundedNodeLocation {
fn from(other: &'a NodeLocation) -> Self {
Self {
id: other.id,
lat: other.lat.round(),
lon: other.lon.round(),
}
}
}
值得注意的是,这还允许您添加或删除字段,因为 "inner" 序列化类型基本上可以做任何它想做的事情。