Skip to main content

Crate hl7_2_soap

Crate hl7_2_soap 

Source
Expand description

HL7 v2 over SOAP: the envelope, faults, payload carriage, WSDL, and response evaluation that carry HL7 v2 messages over HTTP.

MLLP is how HL7 v2 usually moves, and hl7-2-mllp is that transport. SOAP is the other one — the transport an estate ends up with when the messages have to cross a boundary that speaks HTTP, or when the system at the far end was built by a team who had a WSDL and no socket. This crate is that transport, and it is deliberately the same shape as its MLLP sibling: it does the protocol and nothing else.

§What it does

  • parse a SOAP envelope and take the single payload out of its body
  • Faults, each carrying the HTTP status that belongs with it
  • message — read a v2.xml payload, or ER7 wrapped in one, and check a payload against what the interface accepts
  • response — build the reply, and read one as accepted or rejected
  • wsdl — describe the endpoint to client tooling, at its real address

§What it does not do

No HTTP client and no HTTP server: this crate turns bytes into meaning and back, and leaves the socket to whatever the caller already uses. No HL7 validation and no format conversion either — hl7-rust and the hl7-2-from-* crates own those, and a transport that also converted formats would be two crates in a trench coat.

§Receiving

use hl7_2_soap::{Fault, message, response};

fn handle(request_body: &str) -> (u16, String) {
    match accept(request_body) {
        Ok(control_id) => (200, response::success(&control_id)),
        Err(fault) => (fault.status, fault.to_envelope()),
    }
}

fn accept(request_body: &str) -> Result<String, Fault> {
    let envelope = hl7_2_soap::parse(request_body)?;
    let payload = envelope.payload()?;
    message::check(payload, &["ADT_A05".to_string()], &[])?;
    // ...validate and forward the payload here...
    Ok(message::control_id(payload).unwrap_or_default().to_string())
}

let request = r#"<Envelope><Body><ADT_A05><MSH><MSH.10>9</MSH.10></MSH></ADT_A05></Body></Envelope>"#;
assert_eq!(handle(request).0, 200);

let wrong = r#"<Envelope><Body><ADT_A39/></Body></Envelope>"#;
assert_eq!(handle(wrong).0, 400);

§Sending

use hl7_2_soap::{message, response::{self, Outcome}};

let body = message::wrap_er7("MSH|^~\\&|APP||||1||ADT^A01|9|P|2.5");
// ...POST `body` with Content-Type: text/xml; charset=utf-8...
match response::evaluate(status, &reply) {
    Outcome::Accepted => {}
    Outcome::Rejected(reason) => panic!("not delivered: {reason}"),
}

See spec/index.md for the exact rules (source of truth).

Re-exports§

pub use envelope::Envelope;
pub use envelope::parse;
pub use envelope::wrap_xml;
pub use fault::Fault;
pub use fault::SOAP_NS;
pub use response::Outcome;
pub use hl7_2_xml_lite_helper as xml;

Modules§

envelope
Reading a SOAP envelope, and writing one.
fault
SOAP faults, and the HTTP status that goes with them.
message
What a SOAP body is carrying, and how to read it.
response
The reply a receiver sends, and how a sender reads one.
wsdl
Describing the endpoint to client tooling.

Constants§

CONTENT_TYPE
The content type a SOAP 1.1 request and response are sent with.