Skip to content

Commit

Permalink
feat: print config snippets of error location
Browse files Browse the repository at this point in the history
  • Loading branch information
azzamsa committed Jan 3, 2023
1 parent 21c878b commit 7879671
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 18 deletions.
30 changes: 18 additions & 12 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::{
path::{Path, PathBuf},
};

use miette::{NamedSource, Result, SourceOffset};
use serde::Deserialize;

use crate::error::Error;
Expand All @@ -21,26 +22,31 @@ pub struct Config {

pub fn read<P>(filename: P) -> Result<Config, Error>
where
P: AsRef<Path> + AsRef<OsStr>,
P: AsRef<Path>,
P: AsRef<OsStr>,
{
let file_content = fs::read_to_string(&filename).map_err(|_| Error::ConfigNotFound {
path: PathBuf::from(&filename),
})?;
deserialize(&file_content)
deserialize(&file_content, &filename)
}

/// Deserialize config intro struct.
/// # Errors
///
/// Will return `Err` if deserialization error.
/// Possibly the error contains a position (line number) of the occurred error
/// But this is not accurate. All the other apps that depend on toml.rs
/// share the same faith.
fn deserialize(content: &str) -> Result<Config, Error> {
fn deserialize<P>(content: &str, filename: P) -> Result<Config, Error>
where
P: AsRef<Path>,
P: AsRef<OsStr>,
{
match toml::from_str(content) {
Ok(config) => Ok(config),
Err(e) => Err(Error::InvalidConfig {
message: e.to_string(),
}),
Err(e) => {
let (line, column) = &e.line_col().unwrap_or((0, 0));
let filename = Path::new(&filename);
Err(Error::InvalidConfig {
src: NamedSource::new(filename.to_string_lossy(), content.to_owned()),
bad_bit: SourceOffset::from_location(content, line + 1, column + 1),
message: e.to_string(),
})?
}
}
}
10 changes: 8 additions & 2 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::path::PathBuf;

use miette::Diagnostic;
use miette::{Diagnostic, NamedSource, SourceOffset};
use thiserror::Error;

/// all possible errors returned by the app.
Expand Down Expand Up @@ -29,7 +29,13 @@ pub enum Error {
url(docsrs),
help("See the configuration example https://github.com/BiznetGIO/digs#usage")
)]
InvalidConfig { message: String },
InvalidConfig {
#[source_code]
src: NamedSource,
#[label("{message}")]
bad_bit: SourceOffset,
message: String,
},
}

impl std::convert::From<std::io::Error> for Error {
Expand Down
3 changes: 2 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ fn run() -> Result<()> {
cli::RecordType::TXT => RecordType::TXT,
};

let printer = Printer::new(domain, record_type, opts.config);
let config_file = opts.config;
let printer = Printer::new(domain, record_type, config_file);
printer.print()?;
Ok(())
}
Expand Down
6 changes: 3 additions & 3 deletions src/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ use crate::{config, dns};
pub struct Printer {
domain: String,
record_type: RecordType,
config: PathBuf,
config_file: PathBuf,
}

impl Printer {
pub fn new(domain: String, record_type: RecordType, config: PathBuf) -> Self {
Self {
domain,
record_type,
config,
config_file: config,
}
}
pub fn print(&self) -> Result<(), Error> {
let config = config::read(&self.config)?;
let config = config::read(&self.config_file)?;

for server in config.servers {
let response = dns::query(&self.domain, self.record_type, &server.ip);
Expand Down

0 comments on commit 7879671

Please sign in to comment.