better error handling in parse_mark_register_contents

pull/10905/head
Sam Vente 6 months ago
parent dba438832c
commit a9a72174c1
No known key found for this signature in database

@ -1,5 +1,6 @@
use std::fmt::Write;
use std::io::BufReader;
use std::num::ParseIntError;
use std::ops::Deref;
use crate::job::Job;
@ -502,11 +503,23 @@ fn parse_mark_register_contents(
match registers_vals {
Some(rv) => {
let mut rv_iter = rv.into_iter();
let doc_id_str = rv_iter.next().unwrap().into_owned();
let doc_id: DocumentId = doc_id_str.try_into().unwrap();
let history_rev_str = rv_iter.next().unwrap().into_owned();
let history_rev: usize = history_rev_str.parse().unwrap();
let mut ranges = rv_iter
let Some(doc_id) = rv_iter
.next()
.and_then(|c| Some(c.into_owned()))
.and_then(|s| s.try_into().ok())
else {
return Err("Register did not contain valid document id".to_string());
};
let Some(history_rev) = rv_iter
.next()
.and_then(|c| Some(c.into_owned()))
.and_then(|s| s.parse().ok())
else {
return Err("Register did not contain valid revision number".to_string());
};
let Ok(ranges) = rv_iter
.map(|tup| {
let s = tup.into_owned();
let range_parser = seq!(
@ -516,25 +529,43 @@ fn parse_mark_register_contents(
take_until(|c| c == ')'),
")"
);
let (_, (_, anchor_str, _, head_str, _)) = range_parser.parse(&s).unwrap();
let anchor: usize = <usize as FromStr>::from_str(anchor_str).unwrap();
let head: usize = <usize as FromStr>::from_str(head_str).unwrap();
Range {
let Ok((_tail, (_lparen, anchor_str, _comma, head_str, _rparen))) =
range_parser.parse(&s)
else {
return Err(format!("Could not parse range from string: {}", s));
};
let Ok(anchor) = <usize as FromStr>::from_str(anchor_str) else {
return Err(format!("Could not parse range from string: {}", s));
};
let Ok(head) = <usize as FromStr>::from_str(head_str) else {
return Err(format!("Could not parse range from string: {}", s));
};
Ok(Range {
anchor,
head,
old_visual_position: None,
}
})
})
// reverse the iterators so the first range will end up as the primary when we push them
.rev();
let last_range = ranges.next().unwrap(); // there is always at least one range
.rev()
.collect::<Result<Vec<Range>, String>>()
else {
return Err("Some ranges in the register failed to parse!".to_string());
};
let mut ranges_iter = ranges.into_iter();
let last_range = ranges_iter.next().unwrap(); // safe since there is always at least one range
let mut selection = Selection::from(last_range);
for r in ranges {
for r in ranges_iter {
selection = selection.push(r);
}
Ok((doc_id, history_rev, selection))
}
None => Err("Could not parse registry content".to_string()), // I can't figure out how to set status line here because of borrow issues :(
None => Err("Register was empty".to_string()),
}
}

Loading…
Cancel
Save