From 2cf8c68f5bbd197e5066a1904c4c0bc4d3e0fe0c Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 24 Apr 2021 12:57:12 +0200 Subject: Add support for Vec Signed-off-by: Matthias Beyer --- src/backend/dialoguer.rs | 31 +++++++++++++++++++++++++++++++ src/backend/mod.rs | 6 ++++++ src/buildable.rs | 21 +++++++++++++++++++++ src/collection_builder.rs | 2 +- 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/backend/dialoguer.rs b/src/backend/dialoguer.rs index 6689250..11d5349 100644 --- a/src/backend/dialoguer.rs +++ b/src/backend/dialoguer.rs @@ -1,5 +1,7 @@ use crate::Backend; use crate::ValueBuilder; +use crate::BuildableValue; +use crate::CollectionBuilder; pub struct DialoguerBackend; @@ -80,6 +82,12 @@ impl Backend for DialoguerBackend { Box::new(DialoguerValueBuilder::(std::marker::PhantomData)) } + fn vec_builder(&self) -> Box, Error = Self::Error>> + where T: 'static + BuildableValue + { + Box::new(DialoguerVecBuilder::(std::marker::PhantomData)) + } + } pub struct DialoguerValueBuilder(std::marker::PhantomData); @@ -99,3 +107,26 @@ impl ValueBuilder for DialoguerValueBuilder } +pub struct DialoguerVecBuilder(std::marker::PhantomData); +impl CollectionBuilder for DialoguerVecBuilder + where T: 'static + BuildableValue +{ + type Output = Vec; + type Error = DialoguerBackendError; + + fn build_collection(&self, value_desc: &str) -> Result { + let mut buf = vec![]; + + loop { + let v: T = T::builder(DialoguerBackend).build_value(value_desc)?; + buf.push(v); + + if !dialoguer::Input::::new().with_prompt("Another one?").interact_text()? { + break + } + } + + Ok(buf) + } +} + diff --git a/src/backend/mod.rs b/src/backend/mod.rs index dfd77c8..1353a6d 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -1,6 +1,8 @@ pub mod dialoguer; use crate::ValueBuilder; +use crate::BuildableValue; +use crate::CollectionBuilder; /// A backend can be used to get builders for specific types pub trait Backend { @@ -23,6 +25,10 @@ pub trait Backend { fn f64_builder(&self) -> Box>; fn char_builder(&self) -> Box>; fn string_builder(&self) -> Box>; + + fn vec_builder(&self) -> Box, Error = Self::Error>> + where T: 'static + BuildableValue + ; } diff --git a/src/buildable.rs b/src/buildable.rs index 22f6d0a..95382e7 100644 --- a/src/buildable.rs +++ b/src/buildable.rs @@ -1,4 +1,5 @@ use crate::ValueBuilder; +use crate::CollectionBuilder; use crate::Backend; // A value that can be built interactively, using a Backend @@ -162,3 +163,23 @@ impl BuildableValue for String { } } + + +pub trait BuildableCollection { + fn builder(backend: B) -> Box> + where E: Sized, + B: Backend + ; +} + +impl BuildableCollection for Vec + where T: 'static + BuildableValue +{ + fn builder(backend: B) -> Box> + where E: Sized, + B: Backend + { + backend.vec_builder::() + } +} + diff --git a/src/collection_builder.rs b/src/collection_builder.rs index 3535ee2..70c1ae3 100644 --- a/src/collection_builder.rs +++ b/src/collection_builder.rs @@ -5,6 +5,6 @@ pub trait CollectionBuilder { type Output: Sized; type Error: Sized; - fn build_collection(&self) -> Result; + fn build_collection(&self, value_desc: &str) -> Result; } -- cgit v1.2.3 From 8e4d1f43c5383c5efc112e39f035476a4e63713e Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 24 Apr 2021 13:22:57 +0200 Subject: Add missing backend functions Signed-off-by: Matthias Beyer --- src/lib.rs | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index e054fa1..6d62617 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,6 +22,60 @@ mod dummy_bool_test { fn bool_builder(&self) -> Box> { Box::new(BoolValBuilder) } + fn u8_builder(&self) -> Box> { + unimplemented!() + } + fn u16_builder(&self) -> Box> { + unimplemented!() + } + fn u32_builder(&self) -> Box> { + unimplemented!() + } + fn u64_builder(&self) -> Box> { + unimplemented!() + } + fn u128_builder(&self) -> Box> { + unimplemented!() + } + fn i8_builder(&self) -> Box> { + unimplemented!() + } + fn i16_builder(&self) -> Box> { + unimplemented!() + } + fn i32_builder(&self) -> Box> { + unimplemented!() + } + fn i64_builder(&self) -> Box> { + unimplemented!() + } + fn i128_builder(&self) -> Box> { + unimplemented!() + } + fn usize_builder(&self) -> Box> { + unimplemented!() + } + fn isize_builder(&self) -> Box> { + unimplemented!() + } + fn f32_builder(&self) -> Box> { + unimplemented!() + } + fn f64_builder(&self) -> Box> { + unimplemented!() + } + fn char_builder(&self) -> Box> { + unimplemented!() + } + fn string_builder(&self) -> Box> { + unimplemented!() + } + + fn vec_builder(&self) -> Box, Error = Self::Error>> + where T: 'static + BuildableValue + { + unimplemented!() + } } struct BoolValBuilder; -- cgit v1.2.3 From 851a1adf02093cdb094f85978bc1433fd18a28ec Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 24 Apr 2021 13:23:05 +0200 Subject: Add test for Vec Signed-off-by: Matthias Beyer --- src/lib.rs | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 6d62617..21d5ab4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -95,3 +95,107 @@ mod dummy_bool_test { } } + +#[cfg(test)] +mod vec_test { + use super::*; + + struct DummyBackend; + impl Backend for DummyBackend { + type Error = (); + + fn bool_builder(&self) -> Box> { + Box::new(BoolValBuilder) + } + fn u8_builder(&self) -> Box> { + unimplemented!() + } + fn u16_builder(&self) -> Box> { + unimplemented!() + } + fn u32_builder(&self) -> Box> { + unimplemented!() + } + fn u64_builder(&self) -> Box> { + unimplemented!() + } + fn u128_builder(&self) -> Box> { + unimplemented!() + } + fn i8_builder(&self) -> Box> { + unimplemented!() + } + fn i16_builder(&self) -> Box> { + unimplemented!() + } + fn i32_builder(&self) -> Box> { + unimplemented!() + } + fn i64_builder(&self) -> Box> { + unimplemented!() + } + fn i128_builder(&self) -> Box> { + unimplemented!() + } + fn usize_builder(&self) -> Box> { + unimplemented!() + } + fn isize_builder(&self) -> Box> { + unimplemented!() + } + fn f32_builder(&self) -> Box> { + unimplemented!() + } + fn f64_builder(&self) -> Box> { + unimplemented!() + } + fn char_builder(&self) -> Box> { + unimplemented!() + } + fn string_builder(&self) -> Box> { + unimplemented!() + } + fn vec_builder(&self) -> Box, Error = Self::Error>> + where T: 'static + BuildableValue + { + Box::new(VecBuilder::(std::marker::PhantomData)) + } + } + + struct BoolValBuilder; + impl ValueBuilder for BoolValBuilder { + type Output = bool; + type Error = (); + + fn build_value(&self, _question: &str) -> Result { + Ok(true) + } + } + + pub struct VecBuilder(std::marker::PhantomData); + impl CollectionBuilder for VecBuilder { + type Output = Vec; + type Error = (); + + fn build_collection(&self, value_desc: &str) -> Result { + let mut buf = vec![]; + + loop { + let v: T = T::builder(DummyBackend).build_value(value_desc)?; + buf.push(v); + + if buf.len() == 3 { + break + } + } + + Ok(buf) + } + } + + #[test] + fn test_build_vec() { + let v = Vec::::builder(DummyBackend).build_collection("flag").unwrap(); + assert_eq!(v, vec![true, true, true]); + } +} -- cgit v1.2.3