use std::ops::Range;
use super::subslice_range;
pub(crate) struct ProcessingParts {
pub(crate) head: Range<usize>,
pub(crate) name: Option<Range<usize>>,
pub(crate) number: Option<Range<usize>>,
pub(crate) dest: Range<usize>,
pub(crate) context: Range<usize>,
}
pub(crate) fn processing_parts(msg: &str) -> Option<ProcessingParts> {
let proc_idx = msg.find("Processing ")?;
let base = proc_idx + "Processing ".len();
let after_proc = &msg[base..];
let ctx_idx = after_proc.rfind(" in context ")?;
let head = &after_proc[..ctx_idx];
let ctx_start = base + ctx_idx + " in context ".len();
let context_token = msg.get(ctx_start..)?.split_whitespace().next()?;
let context = subslice_range(msg, context_token)?;
let (head_range, dest) = match head.rfind(">->") {
Some(i) => (base..base + i + 1, base + i + ">->".len()..base + ctx_idx),
None => {
let i = head.rfind("->")?;
(base..base + i, base + i + "->".len()..base + ctx_idx)
}
};
let (name, number) = match msg[head_range.clone()]
.strip_suffix('>')
.and_then(|h| h.rfind(" <"))
{
Some(i) => (
Some(head_range.start..head_range.start + i),
Some(head_range.start + i + " <".len()..head_range.end - 1),
),
None => (None, None),
};
Some(ProcessingParts {
head: head_range,
name: name.filter(|r| !r.is_empty()),
number: number.filter(|r| !r.is_empty()),
dest,
context,
})
}