mirror of
https://git.proxmox.com/git/proxmox
synced 2025-08-13 11:58:05 +00:00
router: hook help/completion/docgen into new cli parser
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
eb5614adf1
commit
420e238126
@ -251,7 +251,7 @@ fn help_command(
|
|||||||
Ok(Value::Null)
|
Ok(Value::Null)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_help_context(def: Option<Arc<CommandLineInterface>>) {
|
pub(crate) fn set_help_context(def: Option<Arc<CommandLineInterface>>) {
|
||||||
HELP_CONTEXT.with(|ctx| {
|
HELP_CONTEXT.with(|ctx| {
|
||||||
*ctx.borrow_mut() = def;
|
*ctx.borrow_mut() = def;
|
||||||
});
|
});
|
||||||
@ -339,7 +339,10 @@ pub fn handle_command(
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare_cli_command<A>(def: &CommandLineInterface, mut args: A) -> (String, Vec<String>)
|
pub(crate) fn prepare_cli_command<A>(
|
||||||
|
def: &CommandLineInterface,
|
||||||
|
mut args: A,
|
||||||
|
) -> (String, Vec<String>)
|
||||||
where
|
where
|
||||||
A: Iterator<Item = String>,
|
A: Iterator<Item = String>,
|
||||||
{
|
{
|
||||||
|
@ -15,10 +15,9 @@
|
|||||||
use std::any::{Any, TypeId};
|
use std::any::{Any, TypeId};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use anyhow::{bail, Error};
|
use anyhow::{bail, format_err, Error};
|
||||||
|
|
||||||
use anyhow::{format_err, Error};
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
@ -335,6 +334,7 @@ impl From<CliCommandMap> for CommandLineInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Options covering an entire hierarchy set of subcommands.
|
/// Options covering an entire hierarchy set of subcommands.
|
||||||
|
#[derive(Clone)]
|
||||||
pub(crate) struct OptionEntry {
|
pub(crate) struct OptionEntry {
|
||||||
schema: &'static Schema,
|
schema: &'static Schema,
|
||||||
parse: fn(env: &mut CliEnvironment, &mut HashMap<String, String>) -> Result<(), Error>,
|
parse: fn(env: &mut CliEnvironment, &mut HashMap<String, String>) -> Result<(), Error>,
|
||||||
@ -398,24 +398,24 @@ impl OptionEntry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CommandLine<'a> {
|
pub struct CommandLine {
|
||||||
interface: &'a CommandLineInterface,
|
interface: Arc<CommandLineInterface>,
|
||||||
async_run: Option<fn(ApiFuture) -> Result<Value, Error>>,
|
async_run: Option<fn(ApiFuture) -> Result<Value, Error>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CommandLineParseState {
|
||||||
prefix: String,
|
prefix: String,
|
||||||
global_option_schemas: HashMap<&'static str, &'static Schema>,
|
global_option_schemas: HashMap<&'static str, &'static Schema>,
|
||||||
global_option_values: HashMap<String, String>,
|
global_option_values: HashMap<String, String>,
|
||||||
global_option_types: HashMap<TypeId, &'a OptionEntry>,
|
global_option_types: HashMap<TypeId, OptionEntry>,
|
||||||
|
async_run: Option<fn(ApiFuture) -> Result<Value, Error>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'cli> CommandLine<'cli> {
|
impl CommandLine {
|
||||||
pub fn new(interface: &'cli CommandLineInterface) -> Self {
|
pub fn new(interface: CommandLineInterface) -> Self {
|
||||||
Self {
|
Self {
|
||||||
interface,
|
interface: Arc::new(interface),
|
||||||
async_run: None,
|
async_run: None,
|
||||||
prefix: String::new(),
|
|
||||||
global_option_schemas: HashMap::new(),
|
|
||||||
global_option_values: HashMap::new(),
|
|
||||||
global_option_types: HashMap::new(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -424,23 +424,29 @@ impl<'cli> CommandLine<'cli> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse<A>(
|
pub fn parse<A>(&self, rpcenv: &mut CliEnvironment, args: A) -> Result<Invocation, Error>
|
||||||
mut self,
|
|
||||||
rpcenv: &mut CliEnvironment,
|
|
||||||
args: A,
|
|
||||||
) -> Result<Invocation<'cli>, Error>
|
|
||||||
where
|
where
|
||||||
A: IntoIterator<Item = String>,
|
A: IntoIterator<Item = String>,
|
||||||
{
|
{
|
||||||
let cli = self.interface;
|
let (prefix, args) = command::prepare_cli_command(&self.interface, args.into_iter());
|
||||||
let mut args = args.into_iter();
|
|
||||||
self.prefix = args
|
|
||||||
.next()
|
|
||||||
.expect("no parameters passed to CommandLine::parse");
|
|
||||||
self.parse_do(cli, rpcenv, args.collect())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_do(
|
let state = CommandLineParseState {
|
||||||
|
prefix,
|
||||||
|
global_option_schemas: HashMap::new(),
|
||||||
|
global_option_values: HashMap::new(),
|
||||||
|
global_option_types: HashMap::new(),
|
||||||
|
async_run: self.async_run,
|
||||||
|
};
|
||||||
|
|
||||||
|
command::set_help_context(Some(Arc::clone(&self.interface)));
|
||||||
|
let out = state.parse_do(&self.interface, rpcenv, args);
|
||||||
|
command::set_help_context(None);
|
||||||
|
out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CommandLineParseState {
|
||||||
|
fn parse_do<'cli>(
|
||||||
self,
|
self,
|
||||||
cli: &'cli CommandLineInterface,
|
cli: &'cli CommandLineInterface,
|
||||||
rpcenv: &mut CliEnvironment,
|
rpcenv: &mut CliEnvironment,
|
||||||
@ -467,7 +473,7 @@ impl<'cli> CommandLine<'cli> {
|
|||||||
Ok(args)
|
Ok(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_nested(
|
fn parse_nested<'cli>(
|
||||||
mut self,
|
mut self,
|
||||||
cli: &'cli CliCommandMap,
|
cli: &'cli CliCommandMap,
|
||||||
rpcenv: &mut CliEnvironment,
|
rpcenv: &mut CliEnvironment,
|
||||||
@ -480,8 +486,11 @@ impl<'cli> CommandLine<'cli> {
|
|||||||
// handle possible "global" parameters for the current level:
|
// handle possible "global" parameters for the current level:
|
||||||
// first add the global args of this level to the known list:
|
// first add the global args of this level to the known list:
|
||||||
for entry in cli.global_options.values() {
|
for entry in cli.global_options.values() {
|
||||||
self.global_option_types
|
self.global_option_types.extend(
|
||||||
.extend(cli.global_options.iter().map(|(id, entry)| (*id, entry)));
|
cli.global_options
|
||||||
|
.iter()
|
||||||
|
.map(|(id, entry)| (*id, entry.clone())),
|
||||||
|
);
|
||||||
for (name, schema) in entry.properties() {
|
for (name, schema) in entry.properties() {
|
||||||
if self.global_option_schemas.insert(name, schema).is_some() {
|
if self.global_option_schemas.insert(name, schema).is_some() {
|
||||||
panic!(
|
panic!(
|
||||||
@ -518,7 +527,7 @@ impl<'cli> CommandLine<'cli> {
|
|||||||
self.parse_do(sub_cmd, rpcenv, args)
|
self.parse_do(sub_cmd, rpcenv, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_simple(
|
fn parse_simple<'cli>(
|
||||||
mut self,
|
mut self,
|
||||||
cli: &'cli CliCommand,
|
cli: &'cli CliCommand,
|
||||||
rpcenv: &mut CliEnvironment,
|
rpcenv: &mut CliEnvironment,
|
||||||
|
Loading…
Reference in New Issue
Block a user