aboutsummaryrefslogtreecommitdiff
path: root/azalea-brigadier/src/context/command_context.rs
blob: 7a2189d9ae3e18e89d0bd56907ba6b00fef1951b (plain)
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use super::{
    parsed_argument::ParsedArgument, parsed_command_node::ParsedCommandNode,
    string_range::StringRange,
};
use crate::{
    arguments::argument_type::{ArgumentResult, ArgumentType},
    command::Command,
    redirect_modifier::RedirectModifier,
    tree::command_node::CommandNode,
};
use std::collections::HashMap;

pub struct CommandContext<S> {
    source: S,
    input: String,
    command: dyn Command<S>,
    arguments: HashMap<String, ParsedArgument<dyn ArgumentType<dyn ArgumentResult>>>,
    root_node: dyn CommandNode<S>,
    nodes: Vec<ParsedCommandNode<S>>,
    range: StringRange,
    child: Option<CommandContext<S>>,
    modifier: Option<dyn RedirectModifier<S>>,
    forks: bool,
}

impl<S> CommandContext<S> {
    pub fn clone_for(&self, source: S) -> Self {
        if self.source == source {
            return self.clone();
        }
        Self {
            source,
            input: self.input.clone(),
            command: self.command.clone(),
            arguments: self.arguments.clone(),
            root_node: self.root_node.clone(),
            nodes: self.nodes.clone(),
            range: self.range.clone(),
            child: self.child.clone(),
            modifier: self.modifier.clone(),
            forks: self.forks,
        }
    }

    fn child(&self) -> &Option<CommandContext<S>> {
        &self.child
    }

    fn last_child(&self) -> &CommandContext<S> {
        let mut result = self;
        while result.child.is_some() {
            result = result.child.as_ref().unwrap();
        }
        result
    }

    fn command(&self) -> &dyn Command<S> {
        &self.command
    }

    fn source(&self) -> &S {
        &self.source
    }

    // public <V> V getArgument(final String name, final Class<V> clazz) {
    //     final ParsedArgument<S, ?> argument = arguments.get(name);

    //     if (argument == null) {
    //         throw new IllegalArgumentException("No such argument '" + name + "' exists on this command");
    //     }

    //     final Object result = argument.getResult();
    //     if (PRIMITIVE_TO_WRAPPER.getOrDefault(clazz, clazz).isAssignableFrom(result.getClass())) {
    //         return (V) result;
    //     } else {
    //         throw new IllegalArgumentException("Argument '" + name + "' is defined as " + result.getClass().getSimpleName() + ", not " + clazz);
    //     }
    // }
    fn get_argument<V>(&self, name: &str) -> Result<V, String> {
        let argument = self.arguments.get(name);

        if argument.is_none() {
            return Err(format!(
                "No such argument '{}' exists on this command",
                name
            ));
        }

        let result = argument.unwrap().result();
        Ok(result)
    }
}