Files
crank/crates/crank-core/src/soap.rs
T
2026-04-06 21:27:19 +03:00

102 lines
3.4 KiB
Rust

use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum SoapVersion {
#[serde(rename = "soap_11")]
Soap11,
#[serde(rename = "soap_12")]
Soap12,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum SoapBindingStyle {
DocumentLiteral,
RpcLiteral,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct SoapHeaderConfig {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub namespace_uri: Option<String>,
pub required: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub value_path: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct SoapFaultContract {
#[serde(skip_serializing_if = "Option::is_none")]
pub code_path: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub message_path: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub detail_path: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
pub struct SoapOperationMetadata {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub input_part_names: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub output_part_names: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub namespaces: Vec<String>,
}
#[cfg(test)]
mod tests {
use serde_json::json;
use super::{
SoapBindingStyle, SoapFaultContract, SoapHeaderConfig, SoapOperationMetadata, SoapVersion,
};
#[test]
fn soap_metadata_serializes_compactly() {
let value = serde_json::to_value(SoapOperationMetadata {
input_part_names: vec!["LeadRequest".to_owned()],
output_part_names: vec!["LeadResponse".to_owned()],
namespaces: vec!["urn:crm".to_owned()],
})
.unwrap();
assert_eq!(value["input_part_names"][0], "LeadRequest");
assert_eq!(value["output_part_names"][0], "LeadResponse");
assert_eq!(value["namespaces"][0], "urn:crm");
}
#[test]
fn soap_supporting_types_roundtrip() {
let value = json!({
"version": "soap_12",
"style": "document_literal",
"header": {
"name": "CorrelationId",
"namespace_uri": "urn:crm",
"required": true,
"value_path": "$.mcp.correlation_id"
},
"fault": {
"code_path": "$.Envelope.Body.Fault.Code.Value",
"message_path": "$.Envelope.Body.Fault.Reason.Text",
"detail_path": "$.Envelope.Body.Fault.Detail"
}
});
let version: SoapVersion = serde_json::from_value(value["version"].clone()).unwrap();
let style: SoapBindingStyle = serde_json::from_value(value["style"].clone()).unwrap();
let header: SoapHeaderConfig = serde_json::from_value(value["header"].clone()).unwrap();
let fault: SoapFaultContract = serde_json::from_value(value["fault"].clone()).unwrap();
assert_eq!(version, SoapVersion::Soap12);
assert_eq!(style, SoapBindingStyle::DocumentLiteral);
assert_eq!(header.name, "CorrelationId");
assert_eq!(
fault.detail_path.as_deref(),
Some("$.Envelope.Body.Fault.Detail")
);
}
}