summary refs log tree commit diff stats
path: root/src/args.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/args.rs')
-rw-r--r--src/args.rs93
1 files changed, 92 insertions, 1 deletions
diff --git a/src/args.rs b/src/args.rs
index ca35bfb..b3bd7ca 100644
--- a/src/args.rs
+++ b/src/args.rs
@@ -134,7 +134,6 @@ impl<T: ArgumentType<S, E> + Send + Sync, S, E> ArgumentTypeAny<S, E> for T {
 
 /// A boolean argument.
 // FIXME add examples/expand docs
-// FIXME add tests
 #[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash, Default)]
 pub struct BoolArgumentType;
 
@@ -324,3 +323,95 @@ where
         Cow::Borrowed(&["0", "1.2", ".5", "-1", "-.5", "-1234.56"])
     }
 }
+
+/// A string argument.
+#[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)]
+pub struct StringArgumentType(StringMode);
+
+/// Creates a string argument that accepts simple words.
+///
+/// # Examples
+///
+/// ```rust
+/// use ::iosonism::args::word;
+///
+/// let argtype = word();
+/// ```
+pub fn word() -> StringArgumentType {
+    StringArgumentType(StringMode::SingleWord)
+}
+
+/// Creates a string argument that accepts simple words and quoted strings.
+///
+/// # Examples
+///
+/// ```rust
+/// use ::iosonism::args::string;
+///
+/// let argtype = string();
+/// ```
+pub fn string() -> StringArgumentType {
+    StringArgumentType(StringMode::QuotablePhrase)
+}
+
+/// Creates a string argument that accepts simple text until the end of the
+/// input.
+///
+/// # Examples
+///
+/// ```rust
+/// use ::iosonism::args::greedy_string;
+///
+/// let argtype = greedy_string();
+/// ```
+pub fn greedy_string() -> StringArgumentType {
+    StringArgumentType(StringMode::GreedyPhrase)
+}
+
+/// The "mode" of parsing a string.
+#[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)]
+enum StringMode {
+    SingleWord,
+    QuotablePhrase,
+    GreedyPhrase,
+}
+
+/// An `ArgumentType` for strings.
+impl<S, E> ArgumentType<S, E> for StringArgumentType
+where for<'i> E: ReadError<'i, Cursor<&'i str>> {
+    /// A `StringArgumentType` parses a string.
+    type Result = String;
+
+    /// Attempts to parse a string from the `reader`.
+    fn parse<'i>(
+        &self,
+        reader: &mut Cursor<&'i str>,
+    ) -> Result<String, E> where E: 'i {
+        match self {
+            Self(StringMode::SingleWord) => {
+                Ok(reader.read_unquoted_str().into())
+            },
+            Self(StringMode::QuotablePhrase) => reader.read_string(),
+            Self(StringMode::GreedyPhrase) => {
+                let text = reader.get_remaining().into();
+                reader.set_position(reader.total_len() as u64);
+                Ok(text)
+            },
+        }
+    }
+
+    /// Returns examples
+    fn get_examples(&self) -> Cow<'static, [&str]> {
+        match self {
+            Self(StringMode::SingleWord) => {
+                Cow::Borrowed(&["word", "words_With_underscores"])
+            },
+            Self(StringMode::QuotablePhrase) => {
+                Cow::Borrowed(&["\"quoted phrase\"", "word", "\"\""])
+            },
+            Self(StringMode::GreedyPhrase) => {
+                Cow::Borrowed(&["word", "with spaces", "text \"and symbols\""])
+            },
+        }
+    }
+}