Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing field on deserialization, serialization works #377

Closed
AxelMontini opened this issue Mar 24, 2022 · 2 comments
Closed

Missing field on deserialization, serialization works #377

AxelMontini opened this issue Mar 24, 2022 · 2 comments
Labels
question serde Issues related to mapping from Rust types to XML

Comments

@AxelMontini
Copy link

I've tried using the library to serialize/deserialize XML for an API but I didn't get far.

There's two tests at the bottom producing this behaviour.
When deserializing, the error is thread 'api::tests::deserialize' panicked at 'called Result::unwrap()on anErrvalue: Custom("missing fieldRequestTimestamp")'.
When serializing, the output (using --nocapture) is <OJP><OJPRequest><ServiceRequest><RequestTimestamp>2022-03-24T07:56:40.192049665Z</RequestTimestamp></ServiceRequest></OJPRequest></OJP>.

use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
struct OJP(OJPRequest);

#[derive(Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
struct OJPRequest(ServiceRequest);

#[derive(Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
struct ServiceRequest {
    request_timestamp: RequestTimestamp,
}

#[derive(Serialize, Deserialize, derive_more::From)]
struct RequestTimestamp(DateTime<Utc>);

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

    #[test]
    fn deserialize() {
        let xml = r#"<OJP><OJPRequest><ServiceRequest><RequestTimestamp>2022-03-24T07:48:03.571299970Z</RequestTimestamp></ServiceRequest></OJPRequest></OJP>"#;

        let ojp: OJP = quick_xml::de::from_str(xml).unwrap();
    }

    #[test]
    fn serialize() {
        let ojp = OJP(OJPRequest(ServiceRequest {
            request_timestamp: Utc::now().into(),
        }));

        println!("{}", quick_xml::se::to_string(&ojp).unwrap());
    }
}

Modifying the xml string like this solves the issue and the library expects RequestTimestamp to be somewhere else.

let xml = r#"<OJP><RequestTimestamp>2022-03-24T07:48:03.571299970Z</RequestTimestamp><OJPRequest><ServiceRequest></ServiceRequest></OJPRequest></OJP>"#;
@Mingun
Copy link
Collaborator

Mingun commented Mar 31, 2022

I think, this is expected, because names of any types does not have any meaning. If you see an element in the XML and want to use it name, you should map it or to a struct field, or to an enum variant. That are things that is not expected to be changed.

You can also find a more info in my not yet finished PR, that describes things as it should be (and in many cases they already behaves as described).

(The better way to read it is to checkout branch and build rustdoc, because information in PR description is outdated).

In you case such types should work:

#[derive(Serialize, Deserialize)]
struct OJP {
  #[serde(rename = "OJPRequest")]
  ojp_request: OJPRequest,
}

#[derive(Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
struct OJPRequest {
  service_request: ServiceRequest,
}

#[derive(Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
struct ServiceRequest {
    request_timestamp: RequestTimestamp,
}

#[derive(Serialize, Deserialize, derive_more::From)]
struct RequestTimestamp(DateTime<Utc>);

If you want to enforce that root tag is OJP, then for deserializing there is no simple way yet, and for serializing use with_root method.

@Mingun Mingun added question serde Issues related to mapping from Rust types to XML labels May 21, 2022
@AxelMontini
Copy link
Author

Sorry for the late reply, I can confirm it works with the code provided.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question serde Issues related to mapping from Rust types to XML
Projects
None yet
Development

No branches or pull requests

2 participants