summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2021-04-24 12:57:12 +0200
committerMatthias Beyer <mail@beyermatthias.de>2021-04-24 13:13:01 +0200
commit2cf8c68f5bbd197e5066a1904c4c0bc4d3e0fe0c (patch)
treecb361bd77e8ee098c6e5e9941dcb8a50518d1db7
parent330e1bc40c49c588da3b2a1d6f0cf804f00d4358 (diff)
Add support for Vec<T>
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r--src/backend/dialoguer.rs31
-rw-r--r--src/backend/mod.rs6
-rw-r--r--src/buildable.rs21
-rw-r--r--src/collection_builder.rs2
4 files changed, 59 insertions, 1 deletions
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::<String>(std::marker::PhantomData))
}
+ fn vec_builder<T>(&self) -> Box<dyn CollectionBuilder<Output = Vec<T>, Error = Self::Error>>
+ where T: 'static + BuildableValue
+ {
+ Box::new(DialoguerVecBuilder::<T>(std::marker::PhantomData))
+ }
+
}
pub struct DialoguerValueBuilder<T: Sized>(std::marker::PhantomData<T>);
@@ -99,3 +107,26 @@ impl<T> ValueBuilder for DialoguerValueBuilder<T>
}
+pub struct DialoguerVecBuilder<T: 'static + BuildableValue>(std::marker::PhantomData<T>);
+impl<T> CollectionBuilder for DialoguerVecBuilder<T>
+ where T: 'static + BuildableValue
+{
+ type Output = Vec<T>;
+ type Error = DialoguerBackendError;
+
+ fn build_collection(&self, value_desc: &str) -> Result<Self::Output, Self::Error> {
+ let mut buf = vec![];
+
+ loop {
+ let v: T = T::builder(DialoguerBackend).build_value(value_desc)?;
+ buf.push(v);
+
+ if !dialoguer::Input::<bool>::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<dyn ValueBuilder<Output = f64, Error = Self::Error>>;
fn char_builder(&self) -> Box<dyn ValueBuilder<Output = char, Error = Self::Error>>;
fn string_builder(&self) -> Box<dyn ValueBuilder<Output = String, Error = Self::Error>>;
+
+ fn vec_builder<T>(&self) -> Box<dyn CollectionBuilder<Output = Vec<T>, 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<E, B>(backend: B) -> Box<dyn CollectionBuilder<Output = Self, Error = E>>
+ where E: Sized,
+ B: Backend<Error = E>
+ ;
+}
+
+impl<T> BuildableCollection for Vec<T>
+ where T: 'static + BuildableValue
+{
+ fn builder<E, B>(backend: B) -> Box<dyn CollectionBuilder<Output = Self, Error = E>>
+ where E: Sized,
+ B: Backend<Error = E>
+ {
+ backend.vec_builder::<T>()
+ }
+}
+
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<Self::Output, Self::Error>;
+ fn build_collection(&self, value_desc: &str) -> Result<Self::Output, Self::Error>;
}