From fb2bc2e64cda462a8be0acb19863796647d180d6 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 24 Apr 2021 17:08:47 +0200 Subject: Make error type explicit Signed-off-by: Matthias Beyer --- examples/option.rs | 10 ++--- examples/simple.rs | 5 +-- examples/vec.rs | 5 +-- src/backend/dialoguer.rs | 58 ++++++++++-------------- src/backend/mod.rs | 40 ++++++++--------- src/buildable.rs | 111 ++++++++++++++++++---------------------------- src/collection_builder.rs | 5 ++- src/error.rs | 7 +++ src/lib.rs | 92 ++++++++++++++++++-------------------- src/value_builder.rs | 5 ++- 10 files changed, 151 insertions(+), 187 deletions(-) create mode 100644 src/error.rs diff --git a/examples/option.rs b/examples/option.rs index 937733a..2a30eed 100644 --- a/examples/option.rs +++ b/examples/option.rs @@ -1,15 +1,11 @@ use interactive_object_builder::*; use interactive_object_builder::backend::dialoguer::DialoguerBackend; -fn main() -> Result<(), ()> { - let v = Option::::builder(DialoguerBackend).build_collection("optional yes/no") - .map_err(|_| ())?; - +fn main() -> Result<()> { + let v = Option::::builder(DialoguerBackend).build_collection("optional yes/no")?; println!("{:?}", v); - let v = Option::::builder(DialoguerBackend).build_collection("optional u64") - .map_err(|_| ())?; - + let v = Option::::builder(DialoguerBackend).build_collection("optional u64")?; println!("{:?}", v); Ok(()) } diff --git a/examples/simple.rs b/examples/simple.rs index 46dedfd..bd406c4 100644 --- a/examples/simple.rs +++ b/examples/simple.rs @@ -1,9 +1,8 @@ use interactive_object_builder::*; use interactive_object_builder::backend::dialoguer::DialoguerBackend; -fn main() -> Result<(), ()> { - let b = bool::builder(DialoguerBackend).build_value("Success?") - .map_err(|_| ())?; +fn main() -> Result<()> { + let b = bool::builder(DialoguerBackend).build_value("Success?")?; if b { println!("Success"); diff --git a/examples/vec.rs b/examples/vec.rs index 6aa10c4..6adeacc 100644 --- a/examples/vec.rs +++ b/examples/vec.rs @@ -1,9 +1,8 @@ use interactive_object_builder::*; use interactive_object_builder::backend::dialoguer::DialoguerBackend; -fn main() -> Result<(), ()> { - let v = Vec::::builder(DialoguerBackend).build_collection("yes/no flag") - .map_err(|_| ())?; +fn main() -> Result<()> { + let v = Vec::::builder(DialoguerBackend).build_collection("yes/no flag")?; println!("{:?}", v); Ok(()) diff --git a/src/backend/dialoguer.rs b/src/backend/dialoguer.rs index 5bdebd6..ec1f5b8 100644 --- a/src/backend/dialoguer.rs +++ b/src/backend/dialoguer.rs @@ -1,3 +1,4 @@ +use crate::error::Result; use crate::Backend; use crate::BuildableValue; use crate::CollectionBuilder; @@ -5,90 +6,82 @@ use crate::ValueBuilder; pub struct DialoguerBackend; -#[derive(Debug, thiserror::Error)] -pub enum DialoguerBackendError { - #[error("")] - Io(#[from] std::io::Error), -} - impl Backend for DialoguerBackend { - type Error = DialoguerBackendError; - - fn bool_builder(&self) -> Box> { + fn bool_builder(&self) -> Box> { Box::new(DialoguerValueBuilder::(std::marker::PhantomData)) } - fn u8_builder(&self) -> Box> { + fn u8_builder(&self) -> Box> { Box::new(DialoguerValueBuilder::(std::marker::PhantomData)) } - fn u16_builder(&self) -> Box> { + fn u16_builder(&self) -> Box> { Box::new(DialoguerValueBuilder::(std::marker::PhantomData)) } - fn u32_builder(&self) -> Box> { + fn u32_builder(&self) -> Box> { Box::new(DialoguerValueBuilder::(std::marker::PhantomData)) } - fn u64_builder(&self) -> Box> { + fn u64_builder(&self) -> Box> { Box::new(DialoguerValueBuilder::(std::marker::PhantomData)) } - fn u128_builder(&self) -> Box> { + fn u128_builder(&self) -> Box> { Box::new(DialoguerValueBuilder::(std::marker::PhantomData)) } - fn i8_builder(&self) -> Box> { + fn i8_builder(&self) -> Box> { Box::new(DialoguerValueBuilder::(std::marker::PhantomData)) } - fn i16_builder(&self) -> Box> { + fn i16_builder(&self) -> Box> { Box::new(DialoguerValueBuilder::(std::marker::PhantomData)) } - fn i32_builder(&self) -> Box> { + fn i32_builder(&self) -> Box> { Box::new(DialoguerValueBuilder::(std::marker::PhantomData)) } - fn i64_builder(&self) -> Box> { + fn i64_builder(&self) -> Box> { Box::new(DialoguerValueBuilder::(std::marker::PhantomData)) } - fn i128_builder(&self) -> Box> { + fn i128_builder(&self) -> Box> { Box::new(DialoguerValueBuilder::(std::marker::PhantomData)) } - fn usize_builder(&self) -> Box> { + fn usize_builder(&self) -> Box> { Box::new(DialoguerValueBuilder::(std::marker::PhantomData)) } - fn isize_builder(&self) -> Box> { + fn isize_builder(&self) -> Box> { Box::new(DialoguerValueBuilder::(std::marker::PhantomData)) } - fn f32_builder(&self) -> Box> { + fn f32_builder(&self) -> Box> { Box::new(DialoguerValueBuilder::(std::marker::PhantomData)) } - fn f64_builder(&self) -> Box> { + fn f64_builder(&self) -> Box> { Box::new(DialoguerValueBuilder::(std::marker::PhantomData)) } - fn char_builder(&self) -> Box> { + fn char_builder(&self) -> Box> { Box::new(DialoguerValueBuilder::(std::marker::PhantomData)) } - fn string_builder(&self) -> Box> { + fn string_builder(&self) -> Box> { Box::new(DialoguerValueBuilder::(std::marker::PhantomData)) } - fn vec_builder(&self) -> Box, Error = Self::Error>> + fn vec_builder(&self) -> Box>> where T: 'static + BuildableValue { Box::new(DialoguerVecBuilder::(std::marker::PhantomData)) } - fn option_builder(&self) -> Box, Error = Self::Error>> { + fn option_builder(&self) -> Box>> { Box::new(DialoguerOptionValueBuilder::(std::marker::PhantomData)) } } @@ -99,22 +92,20 @@ impl ValueBuilder for DialoguerValueBuilder T::Err: std::fmt::Display + std::fmt::Debug, { type Output = T; - type Error = DialoguerBackendError; - fn build_value(&self, question: &str) -> Result { + fn build_value(&self, question: &str) -> Result { dialoguer::Input::::new() .with_prompt(question) .interact_text() - .map_err(DialoguerBackendError::from) + .map_err(crate::error::IOBError::from) } } pub struct DialoguerOptionValueBuilder(std::marker::PhantomData); impl CollectionBuilder for DialoguerOptionValueBuilder { type Output = Option; - type Error = DialoguerBackendError; - fn build_collection(&self, value_desc: &str) -> Result { + fn build_collection(&self, value_desc: &str) -> Result { let q = format!("Do you want to provide a Value for {}", value_desc); let b = dialoguer::Input::::new() .with_prompt(q) @@ -136,9 +127,8 @@ impl CollectionBuilder for DialoguerVecBuilder where T: 'static + BuildableValue { type Output = Vec; - type Error = DialoguerBackendError; - fn build_collection(&self, value_desc: &str) -> Result { + fn build_collection(&self, value_desc: &str) -> Result { let mut buf = vec![]; loop { diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 3f72d66..5884726 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -6,29 +6,27 @@ use crate::ValueBuilder; /// A backend can be used to get builders for specific types pub trait Backend { - type Error: Sized; + fn bool_builder(&self) -> Box>; + fn u8_builder(&self) -> Box>; + fn u16_builder(&self) -> Box>; + fn u32_builder(&self) -> Box>; + fn u64_builder(&self) -> Box>; + fn u128_builder(&self) -> Box>; + fn i8_builder(&self) -> Box>; + fn i16_builder(&self) -> Box>; + fn i32_builder(&self) -> Box>; + fn i64_builder(&self) -> Box>; + fn i128_builder(&self) -> Box>; + fn usize_builder(&self) -> Box>; + fn isize_builder(&self) -> Box>; + fn f32_builder(&self) -> Box>; + fn f64_builder(&self) -> Box>; + fn char_builder(&self) -> Box>; + fn string_builder(&self) -> Box>; - fn bool_builder(&self) -> Box>; - fn u8_builder(&self) -> Box>; - fn u16_builder(&self) -> Box>; - fn u32_builder(&self) -> Box>; - fn u64_builder(&self) -> Box>; - fn u128_builder(&self) -> Box>; - fn i8_builder(&self) -> Box>; - fn i16_builder(&self) -> Box>; - fn i32_builder(&self) -> Box>; - fn i64_builder(&self) -> Box>; - fn i128_builder(&self) -> Box>; - fn usize_builder(&self) -> Box>; - fn isize_builder(&self) -> Box>; - fn f32_builder(&self) -> Box>; - fn f64_builder(&self) -> Box>; - fn char_builder(&self) -> Box>; - fn string_builder(&self) -> Box>; + fn option_builder(&self) -> Box>>; - fn option_builder(&self) -> Box, Error = Self::Error>>; - - fn vec_builder(&self) -> Box, Error = Self::Error>> + fn vec_builder(&self) -> Box>> where T: 'static + BuildableValue; } diff --git a/src/buildable.rs b/src/buildable.rs index 37bfc3c..54e7bbe 100644 --- a/src/buildable.rs +++ b/src/buildable.rs @@ -4,160 +4,141 @@ use crate::ValueBuilder; // A value that can be built interactively, using a Backend pub trait BuildableValue: Sized { - fn builder(backend: B) -> Box> - where E: Sized, - B: Backend - ; + fn builder(backend: B) -> Box> + where B: Backend; } impl BuildableValue for bool { - fn builder(backend: B) -> Box> - where E: Sized, - B: Backend + fn builder(backend: B) -> Box> + where B: Backend { backend.bool_builder() } } impl BuildableValue for u8 { - fn builder(backend: B) -> Box> - where E: Sized, - B: Backend + fn builder(backend: B) -> Box> + where B: Backend { backend.u8_builder() } } impl BuildableValue for u16 { - fn builder(backend: B) -> Box> - where E: Sized, - B: Backend + fn builder(backend: B) -> Box> + where B: Backend { backend.u16_builder() } } impl BuildableValue for u32 { - fn builder(backend: B) -> Box> - where E: Sized, - B: Backend + fn builder(backend: B) -> Box> + where B: Backend { backend.u32_builder() } } impl BuildableValue for u64 { - fn builder(backend: B) -> Box> - where E: Sized, - B: Backend + fn builder(backend: B) -> Box> + where B: Backend { backend.u64_builder() } } impl BuildableValue for u128 { - fn builder(backend: B) -> Box> - where E: Sized, - B: Backend + fn builder(backend: B) -> Box> + where B: Backend { backend.u128_builder() } } impl BuildableValue for i8 { - fn builder(backend: B) -> Box> - where E: Sized, - B: Backend + fn builder(backend: B) -> Box> + where B: Backend { backend.i8_builder() } } impl BuildableValue for i16 { - fn builder(backend: B) -> Box> - where E: Sized, - B: Backend + fn builder(backend: B) -> Box> + where B: Backend { backend.i16_builder() } } impl BuildableValue for i32 { - fn builder(backend: B) -> Box> - where E: Sized, - B: Backend + fn builder(backend: B) -> Box> + where B: Backend { backend.i32_builder() } } impl BuildableValue for i64 { - fn builder(backend: B) -> Box> - where E: Sized, - B: Backend + fn builder(backend: B) -> Box> + where B: Backend { backend.i64_builder() } } impl BuildableValue for i128 { - fn builder(backend: B) -> Box> - where E: Sized, - B: Backend + fn builder(backend: B) -> Box> + where B: Backend { backend.i128_builder() } } impl BuildableValue for usize { - fn builder(backend: B) -> Box> - where E: Sized, - B: Backend + fn builder(backend: B) -> Box> + where B: Backend { backend.usize_builder() } } impl BuildableValue for isize { - fn builder(backend: B) -> Box> - where E: Sized, - B: Backend + fn builder(backend: B) -> Box> + where B: Backend { backend.isize_builder() } } impl BuildableValue for f32 { - fn builder(backend: B) -> Box> - where E: Sized, - B: Backend + fn builder(backend: B) -> Box> + where B: Backend { backend.f32_builder() } } impl BuildableValue for f64 { - fn builder(backend: B) -> Box> - where E: Sized, - B: Backend + fn builder(backend: B) -> Box> + where B: Backend { backend.f64_builder() } } impl BuildableValue for char { - fn builder(backend: B) -> Box> - where E: Sized, - B: Backend + fn builder(backend: B) -> Box> + where B: Backend { backend.char_builder() } } impl BuildableValue for String { - fn builder(backend: B) -> Box> - where E: Sized, - B: Backend + fn builder(backend: B) -> Box> + where B: Backend { backend.string_builder() } @@ -165,29 +146,25 @@ impl BuildableValue for String { pub trait BuildableCollection { - fn builder(backend: B) -> Box> - where E: Sized, - B: Backend - ; + fn builder(backend: B) -> Box> + where B: Backend; } impl BuildableCollection for Vec - where T: 'static + BuildableValue + where T: 'static + BuildableValue, { - fn builder(backend: B) -> Box> - where E: Sized, - B: Backend + fn builder(backend: B) -> Box> + where B: Backend { backend.vec_builder::() } } impl BuildableCollection for Option - where T: 'static + BuildableValue + Sized + where T: 'static + BuildableValue + Sized, { - fn builder(backend: B) -> Box, Error = E>> - where E: Sized, - B: Backend + fn builder(backend: B) -> Box>> + where B: Backend { backend.option_builder() } diff --git a/src/collection_builder.rs b/src/collection_builder.rs index 70c1ae3..ee49896 100644 --- a/src/collection_builder.rs +++ b/src/collection_builder.rs @@ -1,10 +1,11 @@ +use crate::error::Result; + /// A collection type that can be built interactively /// /// That is, for example, a Vec<_>, a HashMap<_, _> or a struct pub trait CollectionBuilder { type Output: Sized; - type Error: Sized; - fn build_collection(&self, value_desc: &str) -> Result; + fn build_collection(&self, value_desc: &str) -> Result; } diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..bfcf175 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,7 @@ +#[derive(Debug, thiserror::Error)] +pub enum IOBError { + #[error("{}", .0)] + Io(#[from] std::io::Error), +} + +pub type Result = std::result::Result; diff --git a/src/lib.rs b/src/lib.rs index f7ef93b..9a89f37 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,6 +7,9 @@ pub use crate::buildable::*; pub mod collection_builder; pub use crate::collection_builder::*; +pub mod error; +pub use crate::error::*; + pub mod value_builder; pub use crate::value_builder::*; @@ -17,65 +20,63 @@ mod dummy_bool_test { struct DummyBackend; impl Backend for DummyBackend { - type Error = (); - - fn bool_builder(&self) -> Box> { + fn bool_builder(&self) -> Box> { Box::new(BoolValBuilder) } - fn u8_builder(&self) -> Box> { + fn u8_builder(&self) -> Box> { unimplemented!() } - fn u16_builder(&self) -> Box> { + fn u16_builder(&self) -> Box> { unimplemented!() } - fn u32_builder(&self) -> Box> { + fn u32_builder(&self) -> Box> { unimplemented!() } - fn u64_builder(&self) -> Box> { + fn u64_builder(&self) -> Box> { unimplemented!() } - fn u128_builder(&self) -> Box> { + fn u128_builder(&self) -> Box> { unimplemented!() } - fn i8_builder(&self) -> Box> { + fn i8_builder(&self) -> Box> { unimplemented!() } - fn i16_builder(&self) -> Box> { + fn i16_builder(&self) -> Box> { unimplemented!() } - fn i32_builder(&self) -> Box> { + fn i32_builder(&self) -> Box> { unimplemented!() } - fn i64_builder(&self) -> Box> { + fn i64_builder(&self) -> Box> { unimplemented!() } - fn i128_builder(&self) -> Box> { + fn i128_builder(&self) -> Box> { unimplemented!() } - fn usize_builder(&self) -> Box> { + fn usize_builder(&self) -> Box> { unimplemented!() } - fn isize_builder(&self) -> Box> { + fn isize_builder(&self) -> Box> { unimplemented!() } - fn f32_builder(&self) -> Box> { + fn f32_builder(&self) -> Box> { unimplemented!() } - fn f64_builder(&self) -> Box> { + fn f64_builder(&self) -> Box> { unimplemented!() } - fn char_builder(&self) -> Box> { + fn char_builder(&self) -> Box> { unimplemented!() } - fn string_builder(&self) -> Box> { + fn string_builder(&self) -> Box> { unimplemented!() } - fn option_builder(&self) -> Box, Error = Self::Error>> { + fn option_builder(&self) -> Box>> { unimplemented!() } - fn vec_builder(&self) -> Box, Error = Self::Error>> + fn vec_builder(&self) -> Box>> where T: 'static + BuildableValue { unimplemented!() @@ -85,9 +86,8 @@ mod dummy_bool_test { struct BoolValBuilder; impl ValueBuilder for BoolValBuilder { type Output = bool; - type Error = (); - fn build_value(&self, _question: &str) -> Result { + fn build_value(&self, _question: &str) -> Result { Ok(true) } } @@ -106,63 +106,61 @@ mod vec_test { struct DummyBackend; impl Backend for DummyBackend { - type Error = (); - - fn bool_builder(&self) -> Box> { + fn bool_builder(&self) -> Box> { Box::new(BoolValBuilder) } - fn u8_builder(&self) -> Box> { + fn u8_builder(&self) -> Box> { unimplemented!() } - fn u16_builder(&self) -> Box> { + fn u16_builder(&self) -> Box> { unimplemented!() } - fn u32_builder(&self) -> Box> { + fn u32_builder(&self) -> Box> { unimplemented!() } - fn u64_builder(&self) -> Box> { + fn u64_builder(&self) -> Box> { unimplemented!() } - fn u128_builder(&self) -> Box> { + fn u128_builder(&self) -> Box> { unimplemented!() } - fn i8_builder(&self) -> Box> { + fn i8_builder(&self) -> Box> { unimplemented!() } - fn i16_builder(&self) -> Box> { + fn i16_builder(&self) -> Box> { unimplemented!() } - fn i32_builder(&self) -> Box> { + fn i32_builder(&self) -> Box> { unimplemented!() } - fn i64_builder(&self) -> Box> { + fn i64_builder(&self) -> Box> { unimplemented!() } - fn i128_builder(&self) -> Box> { + fn i128_builder(&self) -> Box> { unimplemented!() } - fn usize_builder(&self) -> Box> { + fn usize_builder(&self) -> Box> { unimplemented!() } - fn isize_builder(&self) -> Box> { + fn isize_builder(&self) -> Box> { unimplemented!() } - fn f32_builder(&self) -> Box> { + fn f32_builder(&self) -> Box> { unimplemented!() } - fn f64_builder(&self) -> Box> { + fn f64_builder(&self) -> Box> { unimplemented!() } - fn char_builder(&self) -> Box> { + fn char_builder(&self) -> Box> { unimplemented!() } - fn string_builder(&self) -> Box> { + fn string_builder(&self) -> Box> { unimplemented!() } - fn option_builder(&self) -> Box, Error = Self::Error>> { + fn option_builder(&self) -> Box>> { unimplemented!() } - fn vec_builder(&self) -> Box, Error = Self::Error>> + fn vec_builder(&self) -> Box>> where T: 'static + BuildableValue { Box::new(VecBuilder::(std::marker::PhantomData)) @@ -172,9 +170,8 @@ mod vec_test { struct BoolValBuilder; impl ValueBuilder for BoolValBuilder { type Output = bool; - type Error = (); - fn build_value(&self, _question: &str) -> Result { + fn build_value(&self, _question: &str) -> Result { Ok(true) } } @@ -182,9 +179,8 @@ mod vec_test { pub struct VecBuilder(std::marker::PhantomData); impl CollectionBuilder for VecBuilder { type Output = Vec; - type Error = (); - fn build_collection(&self, value_desc: &str) -> Result { + fn build_collection(&self, value_desc: &str) -> Result { let mut buf = vec![]; loop { diff --git a/src/value_builder.rs b/src/value_builder.rs index 5418ee6..d7e045b 100644 --- a/src/value_builder.rs +++ b/src/value_builder.rs @@ -1,8 +1,9 @@ +use crate::error::Result; + /// A thing that can build a value by interactively asking the user a question pub trait ValueBuilder { type Output: Sized; - type Error: Sized; - fn build_value(&self, question: &str) -> Result; + fn build_value(&self, question: &str) -> Result; } -- cgit v1.2.3