csv 缺少serde字段无法设置为默认值

pgvzfuti  于 2023-06-19  发布在  其他
关注(0)|答案(1)|浏览(142)

我这里有一个非常简单的结构,可以从字符串反序列化

#[cfg(test)]
mod tests {
use csv;
#[derive(Debug, serde::Deserialize)]
struct Test {
    x: f64,
    #[serde(default)]
    up: f64,
}

#[test]
fn deserialise() {
    let s = "x,up\n0.0,";

    let mut rdr = csv::Reader::from_reader(s.as_bytes());
    for row in rdr.deserialize() {
        let option: Test = row.expect("Failure");
        dbg!(&option);
    }
}
}

我希望字段“up”默认为0.0,因为它在文件中丢失。使用up: Option<f64>是可行的,但它不是数据模型的真正表示。
我做错了什么?
它失败了

thread 'tests::deserialise' panicked at 'Failure: Error(Deserialize { pos: Some(Position { byte: 111, line: 2, record: 1 }), err: DeserializeError { field: Some(12), kind: ParseFloat(ParseFloatError { kind: Empty }) } })', data_model\examples\upload_options.rs:80:41

Cargo.toml:

[package]
name = "data_model"
version = "0.1.0"
edition = "2021"

[dependencies]
serde = { version = "^1.0", features = ["derive"] }
csv = "^1"
56lgkhnf

56lgkhnf1#

登录https://github.com/BurntSushi/rust-csv/issues/109#issuecomment-372709974。
这是CSV格式的一个限制,因为它不能区分空字符串和不存在的单元格。因此,您需要通过告诉serde将空单元格反序列化为默认值来解决这个问题。

#[derive(Debug, serde::Deserialize)]
pub struct Test {
    pub x: f64,
    #[serde(deserialize_with = "default_if_empty")]
    pub up: f64,
}

fn default_if_empty<'de, D, T>(de: D) -> Result<T, D::Error>
where
    D: serde::Deserializer<'de>,
    T: serde::Deserialize<'de> + Default,
{
    use serde::Deserialize;
    Option::<T>::deserialize(de).map(|x| x.unwrap_or_else(|| T::default()))
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn deserialise() {
        let s = "x,up\n0.0,";

        let mut rdr = csv::Reader::from_reader(s.as_bytes());
        for row in rdr.deserialize() {
            let option: Test = row.expect("Failure");
            dbg!(&option);
        }
    }
}
$ cargo test -- --nocapture
running 1 test
[src/lib.rs:28] &option = Test {
    x: 0.0,
    up: 0.0,
}
test tests::deserialise ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

相关问题