summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/args.rs55
-rw-r--r--src/suggestion.rs5
2 files changed, 54 insertions, 6 deletions
diff --git a/src/args.rs b/src/args.rs
index 2b8eecf..62cd5e3 100644
--- a/src/args.rs
+++ b/src/args.rs
@@ -6,11 +6,12 @@
 //! Argument processing.
 
 use ::std::any::Any;
+use ::std::borrow::Cow;
 use ::std::future::Future;
 use ::std::io::Cursor;
 use ::std::pin::Pin;
 
-use crate::strcursor::StringReader;
+use crate::strcursor::{StringReader, ReadError};
 use crate::suggestion::Suggestions;
 use crate::suggestion::SuggestionsBuilder;
 
@@ -69,12 +70,12 @@ pub trait ArgumentType<S, E> {
     ) -> Pin<Box<dyn Future<Output=Suggestions> + Send + 'i>> {
         let _ = context;
         let _ = builder;
-        todo!()
+        Suggestions::empty()
     }
 
     /// Returns examples for this argument.
-    fn get_examples(&self) -> Vec<&str> {
-        Vec::new()
+    fn get_examples(&self) -> Cow<'static, [&str]> {
+        Cow::Borrowed(&[])
     }
 }
 
@@ -94,7 +95,7 @@ pub(crate) trait ArgumentTypeAny<S, E> {
     ) -> Pin<Box<dyn Future<Output=Suggestions> + Send + 'i>>;
 
     /// Returns examples for this argument.
-    fn get_examples(&self) -> Vec<&str>;
+    fn get_examples(&self) -> Cow<'static, [&str]>;
 }
 
 impl<T: ArgumentType<S, E>, S, E> ArgumentTypeAny<S, E> for T {
@@ -113,7 +114,49 @@ impl<T: ArgumentType<S, E>, S, E> ArgumentTypeAny<S, E> for T {
         self.list_suggestions(context, builder)
     }
 
-    fn get_examples(&self) -> Vec<&str> {
+    fn get_examples(&self) -> Cow<'static, [&str]> {
         self.get_examples()
     }
 }
+
+/// A boolean argument.
+// FIXME add examples/expand docs
+// FIXME add tests
+pub struct BoolArgumentType;
+
+/// An `ArgumentType` for `bool`.
+impl<S, E> ArgumentType<S, E> for BoolArgumentType
+where for<'i> E: ReadError<'i, Cursor<&'i str>>
+{
+    /// A `BoolArgumentType` parses a `bool`.
+    type Result = bool;
+
+    /// Attempts to parse a `bool` from the `reader`.
+    fn parse<'i>(
+        &self,
+        reader: &mut Cursor<&'i str>,
+    ) -> Result<bool, E> where E: 'i {
+        reader.read_bool()
+    }
+
+    /// Suggests completions for inputting a boolean argument.
+    fn list_suggestions<'i>(
+        &self,
+        context: &CommandContext<'i, S, E>,
+        mut builder: SuggestionsBuilder<'i>,
+    ) -> Pin<Box<dyn Future<Output=Suggestions> + Send + 'i>> {
+        let _ = context;
+        if "true".starts_with(builder.get_remaining()) {
+            builder.suggest("true".into());
+        }
+        if "false".starts_with(builder.get_remaining()) {
+            builder.suggest("false".into());
+        }
+        builder.drain_build_future()
+    }
+
+    /// Returns examples
+    fn get_examples(&self) -> Cow<'static, [&str]> {
+        Cow::Borrowed(&["true", "false"])
+    }
+}
diff --git a/src/suggestion.rs b/src/suggestion.rs
index a96e892..f8f4741 100644
--- a/src/suggestion.rs
+++ b/src/suggestion.rs
@@ -185,6 +185,11 @@ impl Suggestions {
             suggestions: suggestions,
         }
     }
+
+    /// Creates an empty `Suggestions` future.
+    pub fn empty<'a>() -> Pin<Box<dyn Future<Output=Suggestions> + Send + 'a>> {
+        Box::pin(async { EMPTY })
+    }
 }
 
 /// Helper for building suggestions.