#message-parser #hl7 #health #parse #parser #time-parser #validation

hl7-parser

解析 HL7v2 消息的结构,但不验证消息的正确性

2 个不稳定版本

0.2.0 2024年1月13日
0.1.0 2024年1月12日

#741 in 解析器实现

Apache-2.0

135KB
2.5K SLoC

hl7-parser   构建状态 最新版本 文档 许可证

解析 HL7v2 消息的结构,但不验证消息的正确性。

[!警告]
尽管已尽力使此解析器正确解析 HL7v2 消息,但无法保证其确实正确。请自行承担风险。

功能

  • 将 HL7v2 消息解析为可查询的结构
  • 将 HL7v2 时间戳解析为 chronotime 类型
  • 解码 HL7v2 编码的字符串
  • 根据字符索引在消息中定位光标
  • 可选的宽松解析段分隔符(允许 \r\n\n\r 作为段分隔符,而不仅仅是 \r
  • 非 ASCII/UTF-8 编码

(未经检查的功能尚未实现,但计划在未来版本中实现)。

用法

将其添加到您的 Cargo.toml

[dependencies]
hl7-parser = "0.2"

然后您可以解析 HL7v2 消息

use hl7_parser::ParsedMessage;

let message = include_str!("../test_assets/sample_adt_a01.hl7");
let message = ParsedMessage::parse(&message, true).expect("can parse message");

let trigger_event = message.query_value("MSH.9.2").expect("can parse location query");
assert_eq!(trigger_event, Some("A01"));

可选 Cargo 功能

默认情况下,未启用任何可选功能。

  • serde:为所有数据结构启用 serde 支持
  • time:启用 time 支持以解析时间戳
  • chrono:启用 chrono 支持以解析时间戳

示例

解析 ParsedMessage

use hl7_parser::ParsedMessage;
use std::num::NonZeroUsize;

let message = r#"
MSH|^~\&|AccMgr|1|||20050110045504||ADT^A01|599102|P|2.3|||
PID|1||10006579^^^1^MRN^1||DUCK^DONALD^D||19241010|M||1|111 DUCK ST^^FOWL^CA^999990000^^M|1|8885551212|8885551212|1|2||40007716^^^AccMgr^VN^1|123121234|||||||||||NO NK1|1|DUCK^HUEY|SO|3583 DUCK RD^^FOWL^CA^999990000|8885552222||Y||||||||||||||
PV1|1|I|PREOP^101^1^1^^^S|3|||37^DISNEY^WALT^^^^^^AccMgr^^^^CI|||01||||1|||37^DISNEY^WALT^^^^^^AccMgr^^^^CI|2|40007716^^^AccMgr^VN|4|||||||||||||||||||1||G|||20050110045253||||||
"#;

let message = ParsedMessage::parse(message.trim(), true).expect("can parse message");
let message_type = message.get_field_source(("MSH", 0), NonZeroUsize::new(9).unwrap());
assert_eq!(message_type.unwrap(), "ADT^A01");

查询 ParsedMessage

use hl7_parser::ParsedMessage;

let message = include_str!("../test_assets/sample_adt_a01.hl7");
let message = ParsedMessage::parse(&message, true).expect("can parse message");

let trigger_event = message.query_value("MSH.9.2").expect("can parse location query");
assert_eq!(trigger_event, Some("A01"));

在 ParsedMessage 中定位光标

(光标是缓冲区中某些点的字符索引)

use hl7_parser::ParsedMessage;
use std::num::NonZeroUsize;

let message = r#"
MSH|^~\&|AccMgr|1|||20050110045504||ADT^A01|599102|P|2.3|||
PID|1||10006579^^^1^MRN^1||DUCK^DONALD^D||19241010|M||1|111 DUCK ST^^FOWL^CA^999990000^^M|1|8885551212|8885551212|1|2||40007716^^^AccMgr^VN^1|123121234|||||||||||NO NK1|1|DUCK^HUEY|SO|3583 DUCK RD^^FOWL^CA^999990000|8885552222||Y||||||||||||||
PV1|1|I|PREOP^101^1^1^^^S|3|||37^DISNEY^WALT^^^^^^AccMgr^^^^CI|||01||||1|||37^DISNEY^WALT^^^^^^AccMgr^^^^CI|2|40007716^^^AccMgr^VN|4|||||||||||||||||||1||G|||20050110045253||||||
"#;

let message = ParsedMessage::parse(message.trim(), true).expect("can parse message");
let location = message.locate_cursor(25);
assert_eq!(location.segment.unwrap().0, "MSH");
assert_eq!(location.field.unwrap().0.get(), 7);
assert_eq!(location.field.unwrap().1.source(message.source), "20050110045504");

解析解析消息的时间戳

使用 time

#[cfg(feature = "time")]
use hl7_parser::parse_timestamp_time;

let ts = "20230312195905-0700";
let ts = parse_timestamp_time(ts).expect("can parse timestamp");

assert_eq!(ts.year(), 2023);
assert_eq!(ts.month(), time::Month::March);
assert_eq!(ts.day(), 12);
assert_eq!(ts.hour(), 19);
assert_eq!(ts.minute(), 59);
assert_eq!(ts.second(), 05);
assert_eq!(ts.microsecond(), 0);
assert_eq!(ts.offset().whole_hours(), -7);
assert_eq!(ts.offset().minutes_past_hour(), 0);

使用 chrono

#[cfg(feature = "chrono")]
use hl7_parser::parse_timestamp_chrono;
use chrono::prelude::*;

let ts = "20230312195905-0700";
let ts = parse_timestamp_chrono(ts).expect("can parse timestamp");

assert_eq!(ts.year(), 2023);
assert_eq!(ts.month(), 3);
assert_eq!(ts.day(), 12);
assert_eq!(ts.hour(), 19);
assert_eq!(ts.minute(), 59);
assert_eq!(ts.second(), 05);
assert_eq!(ts.nanosecond(), 123_400_000);
assert_eq!(ts.offset().local_minus_utc() / 3600, -7);
assert_eq!(ts.offset().local_minus_utc() % 3600, 0);

解码编码字符串

use hl7_parser::Separators;

let separators = Separators::default();
assert_eq!(
    separators.decode(r#"Pierre DuRho\S\ne \T\ Cie"#).as_str(),
    r#"Pierre DuRho^ne & Cie"#
);

依赖

~2–3.5MB
~65K SLoC