azalea_brigadier/exceptions/
command_syntax_exception.rs1use 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}