1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
use crate::query_json::execute_json_query;
use crate::query_web::parse_selector_params;
use crate::query_xml::execute_xpath_query;
use nu_engine::documentation::get_flags_section;
use nu_plugin::{EvaluatedCall, LabeledError, Plugin};
use nu_protocol::{PluginSignature, Spanned, Value};
use std::fmt::Write;

#[derive(Default)]
pub struct Query;

impl Query {
    pub fn new() -> Self {
        Default::default()
    }

    pub fn usage() -> &'static str {
        "Usage: query"
    }

    pub fn query(
        &self,
        _name: &str,
        call: &EvaluatedCall,
        _value: &Value,
        _path: Option<Spanned<String>>,
    ) -> Result<Value, LabeledError> {
        let help = get_brief_subcommand_help(&Query.signature());
        Ok(Value::string(help, call.head))
    }

    pub fn query_json(
        &self,
        name: &str,
        call: &EvaluatedCall,
        input: &Value,
        query: Option<Spanned<String>>,
    ) -> Result<Value, LabeledError> {
        execute_json_query(name, call, input, query)
    }
    pub fn query_web(
        &self,
        _name: &str,
        call: &EvaluatedCall,
        input: &Value,
        _rest: Option<Spanned<String>>,
    ) -> Result<Value, LabeledError> {
        parse_selector_params(call, input)
    }
    pub fn query_xml(
        &self,
        name: &str,
        call: &EvaluatedCall,
        input: &Value,
        query: Option<Spanned<String>>,
    ) -> Result<Value, LabeledError> {
        execute_xpath_query(name, call, input, query)
    }
}

pub fn get_brief_subcommand_help(sigs: &[PluginSignature]) -> String {
    let mut help = String::new();
    let _ = write!(help, "{}\n\n", sigs[0].sig.usage);
    let _ = write!(help, "Usage:\n  > {}\n\n", sigs[0].sig.name);
    help.push_str("Subcommands:\n");

    for x in sigs.iter().enumerate() {
        if x.0 == 0 {
            continue;
        }
        let _ = writeln!(help, "  {} - {}", x.1.sig.name, x.1.sig.usage);
    }

    help.push_str(&get_flags_section(None, &sigs[0].sig, |v| {
        format!("{:#?}", v)
    }));
    help
}