media-io / yaserde

Yet Another Serializer/Deserializer
MIT License
174 stars 57 forks source link

Error "bad namespace for Body, found http://schemas.xmlsoap.org/soap/envelope/" #177

Open averichev opened 5 months ago

averichev commented 5 months ago

Error on deserialize

use yaserde_derive::{YaDeserialize, YaSerialize};

#[test]
fn basic() {
    #[derive(YaDeserialize, YaSerialize)]
    #[yaserde(
    prefix = "soap",
    namespace="soap: http://schemas.xmlsoap.org/soap/envelope/"
    )]
    pub struct Envelope {
        #[yaserde(prefix="soap", rename="Body")]
        pub body: BodyEnum,
    }

    #[derive(YaDeserialize, YaSerialize)]
    #[yaserde(flatten)]
    pub enum BodyEnum {
        #[yaserde(rename="Fault", prefix="soap")]
        #[yaserde(flatten)]
        Fault(Fault),
        #[yaserde(rename="GetMessageResponse" prefix="soap")]
        #[yaserde(flatten)]
        GetMessageResponse(GetMessageResponse),
    }

    impl Default for BodyEnum {
        fn default() -> Self {
            BodyEnum::Fault(Fault{ faultcode: "unknown code".to_string(), faultstring: "unknown fault".to_string() })
        }
    }

    #[derive(YaDeserialize, YaSerialize)]
    pub struct Fault {
        pub faultcode: String,
        pub faultstring: String
    }

    #[derive(YaDeserialize, YaSerialize)]
    pub struct GetMessageResponse {
        #[yaserde(prefix="ns", rename="Message")]
        pub message: Message,
    }

    #[derive(YaDeserialize, YaSerialize)]
    pub struct Message {
        #[yaserde(rename="AuthResponse", prefix="tns")]
        pub auth_response: AuthResponse,
    }

    #[derive(YaDeserialize, YaSerialize)]
    #[yaserde(
    namespace = "tns: urn://test/types/1.0"
    )]
    pub struct AuthResponse {
        #[yaserde(prefix="tns", rename="Result")]
        pub auth_app_info: Result,
    }

    #[derive(YaDeserialize, YaSerialize)]
    pub struct Result {
        #[yaserde(prefix="tns", rename="Token")]
        pub token: String,
        #[yaserde(prefix="tns", rename="expire")]
        pub expire: String,
    }

    let content = r#"
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <soap:Fault>
            <faultcode>soap:Server</faultcode>
            <faultstring>error description</faultstring>
        </soap:Fault>
    </soap:Body>
</soap:Envelope>
"#;

    let envelope = yaserde::de::from_str::<Envelope>(&content).unwrap();
    match envelope.body {
        BodyEnum::Fault(_) => {}
        BodyEnum::GetMessageResponse(_) => {}
    }
}

Link to test

Is this my mistake in using the library or a bug?

MarcAntoine-Arnaud commented 2 months ago

Hello @averichev ,

Sorry for the delay. Can you try to rewrote:

    #[derive(YaDeserialize, YaSerialize)]
    #[yaserde(flatten)]
    pub enum BodyEnum {
        #[yaserde(rename="Fault", prefix="soap", flatten)]
        Fault(Fault),
        #[yaserde(rename="GetMessageResponse", prefix="soap", flatten)]
        GetMessageResponse(GetMessageResponse),
    }

I'm not sure the library handle multi #[yaserde scope. In addition you've missed one comma after #[yaserde(rename="GetMessageResponse".

And if you get against an error, then it's mostly a bug on namespace with enums.

Best, Marc-Antoine