mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 06:16:04 +00:00
add execute & get_integer
This commit is contained in:
parent
82ed6baea5
commit
10cd1733cb
9 changed files with 82 additions and 39 deletions
|
@ -67,7 +67,6 @@ impl<S: Any + Clone> ArgumentBuilder<S> {
|
|||
}
|
||||
|
||||
pub fn build(self) -> CommandNode<S> {
|
||||
println!("building {:?}", self);
|
||||
CommandNode {
|
||||
value: self.value,
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
use super::argument_builder::{ArgumentBuilder, ArgumentBuilderType};
|
||||
use crate::{parsers::Parser, string_reader::StringReader};
|
||||
use crate::{
|
||||
exceptions::command_syntax_exception::CommandSyntaxException, parsers::Parser,
|
||||
string_reader::StringReader,
|
||||
};
|
||||
use std::{any::Any, fmt::Debug, rc::Rc};
|
||||
|
||||
/// An argument node type. The `T` type parameter is the type of the argument,
|
||||
|
@ -17,7 +20,7 @@ impl Argument {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn parse(&self, reader: &mut StringReader) -> Option<Rc<dyn Any>> {
|
||||
pub fn parse(&self, reader: &mut StringReader) -> Result<Rc<dyn Any>, CommandSyntaxException> {
|
||||
self.parser.parse(reader)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -142,4 +142,9 @@ impl<S: Any + Clone> CommandContext<S> {
|
|||
pub fn has_nodes(&self) -> bool {
|
||||
return !self.nodes.is_empty();
|
||||
}
|
||||
|
||||
pub fn argument(&self, name: &str) -> Option<Rc<dyn Any>> {
|
||||
let argument = self.arguments.get(name);
|
||||
argument.map(|a| a.result.clone())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ use crate::{
|
|||
builtin_exceptions::BuiltInExceptions, command_syntax_exception::CommandSyntaxException,
|
||||
},
|
||||
parse_results::ParseResults,
|
||||
string_range::StringRange,
|
||||
string_reader::StringReader,
|
||||
tree::CommandNode,
|
||||
};
|
||||
|
@ -28,10 +27,8 @@ impl<S: Any + Clone> CommandDispatcher<S> {
|
|||
}
|
||||
|
||||
pub fn register(&mut self, node: ArgumentBuilder<S>) {
|
||||
println!("register {:#?}", node);
|
||||
let build = Rc::new(RefCell::new(node.build()));
|
||||
self.root.borrow_mut().add_child(&build);
|
||||
// println!("build: {:#?}", build);
|
||||
}
|
||||
|
||||
pub fn parse(&self, command: StringReader, source: S) -> ParseResults<S> {
|
||||
|
@ -142,7 +139,6 @@ impl<S: Any + Clone> CommandDispatcher<S> {
|
|||
})
|
||||
}
|
||||
let best_potential = potentials.into_iter().next().unwrap();
|
||||
println!("chosen {:#?}", best_potential);
|
||||
return Ok(best_potential);
|
||||
}
|
||||
|
||||
|
@ -153,10 +149,14 @@ impl<S: Any + Clone> CommandDispatcher<S> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn execute(&self, input: StringReader, source: S) -> Result<i32, CommandSyntaxException> {
|
||||
let parse = self.parse(input, source);
|
||||
Self::execute_parsed(parse)
|
||||
}
|
||||
|
||||
/// Executes a given pre-parsed command.
|
||||
pub fn execute(parse: ParseResults<S>) -> Result<i32, CommandSyntaxException> {
|
||||
pub fn execute_parsed(parse: ParseResults<S>) -> Result<i32, CommandSyntaxException> {
|
||||
if parse.reader.can_read() {
|
||||
println!("can read from reader {}", parse.reader.cursor);
|
||||
if parse.exceptions.len() == 1 {
|
||||
return Err(parse.exceptions.values().next().unwrap().clone());
|
||||
}
|
||||
|
@ -169,7 +169,6 @@ impl<S: Any + Clone> CommandDispatcher<S> {
|
|||
BuiltInExceptions::DispatcherUnknownArgument.create_with_context(&parse.reader)
|
||||
);
|
||||
}
|
||||
println!("a");
|
||||
let mut result = 0i32;
|
||||
let mut successful_forks = 0;
|
||||
let mut forked = false;
|
||||
|
|
|
@ -6,17 +6,17 @@ use super::command_syntax_exception::CommandSyntaxException;
|
|||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub enum BuiltInExceptions {
|
||||
DoubleTooSmall { found: usize, min: usize },
|
||||
DoubleTooBig { found: usize, max: usize },
|
||||
DoubleTooSmall { found: f64, min: f64 },
|
||||
DoubleTooBig { found: f64, max: f64 },
|
||||
|
||||
FloatTooSmall { found: usize, min: usize },
|
||||
FloatTooBig { found: usize, max: usize },
|
||||
FloatTooSmall { found: f32, min: f32 },
|
||||
FloatTooBig { found: f32, max: f32 },
|
||||
|
||||
IntegerTooSmall { found: usize, min: usize },
|
||||
IntegerTooBig { found: usize, max: usize },
|
||||
IntegerTooSmall { found: i32, min: i32 },
|
||||
IntegerTooBig { found: i32, max: i32 },
|
||||
|
||||
LONGTooSmall { found: usize, min: usize },
|
||||
LONGTooBig { found: usize, max: usize },
|
||||
LongTooSmall { found: i64, min: i64 },
|
||||
LongTooBig { found: i64, max: i64 },
|
||||
|
||||
LiteralIncorrect { expected: String },
|
||||
|
||||
|
@ -65,10 +65,10 @@ impl fmt::Debug for BuiltInExceptions {
|
|||
write!(f, "Integer must not be more than {}, found {}", max, found)
|
||||
}
|
||||
|
||||
BuiltInExceptions::LONGTooSmall { found, min } => {
|
||||
BuiltInExceptions::LongTooSmall { found, min } => {
|
||||
write!(f, "Long must not be less than {}, found {}", min, found)
|
||||
}
|
||||
BuiltInExceptions::LONGTooBig { found, max } => {
|
||||
BuiltInExceptions::LongTooBig { found, max } => {
|
||||
write!(f, "Long must not be more than {}, found {}", max, found)
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ mod tests {
|
|||
use crate::{
|
||||
builder::{literal_argument_builder::literal, required_argument_builder::argument},
|
||||
dispatcher::CommandDispatcher,
|
||||
parsers::integer,
|
||||
parsers::{get_integer, integer},
|
||||
};
|
||||
|
||||
struct CommandSourceStack {
|
||||
|
@ -36,7 +36,7 @@ mod tests {
|
|||
dispatcher.register(
|
||||
literal("foo")
|
||||
.then(argument("bar", integer()).executes(|c| {
|
||||
// println!("Bar is {}", get_integer(c, "bar"));
|
||||
println!("Bar is {:?}", get_integer(c, "bar"));
|
||||
2
|
||||
}))
|
||||
.executes(|c| {
|
||||
|
@ -45,11 +45,8 @@ mod tests {
|
|||
}),
|
||||
);
|
||||
|
||||
let parse = dispatcher.parse("foo 123".to_string().into(), source);
|
||||
println!(
|
||||
"{}",
|
||||
CommandDispatcher::<Rc<CommandSourceStack>>::execute(parse).unwrap()
|
||||
);
|
||||
// assert_eq!(dispatcher.execute("foo bar", source), 2);
|
||||
let parse = dispatcher.parse("foo 123".into(), source.clone());
|
||||
assert_eq!(CommandDispatcher::<_>::execute_parsed(parse).unwrap(), 2);
|
||||
assert_eq!(dispatcher.execute("foo".into(), source).unwrap(), 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +1,56 @@
|
|||
use std::{any::Any, marker::PhantomData, rc::Rc};
|
||||
|
||||
use crate::string_reader::StringReader;
|
||||
use crate::{
|
||||
context::CommandContext,
|
||||
exceptions::{
|
||||
builtin_exceptions::BuiltInExceptions, command_syntax_exception::CommandSyntaxException,
|
||||
},
|
||||
string_reader::StringReader,
|
||||
};
|
||||
|
||||
pub trait Parser {
|
||||
fn parse(&self, reader: &mut StringReader) -> Option<Rc<dyn Any>>;
|
||||
fn parse(&self, reader: &mut StringReader) -> Result<Rc<dyn Any>, CommandSyntaxException>;
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct Integer {
|
||||
pub minimum: Option<i32>,
|
||||
pub maximum: Option<i32>,
|
||||
}
|
||||
|
||||
struct Integer {}
|
||||
impl Parser for Integer {
|
||||
fn parse(&self, reader: &mut StringReader) -> Option<Rc<dyn Any>> {
|
||||
fn parse(&self, reader: &mut StringReader) -> Result<Rc<dyn Any>, CommandSyntaxException> {
|
||||
let start = reader.cursor;
|
||||
let result = reader.read_int();
|
||||
// TODO: check min and max
|
||||
Some(Rc::new(result))
|
||||
let result = reader.read_int()?;
|
||||
if let Some(minimum) = self.minimum {
|
||||
if result < minimum {
|
||||
return Err(BuiltInExceptions::IntegerTooSmall {
|
||||
found: result,
|
||||
min: minimum,
|
||||
}
|
||||
.create_with_context(reader));
|
||||
}
|
||||
}
|
||||
if let Some(maximum) = self.maximum {
|
||||
if result > maximum {
|
||||
return Err(BuiltInExceptions::IntegerTooBig {
|
||||
found: result,
|
||||
max: maximum,
|
||||
}
|
||||
.create_with_context(reader));
|
||||
}
|
||||
}
|
||||
Ok(Rc::new(result))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn integer() -> impl Parser {
|
||||
Integer {}
|
||||
Integer::default()
|
||||
}
|
||||
pub fn get_integer<S: Any + Clone>(context: &CommandContext<S>, name: &str) -> Option<i32> {
|
||||
context
|
||||
.argument(name)
|
||||
.unwrap()
|
||||
.downcast_ref::<i32>()
|
||||
.map(|x| *x)
|
||||
}
|
||||
|
|
|
@ -18,6 +18,14 @@ impl From<String> for StringReader {
|
|||
Self { string, cursor: 0 }
|
||||
}
|
||||
}
|
||||
impl From<&str> for StringReader {
|
||||
fn from(string: &str) -> Self {
|
||||
Self {
|
||||
string: string.to_string(),
|
||||
cursor: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StringReader {
|
||||
pub fn string(&self) -> &str {
|
||||
|
|
|
@ -67,8 +67,6 @@ impl<S: Any + Clone> CommandNode<S> {
|
|||
pub fn get_relevant_nodes(&self, input: &mut StringReader) -> Vec<Rc<RefCell<CommandNode<S>>>> {
|
||||
let literals = self.literals();
|
||||
|
||||
println!("get relevant nodes {:?} literals={:?}", self, literals);
|
||||
|
||||
if literals.len() > 0 {
|
||||
let cursor = input.cursor();
|
||||
while input.can_read() && input.peek() != ' ' {
|
||||
|
@ -220,7 +218,6 @@ impl<S: Any + Clone> Debug for CommandNode<S> {
|
|||
|
||||
impl<S: Any + Clone> Default for CommandNode<S> {
|
||||
fn default() -> Self {
|
||||
println!("making default node");
|
||||
Self {
|
||||
value: ArgumentBuilderType::Literal(Literal::default()),
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue