Skip to content

Commit

Permalink
Switch to anyhow for runtime error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
arnodb committed Dec 4, 2024
1 parent 3d2678a commit 6d7c9b1
Show file tree
Hide file tree
Showing 15 changed files with 62 additions and 88 deletions.
4 changes: 2 additions & 2 deletions codegen/quirky_binder_codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,8 @@ impl ModuleCode {
quote! {
writeln!(file, r#"
#[test]
fn {}() -> Result<(), QuirkyBinderError> {{
main(ChainConfiguration::default())
fn {}() {{
main(ChainConfiguration::default()).unwrap();
}}
"#, #test_name)?;
}
Expand Down
74 changes: 37 additions & 37 deletions contrib/quirky_binder_csv/src/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ impl DynNode for ReadCsv {
&self.outputs
}

fn gen_chain(&self, _graph: &Graph, chain: &mut Chain) {
fn gen_chain(&self, graph: &Graph, chain: &mut Chain) {
let thread_id = chain.new_threaded_source(
&self.name,
ChainThreadType::Regular,
Expand All @@ -130,49 +130,50 @@ impl DynNode for ReadCsv {

let has_headers = self.has_headers;

let read_headers = if has_headers {
let header_checks = self
.fields
.iter()
.enumerate()
.map(|(index, (field_name, _))| {
let field_name = field_name.name();
quote! {
let header = iter.next();
if let Some(header) = header {
if header != #field_name {
return Err(QuirkyBinderError::Custom(format!(
"Header mismatch at position {}, expected {} but got {}",
#index, #field_name, header)));
let bail = graph.chain_customizer().bail_macro.to_path();

let read_headers =
if has_headers {
let header_checks = self.fields.iter().enumerate().map(
|(index, (field_name, _))| {
let field_name = field_name.name();
quote! {
let header = iter.next();
if let Some(header) = header {
if header != #field_name {
#bail!(
"Header mismatch at position {}, expected {} but got {}",
#index, #field_name, header
);
}
} else {
#bail!(
"Missing header at position {}, expected {}",
#index, #field_name
);
}
} else {
return Err(QuirkyBinderError::Custom(format!(
"Missing header at position {}, expected {}",
#index, #field_name)));
}
}
});
Some(quote! {{
let headers = reader.headers()
.map_err(|err| QuirkyBinderError::Custom(err.to_string()))?;
let mut iter = headers.into_iter();
#(#header_checks)*
if let Some(header) = iter.next() {
return Err(QuirkyBinderError::Custom(format!("Unexpected extra header {}", header)));
};
}})
} else {
None
};
},
);
Some(quote! {{
let headers = reader.headers()?;
let mut iter = headers.into_iter();
#(#header_checks)*
if let Some(header) = iter.next() {
#bail!("Unexpected extra header {}", header);
};
}})
} else {
None
};

let thread_body = quote! {
let output = thread_control.output_0.take().expect("output 0");
move || {
use std::fs::File;
use std::io::BufReader;

let file = File::open(#input_file)
.map_err(|err| QuirkyBinderError::Custom(err.to_string()))?;
let file = File::open(#input_file)?;

let mut reader = csv::ReaderBuilder::new()
.has_headers(#has_headers)
Expand All @@ -181,8 +182,7 @@ impl DynNode for ReadCsv {
#read_headers

for result in reader.deserialize() {
let record = result
.map_err(|err| QuirkyBinderError::Custom(err.to_string()))?;
let record = result?;
output.send(Some(record))?;
}
output.send(None)?;
Expand Down
12 changes: 4 additions & 8 deletions contrib/quirky_binder_csv/src/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,7 @@ impl DynNode for WriteCsv {
let variant = &record_definition[self.inputs.single().variant_id()];
let headers = variant.data().map(|d| record_definition[d].name());
Some(quote! {{
writer.write_record([#(#headers),*])
.map_err(|err| QuirkyBinderError::Custom(err.to_string()))?;
writer.write_record([#(#headers),*])?;
}})
} else {
None
Expand All @@ -111,12 +110,10 @@ impl DynNode for WriteCsv {
let file_path = Path::new(#output_file);
if let Some(parent) = file_path.parent() {
if !parent.exists() {
create_dir_all(parent)
.map_err(|err| QuirkyBinderError::Custom(err.to_string()))?;
create_dir_all(parent)?;
}
}
let file = File::create(file_path)
.map_err(|err| QuirkyBinderError::Custom(err.to_string()))?;
let file = File::create(file_path)?;

let mut writer = csv::WriterBuilder::new()
.has_headers(false)
Expand All @@ -125,8 +122,7 @@ impl DynNode for WriteCsv {
#write_headers

while let Some(record) = input.next()? {
writer.serialize(record)
.map_err(|err| QuirkyBinderError::Custom(err.to_string()))?;
writer.serialize(record)?;
}

Ok(())
Expand Down
1 change: 1 addition & 0 deletions examples/quirky_binder_example_index_first_char/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ edition = "2021"
rust-version = "1.65.0"

[dependencies]
anyhow = "1"
fallible-iterator = "0.3"
itertools = "0.10"
quirky_binder_support = { path = "../../quirky_binder_support" }
Expand Down
2 changes: 1 addition & 1 deletion examples/quirky_binder_example_index_first_char/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ use super::tokenize;
let mut input = stdin.lock();
let mut buffer = String::new();
loop {
let read = input.read_line(&mut buffer).map_err(|err| QuirkyBinderError::Custom(err.to_string()))?;
let read = input.read_line(&mut buffer)?;
if read > 0 {
let value = std::mem::take(&mut buffer);
let value = value.trim_end_matches('\n');
Expand Down
1 change: 1 addition & 0 deletions examples/quirky_binder_example_tree/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ edition = "2021"
rust-version = "1.65.0"

[dependencies]
anyhow = "1"
fallible-iterator = "0.3"
quirky_binder_support = { path = "../../quirky_binder_support" }
serde = "1"
Expand Down
4 changes: 2 additions & 2 deletions examples/quirky_binder_example_tree/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use quirky_binder::{
let mut full_name_index = BTreeMap::<PathBuf, usize>::new();
for (id, entry) in WalkDir::new(thread_control.chain_configuration.variables["root"].clone()).into_iter().enumerate() {
let entry = entry.map_err(|err| QuirkyBinderError::Custom(err.to_string()))?;
let entry = entry?;
let parent_id = entry.path().parent()
.and_then(|parent_path| {
Expand All @@ -50,7 +50,7 @@ use quirky_binder::{
vacant.insert(id);
},
Entry::Occupied(occupied) => {
return Err(QuirkyBinderError::Custom(format!("Already seen file {}", occupied.key().to_string_lossy())));
anyhow::bail!("Already seen file {}", occupied.key().to_string_lossy());
},
}
Expand Down
3 changes: 2 additions & 1 deletion examples/quirky_binder_example_wordlist/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ edition = "2021"
rust-version = "1.65.0"

[dependencies]
quirky_binder_support = { path = "../../quirky_binder_support" }
anyhow = "1"
fallible-iterator = "0.3"
quirky_binder_support = { path = "../../quirky_binder_support" }
serde = "1"
static_assertions = "1"
truc_runtime = { git = "https://github.com/arnodb/truc.git" }
Expand Down
2 changes: 1 addition & 1 deletion examples/quirky_binder_example_wordlist/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use quirky_binder::{
let mut input = stdin.lock();
let mut buffer = String::new();
loop {
let read = input.read_line(&mut buffer).map_err(|err| QuirkyBinderError::Custom(err.to_string()))?;
let read = input.read_line(&mut buffer)?;
if read > 0 {
let value = std::mem::take(&mut buffer);
let value = value.trim_end_matches('\n');
Expand Down
5 changes: 4 additions & 1 deletion quirky_binder/src/chain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -791,14 +791,16 @@ impl<'a> Chain<'a> {

pub const DEFAULT_CHAIN_ROOT_MODULE_NAME: [&str; 2] = ["crate", "chain"];
pub const DEFAULT_CHAIN_STREAMS_MODULE_NAME: &str = "streams";
pub const DEFAULT_CHAIN_ERROR_TYPE: [&str; 2] = ["quirky_binder_support", "QuirkyBinderError"];
pub const DEFAULT_CHAIN_ERROR_TYPE: [&str; 2] = ["anyhow", "Error"];
pub const DEFAULT_CHAIN_BAIL_MACRO: [&str; 2] = ["anyhow", "bail"];
pub const DEFAULT_CHAIN_MAIN_NAME: &str = "main";

pub struct ChainCustomizer {
pub streams_module_name: FullyQualifiedName,
pub module_name: FullyQualifiedName,
pub custom_module_imports: Vec<(String, String)>,
pub error_type: FullyQualifiedName,
pub bail_macro: FullyQualifiedName,
pub main_name: String,
pub main_attrs: Vec<String>,
}
Expand Down Expand Up @@ -832,6 +834,7 @@ impl Default for ChainCustomizer {
module_name: FullyQualifiedName::new_n(DEFAULT_CHAIN_ROOT_MODULE_NAME.iter()),
custom_module_imports: vec![],
error_type: FullyQualifiedName::new_n(DEFAULT_CHAIN_ERROR_TYPE.iter()),
bail_macro: FullyQualifiedName::new_n(DEFAULT_CHAIN_BAIL_MACRO.iter()),
main_name: DEFAULT_CHAIN_MAIN_NAME.to_string(),
main_attrs: Vec::default(),
}
Expand Down
5 changes: 5 additions & 0 deletions quirky_binder/src/support/name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ impl FullyQualifiedName {
pub fn to_name(&self) -> proc_macro2::Ident {
format_ident!("{}", **self.last().expect("last"))
}

pub fn to_path(&self) -> proc_macro2::TokenStream {
let segments = self.0.iter().map(|seg| format_ident!("{}", seg.as_ref()));
quote! { #(#segments)::* }
}
}

impl Display for FullyQualifiedName {
Expand Down
1 change: 0 additions & 1 deletion quirky_binder_support/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ lazy_static = "1"
quirky_binder_codegen_macro = { version = "0.1.1-dev", path = "../codegen/quirky_binder_codegen_macro" }
serde = { version = "1", features = ["derive"] }
tempfile = "3"
thiserror = "1"

[dev-dependencies]
assert_matches = "1"
Expand Down
34 changes: 0 additions & 34 deletions quirky_binder_support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,49 +10,15 @@ extern crate derive_more;
extern crate derive_new;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate thiserror;

pub use quirky_binder_codegen_macro::{tracking_allocator_main, tracking_allocator_static};

pub mod chain;
pub mod data;
pub mod iterator;

use std::sync::mpsc::{RecvError, SendError};

use serde::{Deserialize, Serialize};

#[derive(Error, Debug)]
pub enum QuirkyBinderError {
#[error("Error: {0}")]
Custom(String),
#[error("Pipe read error")]
PipeRead,
#[error("Pipe write error")]
PipeWrite,
#[error("Bincode error {0}")]
Bincode(#[from] bincode::Error),
}

impl QuirkyBinderError {
pub fn custom(error: String) -> Self {
Self::Custom(error)
}
}

impl From<RecvError> for QuirkyBinderError {
fn from(_: RecvError) -> Self {
Self::PipeRead
}
}

impl<T> From<SendError<T>> for QuirkyBinderError {
fn from(_: SendError<T>) -> Self {
Self::PipeWrite
}
}

#[derive(
Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Display, Deref, new, Serialize, Deserialize,
)]
Expand Down
1 change: 1 addition & 0 deletions tests/quirky_binder_tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ edition = "2021"
rust-version = "1.65.0"

[dependencies]
anyhow = "1"
csv = "1"
fallible-iterator = "0.3"
more-asserts = "0.3"
Expand Down
1 change: 1 addition & 0 deletions tests/quirky_binder_tests_source/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ edition = "2021"
rust-version = "1.65.0"

[dependencies]
anyhow = "1"
handlebars = "4"
quirky_binder = { path = "../../quirky_binder" }
quirky_binder_csv = { path = "../../contrib/quirky_binder_csv" }
Expand Down

0 comments on commit 6d7c9b1

Please sign in to comment.