Serde를 사용하여 커스텀 함수를 사용하여 옵션 필드를 역직렬화하려면 어떻게 해야 합니까?
serialize 및 serialize 해제chrono::NaiveDate커스텀 기능을 탑재하고 있습니다만, Serde Book에서는 이 기능에 대해 설명하고 있지 않습니다.또, 코드 문서도 도움이 되지 않습니다.
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
extern crate chrono;
use chrono::NaiveDate;
mod date_serde {
use chrono::NaiveDate;
use serde::{self, Deserialize, Serializer, Deserializer};
pub fn serialize<S>(date: &Option<NaiveDate>, s: S) -> Result<S::Ok, S::Error>
where S: Serializer {
if let Some(ref d) = *date {
return s.serialize_str(&d.format("%Y-%m-%d").to_string())
}
s.serialize_none()
}
pub fn deserialize<'de, D>(deserializer: D)
-> Result<Option<NaiveDate>, D::Error>
where D: Deserializer<'de> {
let s: Option<String> = Option::deserialize(deserializer)?;
if let Some(s) = s {
return Ok(Some(NaiveDate::parse_from_str(&s, "%Y-%m-%d").map_err(serde::de::Error::custom)?))
}
Ok(None)
}
}
#[derive(Debug, Serialize, Deserialize)]
struct Test {
pub i: u64,
#[serde(with = "date_serde")]
pub date: Option<NaiveDate>,
}
fn main() {
let mut test: Test = serde_json::from_str(r#"{"i": 3, "date": "2015-02-03"}"#).unwrap();
assert_eq!(test.i, 3);
assert_eq!(test.date, Some(NaiveDate::from_ymd(2015, 02, 03)));
test = serde_json::from_str(r#"{"i": 5}"#).unwrap();
assert_eq!(test.i, 5);
assert_eq!(test.date, None);
}
나는 그것을 알고 있습니다.Option<chrono::NaiveDate>Chrono가 Serde를 지원하고 있기 때문에 Serde에 의해 쉽게 역직렬화 될 수 있지만 Serde를 배우려고 하기 때문에 직접 구현하고 싶습니다.이 코드를 실행하면 다음 오류가 발생합니다.
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ErrorImpl { code: Message("missing field `date`"), line: 1, column: 8 }', /checkout/src/libcore/result.rs:859
note: Run with `RUST_BACKTRACE=1` for a backtrace.
structure deserialization의 기본 동작은 필드가 시리얼화된 형식으로 존재하지 않을 때 각각의 기본값을 사용하여 필드를 할당하는 것입니다.이것은 구조체의 기본값으로 필드를 채우는 컨테이너 속성과는 다릅니다.
#[derive(Debug, PartialEq, Deserialize)]
pub struct Foo<'a> {
x: Option<&'a str>,
}
let foo: Foo = serde_json::from_str("{}")?;
assert_eq!(foo, Foo { x: None });
그러나 다른 역직렬화 함수()#[serde(deserialize_with = "path")]를 사용하면 이 규칙이 변경됩니다.활자 필드Option여기서 필드가 존재하지 않을 수 있음을 디시리얼라이저에 알리지 않습니다.오히려 빈 내용 또는 늘 내용이 있을 수 있는 필드가 있음을 나타냅니다.none(Serde 용어로)인serde_json예를 들어.Option<String>JavaScript는 다음과 같습니다.null또는string" (null | stringTypeScript / Flow 표기법).다음 코드는 지정된 정의 및 날짜 역직렬화기에서 올바르게 작동합니다.
let test: Test = serde_json::from_str(r#"{"i": 5, "date": null}"#)?;
assert_eq!(test.i, 5);
assert_eq!(test.date, None);
운 좋게도, 탈직렬화 과정은 단지 추가되는 것만으로 더 관대해질 수 있습니다.serde(default)속성(Option::default수율None):
#[derive(Debug, Serialize, Deserialize)]
struct Test {
pub i: u64,
#[serde(default)]
#[serde(with = "date_serde")]
pub date: Option<NaiveDate>,
}
다음 항목도 참조하십시오.
언급URL : https://stackoverflow.com/questions/44301748/how-can-i-deserialize-an-optional-field-with-custom-functions-using-serde
'programing' 카테고리의 다른 글
| Oracle SQL Developer에서 데이터베이스 이름을 쿼리하는 방법 (0) | 2023.03.01 |
|---|---|
| E2E 테스트에 각도 재료와 프로젝터를 함께 사용하는 데 문제가 있습니까? (0) | 2023.03.01 |
| jQuery AJAX 요청에 대한 응답으로 PNG 이미지 표시 (0) | 2023.03.01 |
| Mongoose(mongodb) 배치 인서트? (0) | 2023.03.01 |
| 최적의 문자열 연결/집약 방법 (0) | 2023.03.01 |