Improve error handling in parser module

This commit is contained in:
Joakim Soderlund 2019-07-24 14:25:50 +00:00
parent a9b6351737
commit 1dfbf1ea7f

View file

@ -22,33 +22,60 @@ pub fn parse(reader: impl BufRead) -> Result<Vec<Story>> {
_ => SourceError("Could not read index line."), _ => SourceError("Could not read index line."),
})?; })?;
if 3 < line.len() { if tx.send(line).is_ok() {
tx.send(line).unwrap(); continue;
} }
return Err(match rx.recv() {
Err(_) => SourceError("Parser disappeared unexpectedly."),
Ok(Ok(_)) => SourceError("Parser returned unexpectedly."),
Ok(Err(error)) => error,
});
} }
drop(tx); drop(tx);
rx.recv().unwrap() rx.recv().map_err(|e| match e {
_ => SourceError("Missing parser result."),
})?
} }
fn spawn_parser(stream: Receiver<String>) -> Receiver<Result<Vec<Story>>> { fn spawn_parser(stream: Receiver<String>) -> Receiver<Result<Vec<Story>>> {
use Error::*;
let (tx, rx) = channel(); let (tx, rx) = channel();
spawn(move || { spawn(move || {
let mut stories = Vec::with_capacity(250_000); let mut stories = Vec::with_capacity(250_000);
let mut wrappers = String::with_capacity(2);
while let Ok(line) = stream.recv() { while let Ok(line) = stream.recv() {
if line.len() == 1 {
wrappers.push_str(&line);
continue;
}
match deserialize(line) { match deserialize(line) {
Ok(story) => stories.push(story), Ok(story) => stories.push(story),
Err(e) => return tx.send(Err(e)).unwrap(), Err(e) => return tx.send(Err(e)),
}; };
} }
stories.shrink_to_fit(); let count = stories.len();
stories.sort_by_key(|story| story.id);
tx.send(Ok(stories)).unwrap(); stories.sort_by_key(|story| story.id);
stories.dedup_by_key(|story| story.id);
stories.shrink_to_fit();
if wrappers != "{}" {
return tx.send(Err(SourceError("Invalid index structure.")));
}
if count != stories.len() {
return tx.send(Err(SourceError("Index contains duplicates.")));
}
tx.send(Ok(stories))
}); });
rx rx