azalea_brigadier/exceptions/
command_syntax_exception.rs

1use std::{
2    cmp,
3    fmt::{self, Write},
4};
5
6use super::builtin_exceptions::BuiltInExceptions;
7
8#[derive(Clone, PartialEq)]
9pub struct CommandSyntaxException {
10    pub type_: BuiltInExceptions,
11    message: String,
12    input: Option<String>,
13    cursor: Option<usize>,
14}
15
16const CONTEXT_AMOUNT: usize = 10;
17
18impl CommandSyntaxException {
19    pub fn new(type_: BuiltInExceptions, message: String, input: &str, cursor: usize) -> Self {
20        Self {
21            type_,
22            message,
23            input: Some(input.to_string()),
24            cursor: Some(cursor),
25        }
26    }
27
28    pub fn create(type_: BuiltInExceptions, message: String) -> Self {
29        Self {
30            type_,
31            message,
32            input: None,
33            cursor: None,
34        }
35    }
36
37    pub fn message(&self) -> String {
38        let mut message = self.message.clone();
39        let context = self.context();
40        if let Some(context) = context {
41            write!(
42                message,
43                " at position {}: {}",
44                self.cursor.unwrap_or(usize::MAX),
45                context
46            )
47            .unwrap();
48        }
49        message
50    }
51
52    pub fn raw_message(&self) -> &String {
53        &self.message
54    }
55
56    pub fn context(&self) -> Option<String> {
57        if let Some(input) = &self.input {
58            if let Some(cursor) = self.cursor {
59                let mut builder = String::new();
60                let cursor = cmp::min(input.len(), cursor);
61
62                if cursor > CONTEXT_AMOUNT {
63                    builder.push_str("...");
64                }
65
66                builder.push_str(
67                    &input
68                        [(cmp::max(0, cursor as isize - CONTEXT_AMOUNT as isize) as usize)..cursor],
69                );
70                builder.push_str("<--[HERE]");
71
72                return Some(builder);
73            }
74        }
75        None
76    }
77
78    pub fn get_type(&self) -> &BuiltInExceptions {
79        &self.type_
80    }
81
82    pub fn input(&self) -> &Option<String> {
83        &self.input
84    }
85
86    pub fn cursor(&self) -> Option<usize> {
87        self.cursor
88    }
89}
90
91impl fmt::Debug for CommandSyntaxException {
92    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93        write!(f, "{}", self.message())
94    }
95}