nuts_tool_api/plugin/
cli.rs1use clap::{crate_version, ArgAction, Args, Parser, Subcommand, ValueEnum};
26use std::convert::{TryFrom, TryInto};
27use std::ops::Deref;
28use std::str::FromStr;
29
30#[derive(Clone, Debug)]
31pub struct SizeArg<T>(T);
32
33impl<T: TryFrom<u64>> FromStr for SizeArg<T> {
34 type Err = String;
35
36 fn from_str(s: &str) -> Result<Self, String> {
37 let (num_str, factor) = if let Some(s) = s.strip_suffix('k') {
38 (s, 1024)
39 } else if let Some(s) = s.strip_suffix('m') {
40 (s, 1024 * 1024)
41 } else if let Some(s) = s.strip_suffix('g') {
42 (s, 1024 * 1024 * 1024)
43 } else {
44 (s, 1)
45 };
46
47 if let Ok(n) = num_str.parse::<u64>() {
48 if let Ok(n) = TryInto::<T>::try_into(n * factor) {
49 return Ok(Self(n));
50 }
51 }
52
53 Err("must be a number or a number suffixed with 'k', 'm', 'g'".to_string())
54 }
55}
56
57impl<T> Deref for SizeArg<T> {
58 type Target = T;
59
60 fn deref(&self) -> &T {
61 &self.0
62 }
63}
64
65#[derive(Clone, Copy, Debug, ValueEnum)]
66pub enum Format {
67 Text,
68 Bson,
69}
70
71#[derive(Args, Debug)]
72pub struct InfoArgs {
73 #[clap(long, default_value = "text")]
74 pub format: Format,
75}
76
77#[derive(Args, Debug)]
78pub struct OpenArgs {
79 pub name: String,
81}
82
83#[derive(Args, Debug)]
84pub struct CreateArgs<CX: Args> {
85 pub name: String,
87
88 #[clap(flatten)]
89 pub extra: CX,
90}
91
92#[derive(Debug, Subcommand)]
93pub enum PluginCommand<CX: Args> {
94 Info(InfoArgs),
96
97 Open(OpenArgs),
99
100 Create(CreateArgs<CX>),
102}
103
104impl<CX: Args> PluginCommand<CX> {
105 pub fn as_info(&self) -> Option<&InfoArgs> {
106 match self {
107 Self::Info(args) => Some(args),
108 _ => None,
109 }
110 }
111
112 pub fn as_open(&self) -> Option<&OpenArgs> {
113 match self {
114 Self::Open(args) => Some(args),
115 _ => None,
116 }
117 }
118
119 pub fn as_create(&self) -> Option<&CreateArgs<CX>> {
120 match self {
121 Self::Create(args) => Some(args),
122 _ => None,
123 }
124 }
125}
126
127#[derive(Debug, Parser)]
128#[clap(version = crate_version!())]
129pub struct PluginCli<CX: Args> {
130 #[clap(subcommand)]
131 pub command: PluginCommand<CX>,
132
133 #[clap(short, long, action = ArgAction::Count, global = true)]
135 pub verbose: u8,
136}