finga
12b117db7e
To supporte more than a single log level `log` and `env_logger` crates are used. For the application to support the different type of argument, the verbose argument definition was adapted.
86 lines
2.3 KiB
Rust
86 lines
2.3 KiB
Rust
use anyhow::Result;
|
|
use chrono::{DateTime, Local};
|
|
use clap::Clap;
|
|
use humantime::Duration;
|
|
use log::info;
|
|
use posixmq::PosixMq;
|
|
use std::str;
|
|
|
|
/// Receive and print a message from a message queue
|
|
#[derive(Clap, Debug)]
|
|
pub struct Recv {
|
|
/// Do not block
|
|
#[clap(short, long)]
|
|
pub non_blocking: bool,
|
|
/// Print messages as they are received
|
|
#[clap(short, long)]
|
|
pub follow: bool,
|
|
/// Print a timestamp before each message
|
|
#[clap(short, long)]
|
|
pub timestamp: bool,
|
|
/// Timeout, example "5h 23min 42ms"
|
|
#[clap(short = 'o', long, conflicts_with = "deadline")]
|
|
pub timeout: Option<String>,
|
|
/// Deadline until messages are received (format: "%Y-%m-%d %H:%M:%S")
|
|
#[clap(short, long, conflicts_with = "timeout")]
|
|
pub deadline: Option<String>,
|
|
/// Name of the queue
|
|
#[clap(value_name = "QUEUE")]
|
|
pub queue: String,
|
|
}
|
|
|
|
fn print_message(priority: u32, length: usize, timestamp: bool, msg: &str) {
|
|
info!("Priority: {}, length: {}", priority, length);
|
|
|
|
if timestamp {
|
|
println!("{}", Local::now());
|
|
}
|
|
|
|
println!("{}", msg);
|
|
}
|
|
|
|
impl Recv {
|
|
fn receive(&self, mq: &PosixMq) -> Result<()> {
|
|
let mut buf = vec![0; mq.attributes()?.max_msg_len];
|
|
|
|
if let Some(timeout) = &self.timeout {
|
|
let (prio, len) = mq.recv_timeout(&mut buf, *timeout.parse::<Duration>()?)?;
|
|
|
|
print_message(prio, len, self.timestamp, str::from_utf8(&buf)?);
|
|
} else if let Some(deadline) = &self.deadline {
|
|
let (prio, len) = mq.recv_deadline(
|
|
&mut buf,
|
|
DateTime::parse_from_str(deadline, "%Y-%m-%d %H:%M:%S")?.into(),
|
|
)?;
|
|
|
|
print_message(prio, len, self.timestamp, str::from_utf8(&buf)?);
|
|
} else {
|
|
let (prio, len) = mq.recv(&mut buf)?;
|
|
|
|
print_message(prio, len, self.timestamp, str::from_utf8(&buf)?);
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn run(&self) -> Result<()> {
|
|
let mq = &mut posixmq::OpenOptions::readonly();
|
|
|
|
if self.non_blocking {
|
|
mq.nonblocking();
|
|
}
|
|
|
|
let mq = mq.open(&self.queue)?;
|
|
|
|
if self.follow {
|
|
loop {
|
|
self.receive(&mq)?;
|
|
}
|
|
} else {
|
|
self.receive(&mq)?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|