如何让Schemars生成SignedDecimal字符串形式的JSON Schema而非结构体字段
解决方案:让SignedDecimal序列化为字符串并生成对应JSON Schema
步骤1:为SignedDecimal实现自定义序列化/反序列化逻辑
你已经具备String转换的实现,现在需要替换默认的序列化行为,让SignedDecimal直接输出为字符串而非嵌套结构体形式:
use serde::{Serialize, Deserializer, Serializer}; use schemars::{JsonSchema, schema::Schema}; // 保留你的String转换逻辑(示例) impl From<SignedDecimal> for String { fn from(val: SignedDecimal) -> Self { let sign = if val.sign { "" } else { "-" }; format!("{}{}", sign, val.value) } } impl TryFrom<&str> for SignedDecimal { type Error = /* 替换为你的错误类型 */; fn try_from(s: &str) -> Result<Self, Self::Error> { // 实现你的字符串解析逻辑 Ok(SignedDecimal { sign: !s.starts_with('-'), value: /* 解析得到的Decimal256实例 */, }) } } // 自定义序列化 impl Serialize for SignedDecimal { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, { let str_val: String = self.into(); serializer.serialize_str(&str_val) } } // 自定义反序列化 impl<'de> Deserialize<'de> for SignedDecimal { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>, { let str_val = String::deserialize(deserializer)?; SignedDecimal::try_from(str_val.as_str()).map_err(serde::de::Error::custom) } }
步骤2:为SignedDecimal实现自定义JSON Schema生成逻辑
之前使用#[schemars(schema_with = "String")]无效,是因为schema_with需要传入生成Schema的函数而非类型名。需要定义专属函数并指定:
// 生成字符串类型Schema的函数 fn signed_decimal_schema(_gen: &mut schemars::gen::SchemaGenerator) -> Schema { schemars::schema::SchemaObject { instance_type: Some(schemars::schema::InstanceType::String.into()), ..Default::default() } .into() } // 修改SignedDecimal的宏注解,去掉默认的Serialize/Deserialize derive(改用自定义实现) #[derive(Clone, Copy, Debug, JsonSchema)] #[schemars(schema_with = "signed_decimal_schema")] pub struct SignedDecimal { value: Decimal256, sign: bool, }
步骤3:验证效果
此时Position结构体无需任何修改,序列化后会生成你期望的格式:
{ "x": "1.5", "y": "1.5" }
同时生成的JSON Schema中,x、y字段的类型会被标记为字符串,完全符合需求。
关键说明
- 移除SignedDecimal默认的
Serialize/Deserializederive,改用自定义实现,直接输出字符串而非嵌套结构体。 schema_with参数必须传入返回Schema类型的函数,而非类型名,这是之前写法无效的核心原因。- 全程无需修改Position结构体,仅调整SignedDecimal的实现与宏注解即可达成目标。
内容的提问来源于stack exchange,提问作者ewoolsey
相关产品推荐
相关产品推荐

