mirror of
https://github.com/clap-rs/clap
synced 2024-11-10 14:54:15 +00:00
commit
3224e2e1cd
14 changed files with 107 additions and 31 deletions
|
@ -21,7 +21,6 @@ appveyor = { repository = "kbknapp/clap-rs" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bitflags = "0.9"
|
bitflags = "0.9"
|
||||||
vec_map = "0.8"
|
|
||||||
unicode-width = "0.1.4"
|
unicode-width = "0.1.4"
|
||||||
textwrap = "0.8.0"
|
textwrap = "0.8.0"
|
||||||
strsim = { version = "0.6.0", optional = true }
|
strsim = { version = "0.6.0", optional = true }
|
||||||
|
@ -30,6 +29,7 @@ term_size = { version = "0.3.0", optional = true }
|
||||||
yaml-rust = { version = "0.3.5", optional = true }
|
yaml-rust = { version = "0.3.5", optional = true }
|
||||||
clippy = { version = "~0.0.131", optional = true }
|
clippy = { version = "~0.0.131", optional = true }
|
||||||
atty = { version = "0.2.2", optional = true }
|
atty = { version = "0.2.2", optional = true }
|
||||||
|
vec_map = { version = "0.8", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
regex = "0.2"
|
regex = "0.2"
|
||||||
|
@ -37,7 +37,7 @@ lazy_static = "0.2"
|
||||||
version-sync = "0.3"
|
version-sync = "0.3"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["suggestions", "color", "wrap_help"]
|
default = ["suggestions", "color", "wrap_help", "vec_map"]
|
||||||
suggestions = ["strsim"]
|
suggestions = ["strsim"]
|
||||||
color = ["ansi_term", "atty"]
|
color = ["ansi_term", "atty"]
|
||||||
wrap_help = ["term_size"]
|
wrap_help = ["term_size"]
|
||||||
|
|
|
@ -490,6 +490,7 @@ Then run `cargo build` or `cargo update && cargo build` for your project.
|
||||||
* **"suggestions"**: Turns on the `Did you mean '--myoption'?` feature for when users make typos. (builds dependency `strsim`)
|
* **"suggestions"**: Turns on the `Did you mean '--myoption'?` feature for when users make typos. (builds dependency `strsim`)
|
||||||
* **"color"**: Turns on colored error messages. This feature only works on non-Windows OSs. (builds dependency `ansi-term`)
|
* **"color"**: Turns on colored error messages. This feature only works on non-Windows OSs. (builds dependency `ansi-term`)
|
||||||
* **"wrap_help"**: Wraps the help at the actual terminal width when available, instead of 120 characters. (builds dependency `term_size`)
|
* **"wrap_help"**: Wraps the help at the actual terminal width when available, instead of 120 characters. (builds dependency `term_size`)
|
||||||
|
* **"vec_map"**: Use [`VecMap`](https://crates.io/crates/vec_map) internally instead of a [`BTreeMap`](https://doc.rust-lang.org/stable/std/collections/struct.BTreeMap.html). This feature provides a _slight_ performance improvement. (builds dependency `vec_map`)
|
||||||
|
|
||||||
To disable these, add this to your `Cargo.toml`:
|
To disable these, add this to your `Cargo.toml`:
|
||||||
|
|
||||||
|
|
|
@ -12,13 +12,13 @@ use args::{AnyArg, ArgSettings, DispOrder};
|
||||||
use errors::{Error, Result as ClapResult};
|
use errors::{Error, Result as ClapResult};
|
||||||
use fmt::{Format, Colorizer, ColorizerOption};
|
use fmt::{Format, Colorizer, ColorizerOption};
|
||||||
use app::usage;
|
use app::usage;
|
||||||
|
use map::VecMap;
|
||||||
|
|
||||||
// Third Party
|
// Third Party
|
||||||
use unicode_width::UnicodeWidthStr;
|
use unicode_width::UnicodeWidthStr;
|
||||||
#[cfg(feature = "wrap_help")]
|
#[cfg(feature = "wrap_help")]
|
||||||
use term_size;
|
use term_size;
|
||||||
use textwrap;
|
use textwrap;
|
||||||
use vec_map::VecMap;
|
|
||||||
|
|
||||||
#[cfg(not(feature = "wrap_help"))]
|
#[cfg(not(feature = "wrap_help"))]
|
||||||
mod term_size {
|
mod term_size {
|
||||||
|
|
|
@ -18,7 +18,6 @@ use std::rc::Rc;
|
||||||
use std::result::Result as StdResult;
|
use std::result::Result as StdResult;
|
||||||
|
|
||||||
// Third Party
|
// Third Party
|
||||||
use vec_map::{self, VecMap};
|
|
||||||
#[cfg(feature = "yaml")]
|
#[cfg(feature = "yaml")]
|
||||||
use yaml_rust::Yaml;
|
use yaml_rust::Yaml;
|
||||||
|
|
||||||
|
@ -29,6 +28,7 @@ use args::{AnyArg, Arg, ArgGroup, ArgMatcher, ArgMatches, ArgSettings};
|
||||||
use errors::Result as ClapResult;
|
use errors::Result as ClapResult;
|
||||||
pub use self::settings::AppSettings;
|
pub use self::settings::AppSettings;
|
||||||
use completions::Shell;
|
use completions::Shell;
|
||||||
|
use map::{self, VecMap};
|
||||||
|
|
||||||
/// Used to create a representation of a command line program and all possible command line
|
/// Used to create a representation of a command line program and all possible command line
|
||||||
/// arguments. Application settings are set using the "builder pattern" with the
|
/// arguments. Application settings are set using the "builder pattern" with the
|
||||||
|
@ -1793,7 +1793,7 @@ impl<'n, 'e> AnyArg<'n, 'e> for App<'n, 'e> {
|
||||||
fn help(&self) -> Option<&'e str> { self.p.meta.about }
|
fn help(&self) -> Option<&'e str> { self.p.meta.about }
|
||||||
fn long_help(&self) -> Option<&'e str> { self.p.meta.long_about }
|
fn long_help(&self) -> Option<&'e str> { self.p.meta.long_about }
|
||||||
fn default_val(&self) -> Option<&'e OsStr> { None }
|
fn default_val(&self) -> Option<&'e OsStr> { None }
|
||||||
fn default_vals_ifs(&self) -> Option<vec_map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> {
|
fn default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
fn longest_filter(&self) -> bool { true }
|
fn longest_filter(&self) -> bool { true }
|
||||||
|
|
|
@ -9,9 +9,6 @@ use std::path::PathBuf;
|
||||||
use std::slice::Iter;
|
use std::slice::Iter;
|
||||||
use std::iter::Peekable;
|
use std::iter::Peekable;
|
||||||
|
|
||||||
// Third Party
|
|
||||||
use vec_map::{self, VecMap};
|
|
||||||
|
|
||||||
// Internal
|
// Internal
|
||||||
use INTERNAL_ERROR_MSG;
|
use INTERNAL_ERROR_MSG;
|
||||||
use INVALID_UTF8;
|
use INVALID_UTF8;
|
||||||
|
@ -32,6 +29,7 @@ use suggestions;
|
||||||
use app::settings::AppSettings as AS;
|
use app::settings::AppSettings as AS;
|
||||||
use app::validator::Validator;
|
use app::validator::Validator;
|
||||||
use app::usage;
|
use app::usage;
|
||||||
|
use map::{self, VecMap};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
@ -1795,7 +1793,7 @@ impl<'a, 'b> Parser<'a, 'b>
|
||||||
|
|
||||||
pub fn opts(&self) -> Iter<OptBuilder<'a, 'b>> { self.opts.iter() }
|
pub fn opts(&self) -> Iter<OptBuilder<'a, 'b>> { self.opts.iter() }
|
||||||
|
|
||||||
pub fn positionals(&self) -> vec_map::Values<PosBuilder<'a, 'b>> { self.positionals.values() }
|
pub fn positionals(&self) -> map::Values<PosBuilder<'a, 'b>> { self.positionals.values() }
|
||||||
|
|
||||||
pub fn subcommands(&self) -> Iter<App> { self.subcommands.iter() }
|
pub fn subcommands(&self) -> Iter<App> { self.subcommands.iter() }
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,9 @@ use std::rc::Rc;
|
||||||
use std::fmt as std_fmt;
|
use std::fmt as std_fmt;
|
||||||
use std::ffi::{OsStr, OsString};
|
use std::ffi::{OsStr, OsString};
|
||||||
|
|
||||||
// Third Party
|
|
||||||
use vec_map::{self, VecMap};
|
|
||||||
|
|
||||||
// Internal
|
// Internal
|
||||||
use args::settings::ArgSettings;
|
use args::settings::ArgSettings;
|
||||||
|
use map::{self, VecMap};
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub trait AnyArg<'n, 'e>: std_fmt::Display {
|
pub trait AnyArg<'n, 'e>: std_fmt::Display {
|
||||||
|
@ -34,7 +32,7 @@ pub trait AnyArg<'n, 'e>: std_fmt::Display {
|
||||||
fn help(&self) -> Option<&'e str>;
|
fn help(&self) -> Option<&'e str>;
|
||||||
fn long_help(&self) -> Option<&'e str>;
|
fn long_help(&self) -> Option<&'e str>;
|
||||||
fn default_val(&self) -> Option<&'e OsStr>;
|
fn default_val(&self) -> Option<&'e OsStr>;
|
||||||
fn default_vals_ifs(&self) -> Option<vec_map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>>;
|
fn default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>>;
|
||||||
fn longest_filter(&self) -> bool;
|
fn longest_filter(&self) -> bool;
|
||||||
fn val_terminator(&self) -> Option<&'e str>;
|
fn val_terminator(&self) -> Option<&'e str>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ use std::os::unix::ffi::OsStrExt;
|
||||||
|
|
||||||
#[cfg(feature = "yaml")]
|
#[cfg(feature = "yaml")]
|
||||||
use yaml_rust::Yaml;
|
use yaml_rust::Yaml;
|
||||||
use vec_map::VecMap;
|
use map::VecMap;
|
||||||
|
|
||||||
use usage_parser::UsageParser;
|
use usage_parser::UsageParser;
|
||||||
use args::settings::ArgSettings;
|
use args::settings::ArgSettings;
|
||||||
|
|
|
@ -6,12 +6,10 @@ use std::result::Result as StdResult;
|
||||||
use std::ffi::{OsStr, OsString};
|
use std::ffi::{OsStr, OsString};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
// Third Party
|
|
||||||
use vec_map::{self, VecMap};
|
|
||||||
|
|
||||||
// Internal
|
// Internal
|
||||||
use Arg;
|
use Arg;
|
||||||
use args::{ArgSettings, Base, Switched, AnyArg, DispOrder};
|
use args::{ArgSettings, Base, Switched, AnyArg, DispOrder};
|
||||||
|
use map::{self, VecMap};
|
||||||
|
|
||||||
#[derive(Default, Clone, Debug)]
|
#[derive(Default, Clone, Debug)]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
@ -82,7 +80,7 @@ impl<'n, 'e> AnyArg<'n, 'e> for FlagBuilder<'n, 'e> {
|
||||||
fn long_help(&self) -> Option<&'e str> { self.b.long_help }
|
fn long_help(&self) -> Option<&'e str> { self.b.long_help }
|
||||||
fn val_terminator(&self) -> Option<&'e str> { None }
|
fn val_terminator(&self) -> Option<&'e str> { None }
|
||||||
fn default_val(&self) -> Option<&'e OsStr> { None }
|
fn default_val(&self) -> Option<&'e OsStr> { None }
|
||||||
fn default_vals_ifs(&self) -> Option<vec_map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> {
|
fn default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
fn longest_filter(&self) -> bool { self.s.long.is_some() }
|
fn longest_filter(&self) -> bool { self.s.long.is_some() }
|
||||||
|
|
|
@ -5,11 +5,9 @@ use std::result::Result as StdResult;
|
||||||
use std::ffi::{OsStr, OsString};
|
use std::ffi::{OsStr, OsString};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
// Third Party
|
|
||||||
use vec_map::{self, VecMap};
|
|
||||||
|
|
||||||
// Internal
|
// Internal
|
||||||
use args::{ArgSettings, AnyArg, Base, Switched, Valued, Arg, DispOrder};
|
use args::{ArgSettings, AnyArg, Base, Switched, Valued, Arg, DispOrder};
|
||||||
|
use map::{self, VecMap};
|
||||||
|
|
||||||
#[allow(missing_debug_implementations)]
|
#[allow(missing_debug_implementations)]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
@ -131,7 +129,7 @@ impl<'n, 'e> AnyArg<'n, 'e> for OptBuilder<'n, 'e> {
|
||||||
fn help(&self) -> Option<&'e str> { self.b.help }
|
fn help(&self) -> Option<&'e str> { self.b.help }
|
||||||
fn long_help(&self) -> Option<&'e str> { self.b.long_help }
|
fn long_help(&self) -> Option<&'e str> { self.b.long_help }
|
||||||
fn default_val(&self) -> Option<&'e OsStr> { self.v.default_val }
|
fn default_val(&self) -> Option<&'e OsStr> { self.v.default_val }
|
||||||
fn default_vals_ifs(&self) -> Option<vec_map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> {
|
fn default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> {
|
||||||
self.v.default_vals_ifs.as_ref().map(|vm| vm.values())
|
self.v.default_vals_ifs.as_ref().map(|vm| vm.values())
|
||||||
}
|
}
|
||||||
fn longest_filter(&self) -> bool { true }
|
fn longest_filter(&self) -> bool { true }
|
||||||
|
@ -165,7 +163,7 @@ impl<'n, 'e> PartialEq for OptBuilder<'n, 'e> {
|
||||||
mod test {
|
mod test {
|
||||||
use args::settings::ArgSettings;
|
use args::settings::ArgSettings;
|
||||||
use super::OptBuilder;
|
use super::OptBuilder;
|
||||||
use vec_map::VecMap;
|
use map::VecMap;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn optbuilder_display1() {
|
fn optbuilder_display1() {
|
||||||
|
|
|
@ -6,13 +6,11 @@ use std::result::Result as StdResult;
|
||||||
use std::ffi::{OsStr, OsString};
|
use std::ffi::{OsStr, OsString};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
// Third Party
|
|
||||||
use vec_map::{self, VecMap};
|
|
||||||
|
|
||||||
// Internal
|
// Internal
|
||||||
use Arg;
|
use Arg;
|
||||||
use args::{ArgSettings, Base, Valued, AnyArg, DispOrder};
|
use args::{ArgSettings, Base, Valued, AnyArg, DispOrder};
|
||||||
use INTERNAL_ERROR_MSG;
|
use INTERNAL_ERROR_MSG;
|
||||||
|
use map::{self, VecMap};
|
||||||
|
|
||||||
#[allow(missing_debug_implementations)]
|
#[allow(missing_debug_implementations)]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
@ -141,7 +139,7 @@ impl<'n, 'e> AnyArg<'n, 'e> for PosBuilder<'n, 'e> {
|
||||||
fn takes_value(&self) -> bool { true }
|
fn takes_value(&self) -> bool { true }
|
||||||
fn help(&self) -> Option<&'e str> { self.b.help }
|
fn help(&self) -> Option<&'e str> { self.b.help }
|
||||||
fn long_help(&self) -> Option<&'e str> { self.b.long_help }
|
fn long_help(&self) -> Option<&'e str> { self.b.long_help }
|
||||||
fn default_vals_ifs(&self) -> Option<vec_map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> {
|
fn default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> {
|
||||||
self.v.default_vals_ifs.as_ref().map(|vm| vm.values())
|
self.v.default_vals_ifs.as_ref().map(|vm| vm.values())
|
||||||
}
|
}
|
||||||
fn default_val(&self) -> Option<&'e OsStr> { self.v.default_val }
|
fn default_val(&self) -> Option<&'e OsStr> { self.v.default_val }
|
||||||
|
@ -161,7 +159,7 @@ impl<'n, 'e> PartialEq for PosBuilder<'n, 'e> {
|
||||||
mod test {
|
mod test {
|
||||||
use args::settings::ArgSettings;
|
use args::settings::ArgSettings;
|
||||||
use super::PosBuilder;
|
use super::PosBuilder;
|
||||||
use vec_map::VecMap;
|
use map::VecMap;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn display_mult() {
|
fn display_mult() {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::ffi::{OsStr, OsString};
|
use std::ffi::{OsStr, OsString};
|
||||||
|
|
||||||
use vec_map::VecMap;
|
use map::VecMap;
|
||||||
|
|
||||||
use Arg;
|
use Arg;
|
||||||
|
|
||||||
|
|
|
@ -539,6 +539,7 @@ extern crate yaml_rust;
|
||||||
extern crate unicode_width;
|
extern crate unicode_width;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate bitflags;
|
extern crate bitflags;
|
||||||
|
#[cfg(feature = "vec_map")]
|
||||||
extern crate vec_map;
|
extern crate vec_map;
|
||||||
#[cfg(feature = "wrap_help")]
|
#[cfg(feature = "wrap_help")]
|
||||||
extern crate term_size;
|
extern crate term_size;
|
||||||
|
@ -565,6 +566,7 @@ mod errors;
|
||||||
mod osstringext;
|
mod osstringext;
|
||||||
mod strext;
|
mod strext;
|
||||||
mod completions;
|
mod completions;
|
||||||
|
mod map;
|
||||||
|
|
||||||
const INTERNAL_ERROR_MSG: &'static str = "Fatal internal error. Please consider filing a bug \
|
const INTERNAL_ERROR_MSG: &'static str = "Fatal internal error. Please consider filing a bug \
|
||||||
report at https://github.com/kbknapp/clap-rs/issues";
|
report at https://github.com/kbknapp/clap-rs/issues";
|
||||||
|
|
84
src/map.rs
Normal file
84
src/map.rs
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
#[cfg(feature = "vec_map")]
|
||||||
|
pub use vec_map::{VecMap, Values};
|
||||||
|
|
||||||
|
#[cfg(not(feature = "vec_map"))]
|
||||||
|
pub use self::vec_map::{VecMap, Values};
|
||||||
|
|
||||||
|
#[cfg(not(feature = "vec_map"))]
|
||||||
|
mod vec_map {
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
use std::collections::btree_map;
|
||||||
|
use std::fmt::{self, Debug, Formatter};
|
||||||
|
|
||||||
|
#[derive(Clone, Default, Debug)]
|
||||||
|
pub struct VecMap<V> {
|
||||||
|
inner: BTreeMap<usize, V>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<V> VecMap<V> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
VecMap { inner: Default::default() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.inner.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.inner.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert(&mut self, key: usize, value: V) -> Option<V> {
|
||||||
|
self.inner.insert(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn values(&self) -> Values<V> {
|
||||||
|
self.inner.values()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter(&self) -> Iter<V> {
|
||||||
|
Iter { inner: self.inner.iter() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn contains_key(&self, key: usize) -> bool {
|
||||||
|
self.inner.contains_key(&key)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn entry(&mut self, key: usize) -> Entry<V> {
|
||||||
|
self.inner.entry(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, key: usize) -> Option<&V> {
|
||||||
|
self.inner.get(&key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Values<'a, V> = btree_map::Values<'a, usize, V>;
|
||||||
|
|
||||||
|
pub type Entry<'a, V> = btree_map::Entry<'a, usize, V>;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Iter<'a, V: 'a> {
|
||||||
|
inner: btree_map::Iter<'a, usize, V>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, V: 'a + Debug> Debug for Iter<'a, V> {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
|
f.debug_list().entries(self.inner.clone()).finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, V: 'a> Iterator for Iter<'a, V> {
|
||||||
|
type Item = (usize, &'a V);
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.inner.next().map(|(k, v)| (*k, v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, V: 'a> DoubleEndedIterator for Iter<'a, V> {
|
||||||
|
fn next_back(&mut self) -> Option<Self::Item> {
|
||||||
|
self.inner.next_back().map(|(k, v)| (*k, v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,9 @@
|
||||||
// Third Party
|
|
||||||
use vec_map::VecMap;
|
|
||||||
|
|
||||||
// Internal
|
// Internal
|
||||||
use INTERNAL_ERROR_MSG;
|
use INTERNAL_ERROR_MSG;
|
||||||
use args::Arg;
|
use args::Arg;
|
||||||
use args::settings::ArgSettings;
|
use args::settings::ArgSettings;
|
||||||
|
use map::VecMap;
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
enum UsageToken {
|
enum UsageToken {
|
||||||
|
|
Loading…
Reference in a new issue