aboutsummaryrefslogtreecommitdiff
path: root/src/framework
diff options
context:
space:
mode:
authoracdenisSK <[email protected]>2018-06-21 19:21:42 +0200
committeracdenisSK <[email protected]>2018-06-21 19:22:12 +0200
commitcd4fd1e7836ebb3341000864fa440865964b4ea0 (patch)
tree230528b323b412b0a5cebe2af9cca186beeda030 /src/framework
parentDirectly use the iterator (diff)
downloadserenity-cd4fd1e7836ebb3341000864fa440865964b4ea0.tar.xz
serenity-cd4fd1e7836ebb3341000864fa440865964b4ea0.zip
Miscellaneous changes in Args
- Do not be lazy and DO add an example for the `_*` methods. - Reorganize the methods so they're more coherent. - Use the `rest` method than to rely on deref (which in turn relies on `full`).
Diffstat (limited to 'src/framework')
-rw-r--r--src/framework/standard/args.rs553
1 files changed, 286 insertions, 267 deletions
diff --git a/src/framework/standard/args.rs b/src/framework/standard/args.rs
index 1e9acc7..2648a30 100644
--- a/src/framework/standard/args.rs
+++ b/src/framework/standard/args.rs
@@ -261,8 +261,26 @@ impl<'a> Lexer<'a> {
/// assert_eq!(res, "420");
/// ```
///
-/// **A category of methods not showcased as an example**: `*_n` methods.
-/// Their docs are good enough to explain themselves. (+ don't want to clutter this doc with another Example)
+/// Hmm, taking a glance at the prior example, it seems we have an issue with reading the same argument over and over.
+/// Is there a more sensible solution than rewinding...? Actually, there is! The `*_n` methods:
+///
+/// ```rust
+/// use serenity::framework::standard::Args;
+///
+/// let mut args = Args::new("four five six three", &[" ".to_string()]);
+///
+/// assert_eq!(args.single_n::<String>().unwrap(), "four");
+///
+/// // It might suggest we've lost the `four`, but in fact, we didn't! And not only that, we can do it an infinite amount of times!
+/// assert_eq!(args.single_n::<String>().unwrap(), "four");
+/// assert_eq!(args.single_n::<String>().unwrap(), "four");
+/// assert_eq!(args.single_n::<String>().unwrap(), "four");
+/// assert_eq!(args.single_n::<String>().unwrap(), "four");
+///
+/// // Only if we use its parent method will we then lose it.
+/// assert_eq!(args.single::<String>().unwrap(), "four");
+/// assert_eq!(args.single_n::<String>().unwrap(), "five");
+/// ```
#[derive(Clone, Debug)]
pub struct Args {
message: String,
@@ -336,7 +354,7 @@ impl Args {
/// let args = Args::new("42 69", &[" ".to_string()]);
///
/// assert_eq!(args.single_n::<u32>().unwrap(), 42);
- /// assert_eq!(args, "42 69");
+ /// assert_eq!(args.rest(), "42 69");
/// ```
///
/// [`single`]: #method.single
@@ -351,488 +369,489 @@ impl Args {
Ok(T::from_str(&cur.lit)?)
}
- /// Gets original message passed to the command.
+ /// "Skip" the argument (Sugar for `args.single::<String>().ok()`)
///
/// # Examples
///
/// ```rust
/// use serenity::framework::standard::Args;
///
- /// let args = Args::new("42 69", &[" ".to_string()]);
+ /// let mut args = Args::new("42 69", &[" ".to_string()]);
///
- /// assert_eq!(args.full(), "42 69");
+ /// args.skip();
+ /// assert_eq!(args.single::<u32>().unwrap(), 69);
/// ```
- pub fn full(&self) -> &str {
- &self.message
+ pub fn skip(&mut self) -> Option<String> {
+ if self.is_empty() {
+ return None;
+ }
+
+ self.single::<String>().ok()
}
- /// Gets the original message passed to the command,
- /// but without quotes (if both starting and ending quotes are present, otherwise returns as is).
+ /// Like [`skip`], but do it multiple times.
///
/// # Examples
///
/// ```rust
/// use serenity::framework::standard::Args;
///
- /// let args = Args::new("\"42 69\"", &[" ".to_string()]);
+ /// let mut args = Args::new("42 69 88 99", &[" ".to_string()]);
///
- /// assert_eq!(args.full_quoted(), "42 69");
+ /// args.skip_for(3);
+ /// assert_eq!(args.remaining(), 1);
+ /// assert_eq!(args.single::<u32>().unwrap(), 99);
/// ```
///
+ /// [`skip`]: #method.skip
+ pub fn skip_for(&mut self, i: u32) -> Option<Vec<String>> {
+ if self.is_empty() {
+ return None;
+ }
+
+ let mut vec = Vec::with_capacity(i as usize);
+
+ for _ in 0..i {
+ vec.push(self.skip()?);
+ }
+
+ Some(vec)
+ }
+
+
+ /// Provides an iterator that will spew arguments until the end of the message.
+ ///
+ /// # Examples
+ ///
/// ```rust
/// use serenity::framework::standard::Args;
///
- /// let args = Args::new("\"42 69", &[" ".to_string()]);
+ /// let mut args = Args::new("3 4", &[" ".to_string()]);
///
- /// assert_eq!(args.full_quoted(), "\"42 69");
+ /// assert_eq!(*args.iter::<u32>().map(|num| num.unwrap().pow(2)).collect::<Vec<_>>(), [9, 16]);
+ /// assert!(args.is_empty());
/// ```
+ pub fn iter<T: FromStr>(&mut self) -> Iter<T>
+ where T::Err: StdError {
+ Iter::new(self)
+ }
+
+ /// Parses all of the remaining arguments and returns them in a `Vec` (Sugar for `args.iter().collect::<Vec<_>>()`).
+ ///
+ /// # Examples
///
/// ```rust
/// use serenity::framework::standard::Args;
///
- /// let args = Args::new("42 69\"", &[" ".to_string()]);
+ /// let args = Args::new("42 69", &[" ".to_string()]);
///
- /// assert_eq!(args.full_quoted(), "42 69\"");
+ /// assert_eq!(*args.multiple::<u32>().unwrap(), [42, 69]);
/// ```
- pub fn full_quoted(&self) -> &str {
- let s = &self.message;
-
- if !s.starts_with('"') {
- return s;
- }
-
- let end = s.rfind('"');
- if end.is_none() {
- return s;
- }
-
- let end = end.unwrap();
-
- // If it got the quote at the start, then there's no closing quote.
- if end == 0 {
- return s;
+ pub fn multiple<T: FromStr>(mut self) -> Result<Vec<T>, T::Err>
+ where T::Err: StdError {
+ if self.is_empty() {
+ return Err(Error::Eos);
}
- &s[1..end]
+ self.iter::<T>().collect()
}
- /// Returns the message starting from the token in the current argument offset; the "rest" of the message.
+ /// Like [`single`], but accounts quotes.
///
/// # Examples
///
/// ```rust
/// use serenity::framework::standard::Args;
///
- /// let mut args = Args::new("42 69 91", &[" ".to_string()]);
- ///
- /// assert_eq!(args.rest(), "42 69 91");
+ /// let mut args = Args::new(r#""42 69""#, &[" ".to_string()]);
///
- /// args.skip();
+ /// assert_eq!(args.single_quoted::<String>().unwrap(), "42 69");
+ /// assert!(args.is_empty());
+ /// ```
///
- /// assert_eq!(args.rest(), "69 91");
+ /// [`single`]: #method.single
+ pub fn single_quoted<T: FromStr>(&mut self) -> Result<T, T::Err>
+ where T::Err: StdError {
+ if self.is_empty() {
+ return Err(Error::Eos);
+ }
+
+ let current = &self.args[self.offset];
+
+ // Discard quotations if present
+ let lit = quotes_extract(current);
+
+ let parsed = T::from_str(&lit)?;
+ self.offset += 1;
+ Ok(parsed)
+ }
+
+ /// Like [`single_quoted`], but doesn't advance.
///
- /// args.skip();
+ /// # Examples
///
- /// assert_eq!(args.rest(), "91");
+ /// ```rust
+ /// use serenity::framework::standard::Args;
///
- /// args.skip();
+ /// let mut args = Args::new(r#""42 69""#, &[" ".to_string()]);
///
- /// assert_eq!(args.rest(), "");
+ /// assert_eq!(args.single_quoted_n::<String>().unwrap(), "42 69");
+ /// assert_eq!(args.rest(), r#""42 69""#);
/// ```
- pub fn rest(&self) -> &str {
+ ///
+ /// [`single_quoted`]: #method.single_quoted
+ pub fn single_quoted_n<T: FromStr>(&self) -> Result<T, T::Err>
+ where T::Err: StdError {
if self.is_empty() {
- return "";
+ return Err(Error::Eos);
}
- let args = &self.args[self.offset..];
+ let current = &self.args[self.offset];
- if let Some(token) = args.get(0) {
- &self.message[token.pos..]
- } else {
- &self.message[..]
- }
+ let lit = quotes_extract(current);
+
+ Ok(T::from_str(&lit)?)
}
- /// The full amount of recognised arguments.
- ///
- /// **Note**:
- /// This never changes. Except for [`find`], which upon success, subtracts the length by 1. (e.g len of `3` becomes `2`)
+ /// Like [`iter`], but accounts quotes.
///
/// # Examples
///
/// ```rust
/// use serenity::framework::standard::Args;
///
- /// let mut args = Args::new("42 69", &[" ".to_string()]);
+ /// let mut args = Args::new(r#""2" "5""#, &[" ".to_string()]);
///
- /// assert_eq!(args.len(), 2); // `2` because `["42", "69"]`
+ /// assert_eq!(*args.iter_quoted::<u32>().map(|n| n.unwrap().pow(2)).collect::<Vec<_>>(), [4, 25]);
+ /// assert!(args.is_empty());
/// ```
///
- /// [`find`]: #method.find
- pub fn len(&self) -> usize {
- self.args.len()
+ /// [`iter`]: #method.iter
+ pub fn iter_quoted<T: FromStr>(&mut self) -> IterQuoted<T>
+ where T::Err: StdError {
+ IterQuoted::new(self)
}
- /// Amount of arguments still available.
+ /// Like [`multiple`], but accounts quotes.
///
/// # Examples
///
/// ```rust
/// use serenity::framework::standard::Args;
///
- /// let mut args = Args::new("42 69", &[" ".to_string()]);
- ///
- /// assert_eq!(args.remaining(), 2);
- ///
- /// args.skip();
+ /// let mut args = Args::new(r#""42" "69""#, &[" ".to_string()]);
///
- /// assert_eq!(args.remaining(), 1);
+ /// assert_eq!(*args.multiple_quoted::<u32>().unwrap(), [42, 69]);
/// ```
- pub fn remaining(&self) -> usize {
+ ///
+ /// [`multiple`]: #method.multiple
+ pub fn multiple_quoted<T: FromStr>(mut self) -> Result<Vec<T>, T::Err>
+ where T::Err: StdError {
if self.is_empty() {
- return 0;
+ return Err(Error::Eos);
}
- self.len() - self.offset
+ self.iter_quoted::<T>().collect()
}
- /// Returns true if there are no arguments left.
+ /// Returns the first argument that can be parsed and removes it from the message. The suitable argument
+ /// can be in an arbitrary position in the message. Likewise, takes quotes into account.
+ ///
+ /// **Note**:
+ /// Unlike how other methods on this struct work,
+ /// this function permantently removes the argument if it was **found** and was **succesfully** parsed.
+ /// Hence, use this with caution.
///
/// # Examples
///
/// ```rust
/// use serenity::framework::standard::Args;
///
- /// let mut args = Args::new("", &[" ".to_string()]);
+ /// let mut args = Args::new("c42 69", &[" ".to_string()]);
///
- /// assert!(args.is_empty()); // `true` because passed message is empty thus no arguments.
+ /// assert_eq!(args.find::<u32>().unwrap(), 69);
+ /// assert_eq!(args.single::<String>().unwrap(), "c42");
+ /// assert!(args.is_empty());
/// ```
- pub fn is_empty(&self) -> bool {
- self.offset >= self.args.len()
+ pub fn find<T: FromStr>(&mut self) -> Result<T, T::Err>
+ where T::Err: StdError {
+ if self.is_empty() {
+ return Err(Error::Eos);
+ }
+
+ let pos = match self.args.iter().map(|t| quotes_extract(t)).position(|s| s.parse::<T>().is_ok()) {
+ Some(p) => p,
+ None => return Err(Error::Eos),
+ };
+
+ let parsed = T::from_str(quotes_extract(&self.args[pos]))?;
+ self.args.remove(pos);
+ self.rewind();
+
+ Ok(parsed)
}
- /// Go one step behind.
+ /// Like [`find`], but does not remove it.
///
/// # Examples
///
/// ```rust
/// use serenity::framework::standard::Args;
///
- /// let mut args = Args::new("42 69", &[" ".to_string()]);
- ///
- /// assert_eq!(args.single::<u32>().unwrap(), 42);
+ /// let mut args = Args::new("c42 69", &[" ".to_string()]);
///
- /// // By this point, we can only parse 69 now.
- /// // However, with the help of `rewind`, we can mess with 42 again.
- /// args.rewind();
+ /// assert_eq!(args.find_n::<u32>().unwrap(), 69);
///
- /// assert_eq!(args.single::<u32>().unwrap() * 2, 84);
+ /// // The `69` is still here, so let's parse it again.
+ /// assert_eq!(args.single::<String>().unwrap(), "c42");
+ /// assert_eq!(args.single::<u32>().unwrap(), 69);
+ /// assert!(args.is_empty());
/// ```
- #[inline]
- pub fn rewind(&mut self) {
- if self.offset == 0 {
- return;
+ ///
+ /// [`find`]: #method.find
+ pub fn find_n<T: FromStr>(&mut self) -> Result<T, T::Err>
+ where T::Err: StdError {
+ if self.is_empty() {
+ return Err(Error::Eos);
}
- self.offset -= 1;
+ let pos = match self.args.iter().map(|t| quotes_extract(t)).position(|s| s.parse::<T>().is_ok()) {
+ Some(p) => p,
+ None => return Err(Error::Eos),
+ };
+
+ Ok(T::from_str(quotes_extract(&self.args[pos]))?)
}
- /// Go back to the starting point.
+ /// Gets original message passed to the command.
///
/// # Examples
///
/// ```rust
/// use serenity::framework::standard::Args;
///
- /// let mut args = Args::new("42 69 95", &[" ".to_string()]);
- ///
- /// // Let's parse 'em numbers!
- /// assert_eq!(args.single::<u32>().unwrap(), 42);
- /// assert_eq!(args.single::<u32>().unwrap(), 69);
- /// assert_eq!(args.single::<u32>().unwrap(), 95);
- ///
- /// // Oh, no! I actually wanted to multiply all of them by 2!
- /// // I don't want to call `rewind` 3 times manually....
- /// // Wait, I could just go entirely back!
- /// args.restore();
+ /// let args = Args::new("42 69", &[" ".to_string()]);
///
- /// assert_eq!(args.single::<u32>().unwrap() * 2, 84);
- /// assert_eq!(args.single::<u32>().unwrap() * 2, 138);
- /// assert_eq!(args.single::<u32>().unwrap() * 2, 190);
+ /// assert_eq!(args.full(), "42 69");
/// ```
- ///
- #[inline]
- pub fn restore(&mut self) {
- self.offset = 0;
+ pub fn full(&self) -> &str {
+ &self.message
}
- /// Like [`len`], but accounts quotes.
+ /// Gets the original message passed to the command,
+ /// but without quotes (if both starting and ending quotes are present, otherwise returns as is).
///
/// # Examples
///
/// ```rust
/// use serenity::framework::standard::Args;
///
- /// let mut args = Args::new(r#""42" "69""#, &[" ".to_string()]);
+ /// let args = Args::new("\"42 69\"", &[" ".to_string()]);
///
- /// assert_eq!(args.len_quoted(), 2); // `2` because `["42", "69"]`
+ /// assert_eq!(args.full_quoted(), "42 69");
/// ```
- #[deprecated(since = "0.5.3", note = "Its task was merged with `len`, please use it instead.")]
- pub fn len_quoted(&mut self) -> usize {
- self.len()
- }
-
- /// "Skip" the argument (Sugar for `args.single::<String>().ok()`)
- ///
- /// # Examples
///
/// ```rust
/// use serenity::framework::standard::Args;
///
- /// let mut args = Args::new("42 69", &[" ".to_string()]);
+ /// let args = Args::new("\"42 69", &[" ".to_string()]);
///
- /// args.skip();
- /// assert_eq!(args.single::<u32>().unwrap(), 69);
+ /// assert_eq!(args.full_quoted(), "\"42 69");
/// ```
- pub fn skip(&mut self) -> Option<String> {
- if self.is_empty() {
- return None;
- }
-
- self.single::<String>().ok()
- }
-
- /// Like [`skip`], but do it multiple times.
- ///
- /// # Examples
///
/// ```rust
/// use serenity::framework::standard::Args;
///
- /// let mut args = Args::new("42 69 88 99", &[" ".to_string()]);
+ /// let args = Args::new("42 69\"", &[" ".to_string()]);
///
- /// args.skip_for(3);
- /// assert_eq!(args.remaining(), 1);
- /// assert_eq!(args.single::<u32>().unwrap(), 99);
+ /// assert_eq!(args.full_quoted(), "42 69\"");
/// ```
- ///
- /// [`skip`]: #method.skip
- pub fn skip_for(&mut self, i: u32) -> Option<Vec<String>> {
- if self.is_empty() {
- return None;
+ pub fn full_quoted(&self) -> &str {
+ let s = &self.message;
+
+ if !s.starts_with('"') {
+ return s;
}
- let mut vec = Vec::with_capacity(i as usize);
+ let end = s.rfind('"');
+ if end.is_none() {
+ return s;
+ }
- for _ in 0..i {
- vec.push(self.skip()?);
+ let end = end.unwrap();
+
+ // If it got the quote at the start, then there's no closing quote.
+ if end == 0 {
+ return s;
}
- Some(vec)
+ &s[1..end]
}
- /// Like [`single`], but accounts quotes.
+ /// Returns the message starting from the token in the current argument offset; the "rest" of the message.
///
/// # Examples
///
/// ```rust
/// use serenity::framework::standard::Args;
///
- /// let mut args = Args::new(r#""42 69""#, &[" ".to_string()]);
+ /// let mut args = Args::new("42 69 91", &[" ".to_string()]);
///
- /// assert_eq!(args.single_quoted::<String>().unwrap(), "42 69");
- /// assert!(args.is_empty());
- /// ```
+ /// assert_eq!(args.rest(), "42 69 91");
///
- /// [`single`]: #method.single
- pub fn single_quoted<T: FromStr>(&mut self) -> Result<T, T::Err>
- where T::Err: StdError {
- if self.is_empty() {
- return Err(Error::Eos);
- }
-
- let current = &self.args[self.offset];
-
- // Discard quotations if present
- let lit = quotes_extract(current);
-
- let parsed = T::from_str(&lit)?;
- self.offset += 1;
- Ok(parsed)
- }
-
- /// Like [`single_quoted`], but doesn't advance.
+ /// args.skip();
///
- /// # Examples
+ /// assert_eq!(args.rest(), "69 91");
///
- /// ```rust
- /// use serenity::framework::standard::Args;
+ /// args.skip();
///
- /// let mut args = Args::new(r#""42 69""#, &[" ".to_string()]);
+ /// assert_eq!(args.rest(), "91");
///
- /// assert_eq!(args.single_quoted_n::<String>().unwrap(), "42 69");
- /// assert_eq!(args.full(), r#""42 69""#);
- /// ```
+ /// args.skip();
///
- /// [`single_quoted`]: #method.single_quoted
- pub fn single_quoted_n<T: FromStr>(&self) -> Result<T, T::Err>
- where T::Err: StdError {
+ /// assert_eq!(args.rest(), "");
+ /// ```
+ pub fn rest(&self) -> &str {
if self.is_empty() {
- return Err(Error::Eos);
+ return "";
}
- let current = &self.args[self.offset];
-
- let lit = quotes_extract(current);
+ let args = &self.args[self.offset..];
- Ok(T::from_str(&lit)?)
+ if let Some(token) = args.get(0) {
+ &self.message[token.pos..]
+ } else {
+ &self.message[..]
+ }
}
- /// Like [`multiple`], but accounts quotes.
+ /// The full amount of recognised arguments.
+ ///
+ /// **Note**:
+ /// This never changes. Except for [`find`], which upon success, subtracts the length by 1. (e.g len of `3` becomes `2`)
///
/// # Examples
///
/// ```rust
/// use serenity::framework::standard::Args;
///
- /// let mut args = Args::new(r#""42" "69""#, &[" ".to_string()]);
+ /// let mut args = Args::new("42 69", &[" ".to_string()]);
///
- /// assert_eq!(*args.multiple_quoted::<u32>().unwrap(), [42, 69]);
+ /// assert_eq!(args.len(), 2); // `2` because `["42", "69"]`
/// ```
///
- /// [`multiple`]: #method.multiple
- pub fn multiple_quoted<T: FromStr>(mut self) -> Result<Vec<T>, T::Err>
- where T::Err: StdError {
- if self.is_empty() {
- return Err(Error::Eos);
- }
-
- self.iter_quoted::<T>().collect()
+ /// [`find`]: #method.find
+ pub fn len(&self) -> usize {
+ self.args.len()
}
- /// Like [`iter`], but accounts quotes.
+ /// Returns true if there are no arguments left.
///
/// # Examples
///
/// ```rust
/// use serenity::framework::standard::Args;
///
- /// let mut args = Args::new(r#""2" "5""#, &[" ".to_string()]);
+ /// let mut args = Args::new("", &[" ".to_string()]);
///
- /// assert_eq!(*args.iter_quoted::<u32>().map(|n| n.unwrap().pow(2)).collect::<Vec<_>>(), [4, 25]);
- /// assert!(args.is_empty());
+ /// assert!(args.is_empty()); // `true` because passed message is empty thus no arguments.
/// ```
- ///
- /// [`iter`]: #method.iter
- pub fn iter_quoted<T: FromStr>(&mut self) -> IterQuoted<T>
- where T::Err: StdError {
- IterQuoted::new(self)
+ pub fn is_empty(&self) -> bool {
+ self.offset >= self.args.len()
}
- /// Parses all of the remaining arguments and returns them in a `Vec` (Sugar for `args.iter().collect::<Vec<_>>()`).
+ /// Amount of arguments still available.
///
/// # Examples
///
/// ```rust
/// use serenity::framework::standard::Args;
///
- /// let args = Args::new("42 69", &[" ".to_string()]);
+ /// let mut args = Args::new("42 69", &[" ".to_string()]);
///
- /// assert_eq!(*args.multiple::<u32>().unwrap(), [42, 69]);
+ /// assert_eq!(args.remaining(), 2);
+ ///
+ /// args.skip();
+ ///
+ /// assert_eq!(args.remaining(), 1);
/// ```
- pub fn multiple<T: FromStr>(mut self) -> Result<Vec<T>, T::Err>
- where T::Err: StdError {
+ pub fn remaining(&self) -> usize {
if self.is_empty() {
- return Err(Error::Eos);
+ return 0;
}
- self.iter::<T>().collect()
+ self.len() - self.offset
}
- /// Provides an iterator that will spew arguments until the end of the message.
+ /// Go one step behind.
///
/// # Examples
///
/// ```rust
/// use serenity::framework::standard::Args;
///
- /// let mut args = Args::new("3 4", &[" ".to_string()]);
+ /// let mut args = Args::new("42 69", &[" ".to_string()]);
///
- /// assert_eq!(*args.iter::<u32>().map(|num| num.unwrap().pow(2)).collect::<Vec<_>>(), [9, 16]);
- /// assert!(args.is_empty());
+ /// assert_eq!(args.single::<u32>().unwrap(), 42);
+ ///
+ /// // By this point, we can only parse 69 now.
+ /// // However, with the help of `rewind`, we can mess with 42 again.
+ /// args.rewind();
+ ///
+ /// assert_eq!(args.single::<u32>().unwrap() * 2, 84);
/// ```
- pub fn iter<T: FromStr>(&mut self) -> Iter<T>
- where T::Err: StdError {
- Iter::new(self)
+ #[inline]
+ pub fn rewind(&mut self) {
+ if self.offset == 0 {
+ return;
+ }
+
+ self.offset -= 1;
}
- /// Returns the first argument that can be parsed and removes it from the message. The suitable argument
- /// can be in an arbitrary position in the message. Likewise, takes quotes into account.
- ///
- /// **Note**:
- /// Unlike how other methods on this struct work,
- /// this function permantently removes the argument if it was **found** and was **succesfully** parsed.
- /// Hence, use this with caution.
+ /// Go back to the starting point.
///
/// # Examples
///
/// ```rust
/// use serenity::framework::standard::Args;
///
- /// let mut args = Args::new("c42 69", &[" ".to_string()]);
+ /// let mut args = Args::new("42 69 95", &[" ".to_string()]);
///
- /// assert_eq!(args.find::<u32>().unwrap(), 69);
- /// assert_eq!(args.single::<String>().unwrap(), "c42");
- /// assert!(args.is_empty());
+ /// // Let's parse 'em numbers!
+ /// assert_eq!(args.single::<u32>().unwrap(), 42);
+ /// assert_eq!(args.single::<u32>().unwrap(), 69);
+ /// assert_eq!(args.single::<u32>().unwrap(), 95);
+ ///
+ /// // Oh, no! I actually wanted to multiply all of them by 2!
+ /// // I don't want to call `rewind` 3 times manually....
+ /// // Wait, I could just go entirely back!
+ /// args.restore();
+ ///
+ /// assert_eq!(args.single::<u32>().unwrap() * 2, 84);
+ /// assert_eq!(args.single::<u32>().unwrap() * 2, 138);
+ /// assert_eq!(args.single::<u32>().unwrap() * 2, 190);
/// ```
- pub fn find<T: FromStr>(&mut self) -> Result<T, T::Err>
- where T::Err: StdError {
- if self.is_empty() {
- return Err(Error::Eos);
- }
-
- let pos = match self.args.iter().map(|t| quotes_extract(t)).position(|s| s.parse::<T>().is_ok()) {
- Some(p) => p,
- None => return Err(Error::Eos),
- };
-
- let parsed = T::from_str(quotes_extract(&self.args[pos]))?;
- self.args.remove(pos);
- self.rewind();
-
- Ok(parsed)
+ ///
+ #[inline]
+ pub fn restore(&mut self) {
+ self.offset = 0;
}
- /// Like [`find`], but does not remove it.
+ /// Like [`len`], but accounts quotes.
///
/// # Examples
///
/// ```rust
/// use serenity::framework::standard::Args;
///
- /// let mut args = Args::new("c42 69", &[" ".to_string()]);
- ///
- /// assert_eq!(args.find_n::<u32>().unwrap(), 69);
+ /// let mut args = Args::new(r#""42" "69""#, &[" ".to_string()]);
///
- /// // The `69` is still here, so let's parse it again.
- /// assert_eq!(args.single::<String>().unwrap(), "c42");
- /// assert_eq!(args.single::<u32>().unwrap(), 69);
- /// assert!(args.is_empty());
+ /// assert_eq!(args.len_quoted(), 2); // `2` because `["42", "69"]`
/// ```
- ///
- /// [`find`]: #method.find
- pub fn find_n<T: FromStr>(&mut self) -> Result<T, T::Err>
- where T::Err: StdError {
- if self.is_empty() {
- return Err(Error::Eos);
- }
-
- let pos = match self.args.iter().map(|t| quotes_extract(t)).position(|s| s.parse::<T>().is_ok()) {
- Some(p) => p,
- None => return Err(Error::Eos),
- };
-
- Ok(T::from_str(quotes_extract(&self.args[pos]))?)
+ #[deprecated(since = "0.5.3", note = "Its task was merged with `len`, please use it instead.")]
+ pub fn len_quoted(&mut self) -> usize {
+ self.len()
}
}