summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/args.rs70
-rw-r--r--src/lib.rs2
2 files changed, 71 insertions, 1 deletions
diff --git a/src/args.rs b/src/args.rs
new file mode 100644
index 0000000..2b93e71
--- /dev/null
+++ b/src/args.rs
@@ -0,0 +1,70 @@
+// Copyright (c) 2021 Soni L.
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license.
+// Documentation and comments licensed under CC BY-SA 4.0.
+
+//! Argument processing.
+
+use ::std::future::Future;
+use ::std::pin::Pin;
+
+use crate::strcursor::StringReader;
+use crate::suggestion::Suggestions;
+use crate::suggestion::SuggestionsBuilder;
+
+// FIXME delete when implemented
+pub struct CommandContext<'a, T>(::std::marker::PhantomData<(&'a str, T)>);
+
+/// An argument parser.
+///
+/// # Type params
+///
+/// - `'i`: Lifetime of the input.
+/// - `R`: The reader accepted by this argument type.
+/// - `S`: The source type accepted by this argument type.
+/// - `E`: The error type accepted by this argument type.
+///
+/// # Examples
+///
+/// A very basic `bool` argument type:
+///
+/// ```
+/// use ::iosonism::args::ArgumentType;
+/// use ::iosonism::strcursor::{ReadError, StringReader};
+///
+/// struct BoolArgumentType;
+///
+/// impl<'i, R, S, E> ArgumentType<'i, R, S, E> for BoolArgumentType
+/// where R: StringReader<'i>, E: ReadError<'i, R> {
+///     type Result = bool;
+///     fn parse(&self, reader: &mut R) -> Result<bool, E> {
+///         reader.read_bool()
+///     }
+/// }
+/// ```
+pub trait ArgumentType<'i, T: StringReader<'i>, S, E> {
+    /// The parsed type of the argument.
+    type Result: Sized + 'static;
+
+    /// Parses an argument of this type, returning the parsed argument.
+    fn parse(&self, reader: &mut T) -> Result<Self::Result, E>;
+
+    /// Creates suggestions for this argument.
+    // The hope here is that S is lightweight enough for one to clone into the
+    // closure. Unfortunately making it borrowable would be a pain.
+    // FIXME: this API doesn't look great, can we make it better somehow?
+    fn list_suggestions(
+        &self,
+        context: &CommandContext<'i, S>,
+        builder: SuggestionsBuilder<'i>,
+    ) -> Pin<Box<dyn Future<Output=Suggestions> + Send + 'i>> {
+        let _ = context;
+        let _ = builder;
+        todo!()
+    }
+
+    /// Returns examples for this argument.
+    fn get_examples(&self) -> Vec<&str> {
+        Vec::new()
+    }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 285c0a5..1557709 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -21,7 +21,7 @@
 
 pub mod strcursor;
 pub mod suggestion;
-//pub mod args;
+pub mod args;
 
 #[cfg(test)]
 mod tests {