parse_config/
parse_config.rs1#![expect(clippy::print_stderr, unreachable_pub, clippy::use_debug)]
2use core::{error::Error, fmt};
6use std::{fs, path::Path};
7
8use error_stack::{Report, ResultExt as _};
9
10pub type Config = String;
11
12#[derive(Debug)]
13struct ParseConfigError;
14
15impl ParseConfigError {
16 #[must_use]
17 pub const fn new() -> Self {
18 Self
19 }
20}
21
22impl fmt::Display for ParseConfigError {
23 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
24 fmt.write_str("Could not parse configuration file")
25 }
26}
27
28impl Error for ParseConfigError {}
29
30struct Suggestion(&'static str);
31
32fn parse_config(path: impl AsRef<Path>) -> Result<Config, Report<ParseConfigError>> {
33 let path = path.as_ref();
34
35 let content = fs::read_to_string(path)
36 .change_context(ParseConfigError::new())
37 .attach_opaque(Suggestion("use a file you can read next time!"))
38 .attach_with(|| format!("could not read file {}", path.display()))?;
39
40 Ok(content)
41}
42
43fn main() {
44 if let Err(report) = parse_config("config.json") {
45 eprintln!("{report:?}");
46 #[cfg(nightly)]
47 for suggestion in report.request_ref::<Suggestion>() {
48 eprintln!("Suggestion: {}", suggestion.0);
49 }
50 }
51}