use std::fmt;
pub const INVALID_SESSION_ID: &str = "INVALID_SESSION_ID";
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SoapFault {
pub fault_code: String,
pub fault_string: String,
pub exception_code: Option<String>,
}
impl SoapFault {
#[must_use]
pub fn is_invalid_session(&self) -> bool {
self.exception_code.as_deref() == Some(INVALID_SESSION_ID)
|| self.fault_code.contains(INVALID_SESSION_ID)
|| self.fault_string.contains(INVALID_SESSION_ID)
}
}
impl fmt::Display for SoapFault {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[{}] {}", self.fault_code, self.fault_string)
}
}
impl std::error::Error for SoapFault {}
pub fn parse_fault(xml: &str) -> Option<SoapFault> {
if !xml.contains("Fault") {
return None;
}
let root = super::parse::parse_document(xml).ok()?;
let fault = root.find_descendant("Fault")?;
let fault_code = fault.child_text("faultcode").unwrap_or_default();
let fault_string = fault.child_text("faultstring").unwrap_or_default();
let exception_code = fault
.find_child("detail")
.and_then(|detail| detail.find_descendant("exceptionCode"))
.map(super::parse::Node::text_owned)
.filter(|s| !s.is_empty());
Some(SoapFault {
fault_code,
fault_string,
exception_code,
})
}