#![feature(str_as_str)]
use rumtk_core::core::RUMResult;
use rumtk_core::dependencies::clap;
use rumtk_core::net::tcp::LOCALHOST;
use rumtk_core::strings::{RUMArrayConversions, RUMString};
use rumtk_core::types::RUMCLIParser;
use rumtk_core::{rumtk_read_stdin, rumtk_sleep, rumtk_write_stdout};
use rumtk_hl7_v2::hl7_v2_mllp::mllp_v2::{SafeAsyncMLLP, SafeMLLPChannel, MLLP_FILTER_POLICY};
use rumtk_hl7_v2::{rumtk_v2_mllp_connect, rumtk_v2_mllp_iter_channels, rumtk_v2_mllp_listen};
#[derive(RUMCLIParser, Debug)]
#[command(author, version, about, long_about = None)]
pub struct RUMTKInterfaceArgs {
#[arg(short, long)]
ip: Option<RUMString>,
#[arg(short, long)]
port: Option<u16>,
#[arg(short, long, default_value_t = RUMString::from("none"))]
filter_policy: RUMString,
#[arg(short, long, default_value_t = 1)]
threads: usize,
#[arg(short, long)]
outbound: bool,
#[arg(short, long)]
local: bool,
#[arg(short, long)]
daemon: bool,
}
fn outbound_send(channel: &SafeMLLPChannel) -> RUMResult<()> {
let stdin_msg = rumtk_read_stdin!()?;
if !stdin_msg.is_empty() {
let mut owned_channel = channel.lock().expect("Failed to lock channel");
return owned_channel.send_message(&stdin_msg.as_slice().to_rumstring());
}
Ok(())
}
fn outbound_loop(channel: &SafeMLLPChannel) {
loop {
match outbound_send(channel) {
Ok(()) => continue,
Err(e) => println!("{}", e), };
}
}
fn inbound_receive(channel: &SafeMLLPChannel) -> RUMResult<()> {
let mut owned_channel = channel.lock().expect("Failed to lock channel");
let raw_msg = owned_channel.receive_message()?;
if !raw_msg.is_empty() {
rumtk_write_stdout!(&raw_msg);
} else {
rumtk_sleep!(0.001);
}
Ok(())
}
fn inbound_loop(listener: &SafeAsyncMLLP) {
loop {
for channel in rumtk_v2_mllp_iter_channels!(&listener) {
match inbound_receive(&channel) {
Ok(()) => continue,
Err(e) => println!("{}", e), }
}
}
}
fn main() {
let args = RUMTKInterfaceArgs::parse();
let mllp_filter_policy = match args.filter_policy.as_str() {
"escape" => MLLP_FILTER_POLICY::ESCAPE_INPUT,
"filter" => MLLP_FILTER_POLICY::FILTER_INPUT,
"none" => MLLP_FILTER_POLICY::NONE,
_ => MLLP_FILTER_POLICY::ESCAPE_INPUT,
};
if args.outbound {
let ip = match args.local {
true => args.ip.unwrap_or_else(|| LOCALHOST.parse().unwrap()),
false => args.ip.expect("Must provide an IP address"),
};
let port = args.port.expect("Must provide a port number");
let client =
rumtk_v2_mllp_connect!(&ip, port, mllp_filter_policy).expect("MLLP connection failed");
let channel_option = rumtk_v2_mllp_iter_channels!(&client);
let channel = channel_option.get(0).expect("MLLP connection failed");
if args.daemon {
outbound_loop(&channel);
} else {
outbound_send(&channel);
}
} else {
let mut listener: RUMResult<SafeAsyncMLLP> = Err(RUMString::new(""));
if args.ip.is_none() && args.port.is_none() {
listener = rumtk_v2_mllp_listen!(mllp_filter_policy, args.local);
} else if args.ip.is_none() && !args.port.is_none() {
listener = rumtk_v2_mllp_listen!(args.port.unwrap(), mllp_filter_policy, args.local);
} else if !args.ip.is_none() && !args.port.is_none() {
listener = rumtk_v2_mllp_listen!(
&args.ip.unwrap(),
args.port.unwrap(),
mllp_filter_policy,
args.local
);
} else {
listener = rumtk_v2_mllp_listen!(mllp_filter_policy, args.local);
}
inbound_loop(
&listener.expect("MLLP listening connection failed to bind a network interface!"),
);
}
}