From d2c13e6f22bb5a116f189c348213e2a45e439df6 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 24 Apr 2021 12:57:12 +0200 Subject: Add support for Option Signed-off-by: Matthias Beyer --- src/backend/dialoguer.rs | 26 +++++++++++++++++++++++++- src/backend/mod.rs | 7 ++++--- src/buildable.rs | 16 +++++++++++++--- src/lib.rs | 7 +++++++ 4 files changed, 49 insertions(+), 7 deletions(-) diff --git a/src/backend/dialoguer.rs b/src/backend/dialoguer.rs index 11d5349..5bdebd6 100644 --- a/src/backend/dialoguer.rs +++ b/src/backend/dialoguer.rs @@ -1,7 +1,7 @@ use crate::Backend; -use crate::ValueBuilder; use crate::BuildableValue; use crate::CollectionBuilder; +use crate::ValueBuilder; pub struct DialoguerBackend; @@ -88,6 +88,9 @@ impl Backend for DialoguerBackend { Box::new(DialoguerVecBuilder::(std::marker::PhantomData)) } + fn option_builder(&self) -> Box, Error = Self::Error>> { + Box::new(DialoguerOptionValueBuilder::(std::marker::PhantomData)) + } } pub struct DialoguerValueBuilder(std::marker::PhantomData); @@ -106,6 +109,27 @@ impl ValueBuilder for DialoguerValueBuilder } } +pub struct DialoguerOptionValueBuilder(std::marker::PhantomData); +impl CollectionBuilder for DialoguerOptionValueBuilder { + type Output = Option; + type Error = DialoguerBackendError; + + 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) + .interact_text()?; + + if b { + T::builder(DialoguerBackend) + .build_value(value_desc) + .map(Some) + } else { + Ok(None) + } + } +} + pub struct DialoguerVecBuilder(std::marker::PhantomData); impl CollectionBuilder for DialoguerVecBuilder diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 1353a6d..3f72d66 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -1,8 +1,8 @@ pub mod dialoguer; -use crate::ValueBuilder; use crate::BuildableValue; use crate::CollectionBuilder; +use crate::ValueBuilder; /// A backend can be used to get builders for specific types pub trait Backend { @@ -26,9 +26,10 @@ pub trait Backend { fn char_builder(&self) -> Box>; fn string_builder(&self) -> Box>; + fn option_builder(&self) -> Box, Error = Self::Error>>; + fn vec_builder(&self) -> Box, Error = Self::Error>> - where T: 'static + BuildableValue - ; + where T: 'static + BuildableValue; } diff --git a/src/buildable.rs b/src/buildable.rs index 95382e7..37bfc3c 100644 --- a/src/buildable.rs +++ b/src/buildable.rs @@ -1,6 +1,6 @@ -use crate::ValueBuilder; -use crate::CollectionBuilder; use crate::Backend; +use crate::CollectionBuilder; +use crate::ValueBuilder; // A value that can be built interactively, using a Backend pub trait BuildableValue: Sized { @@ -164,7 +164,6 @@ impl BuildableValue for String { } - pub trait BuildableCollection { fn builder(backend: B) -> Box> where E: Sized, @@ -183,3 +182,14 @@ impl BuildableCollection for Vec } } +impl BuildableCollection for Option + where T: 'static + BuildableValue + Sized +{ + fn builder(backend: B) -> Box, Error = E>> + where E: Sized, + B: Backend + { + backend.option_builder() + } +} + diff --git a/src/lib.rs b/src/lib.rs index 21d5ab4..f7ef93b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -71,6 +71,10 @@ mod dummy_bool_test { unimplemented!() } + fn option_builder(&self) -> Box, Error = Self::Error>> { + unimplemented!() + } + fn vec_builder(&self) -> Box, Error = Self::Error>> where T: 'static + BuildableValue { @@ -155,6 +159,9 @@ mod vec_test { fn string_builder(&self) -> Box> { unimplemented!() } + fn option_builder(&self) -> Box, Error = Self::Error>> { + unimplemented!() + } fn vec_builder(&self) -> Box, Error = Self::Error>> where T: 'static + BuildableValue { -- cgit v1.2.3 From ddaa455a66bb33299ea67e744f95c92b23715f32 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 24 Apr 2021 13:34:01 +0200 Subject: Add example for Option and Option Signed-off-by: Matthias Beyer --- examples/option.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 examples/option.rs diff --git a/examples/option.rs b/examples/option.rs new file mode 100644 index 0000000..937733a --- /dev/null +++ b/examples/option.rs @@ -0,0 +1,15 @@ +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(|_| ())?; + + println!("{:?}", v); + + let v = Option::::builder(DialoguerBackend).build_collection("optional u64") + .map_err(|_| ())?; + + println!("{:?}", v); + Ok(()) +} -- cgit v1.2.3