如何在Rust中反序列化Tarantool 2.10+响应中的Decimal类型?
在Rust中使用alopecosa反序列化Decimal类型字段
1. 添加依赖
先在Cargo.toml中引入所需依赖,确保rust_decimal开启serde特性:
[dependencies] alopecosa = "0.10" # 替换为你实际使用的版本 rust_decimal = { version = "1.30", features = ["serde"] } serde = { version = "1.0", features = ["derive"] }
2. 自定义反序列化逻辑
根据alopecosa返回的Decimal数据格式,选择对应的反序列化方式:
情况1:返回字符串格式(如"199.99")
定义结构体时,为Decimal字段指定自定义反序列化函数:
use alopecosa::Client; use rust_decimal::Decimal; use serde::Deserialize; use serde::de::{self, Deserializer}; #[derive(Debug, Deserialize)] struct ProductSpace { id: String, name: String, #[serde(deserialize_with = "decimal_from_string")] price: Decimal, } // 从字符串反序列化为Decimal fn decimal_from_string<'de, D>(deserializer: D) -> Result<Decimal, D::Error> where D: Deserializer<'de>, { let num_str: &str = de::Deserialize::deserialize(deserializer)?; Decimal::from_str(num_str) .map_err(|e| de::Error::custom(format!("无效的十进制字符串: {}", e))) }
情况2:返回浮点数格式(如199.99)
如果接口返回f64类型数值,使用以下转换函数:
fn decimal_from_f64<'de, D>(deserializer: D) -> Result<Decimal, D::Error> where D: Deserializer<'de>, { let num: f64 = de::Deserialize::deserialize(deserializer)?; Decimal::from_f64(num) .ok_or_else(|| de::Error::custom("无法将f64转换为Decimal")) }
情况3:返回带精度的复合结构(如{"value": 19999, "scale": 2})
先定义中间结构接收原始数据,再转换为Decimal:
#[derive(Deserialize)] struct RawDecimal { value: i64, scale: u32, } fn decimal_from_raw<'de, D>(deserializer: D) -> Result<Decimal, D::Error> where D: Deserializer<'de>, { let raw: RawDecimal = de::Deserialize::deserialize(deserializer)?; Decimal::new(raw.value, raw.scale) .map_err(|e| de::Error::custom(format!("无效的原始十进制数据: {}", e))) }
3. 执行查询并反序列化
使用alopecosa客户端查询数据,自动应用自定义反序列化:
async fn main() -> Result<(), Box<dyn std::error::Error>> { let client = Client::new("https://你的space接口地址")?; let product: ProductSpace = client.get_space("product-123").await?; println!("商品价格: {}", product.price); Ok(()) }
内容的提问来源于stack exchange,提问作者Meas
相关产品推荐
相关产品推荐

