chj_rustbin/io/
readwithcontext.rs1use anyhow::{anyhow, Context, Result};
5use std::{
6 fs::File,
7 io::{BufRead, BufReader},
8 path::Path,
9};
10
11pub fn trim(line: &mut String) {
12 if line.ends_with("\n") {
13 line.pop().unwrap();
14 }
15}
16
17pub fn open_file(path: &Path) -> Result<BufReader<File>> {
21 Ok(BufReader::new(
22 File::open(path).with_context(|| format!("opening file {:?}", path))?,
23 ))
24}
25
26pub fn easy_read_line(
30 inp: &mut BufReader<File>,
31 line: &mut String,
32) -> Result<bool> {
33 line.clear();
34 if inp.read_line(line)? != 0 {
35 trim(line);
36 Ok(true)
37 } else {
38 Ok(false)
39 }
40}
41
42pub struct ReadWithContext<'p> {
45 path: &'p Path,
46 linenumber: i64,
47 reader: BufReader<File>,
48}
49
50impl<'p> ReadWithContext<'p> {
51 pub fn open_path(path: &'p Path) -> Result<ReadWithContext<'p>> {
52 Ok(ReadWithContext {
53 path,
54 linenumber: 0,
55 reader: open_file(path)?,
56 })
57 }
58 pub fn easy_read_line(&mut self, line: &mut String) -> Result<bool> {
62 self.linenumber += 1;
63 easy_read_line(&mut self.reader, line).with_context(|| {
64 anyhow!("file {:?} line {}", self.path, self.linenumber)
65 })
66 }
67
68 #[allow(unused)]
70 pub fn err_with_context<T>(
71 &self,
72 err: anyhow::Error,
73 ) -> Result<T, anyhow::Error> {
74 Err(err.context(anyhow!(
75 "file {:?} line {}",
76 self.path,
77 self.linenumber
78 )))
79 }
80
81 #[allow(unused)]
83 pub fn context<T>(
84 &self,
85 res: Result<T, anyhow::Error>,
86 ) -> Result<T, anyhow::Error> {
87 match res {
88 Ok(v) => Ok(v),
89 Err(e) => self.err_with_context(e),
90 }
91 }
92}