azalea_brigadier/errors/
command_syntax_error.rs1use std::{
2 cmp,
3 fmt::{self, Debug, Write},
4};
5
6use super::builtin_errors::BuiltInError;
7
8#[derive(Clone, PartialEq)]
9pub struct CommandSyntaxError {
10 kind: BuiltInError,
11 message: String,
12 input: Option<String>,
13 cursor: Option<usize>,
14}
15
16const CONTEXT_AMOUNT: usize = 10;
17
18impl CommandSyntaxError {
19 pub fn new(kind: BuiltInError, message: String, input: &str, cursor: usize) -> Self {
20 Self {
21 kind,
22 message,
23 input: Some(input.to_string()),
24 cursor: Some(cursor),
25 }
26 }
27
28 pub fn create(kind: BuiltInError, message: String) -> Self {
29 Self {
30 kind,
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 {}: {context}",
44 self.cursor.unwrap_or(usize::MAX)
45 )
46 .unwrap();
47 }
48 message
49 }
50
51 pub fn raw_message(&self) -> &String {
52 &self.message
53 }
54
55 pub fn context(&self) -> Option<String> {
56 if let Some(input) = &self.input
57 && let Some(cursor) = self.cursor
58 {
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[(cmp::max(0, cursor as isize - CONTEXT_AMOUNT as isize) as usize)..cursor],
68 );
69 builder.push_str("<--[HERE]");
70
71 return Some(builder);
72 }
73 None
74 }
75
76 pub fn kind(&self) -> &BuiltInError {
77 &self.kind
78 }
79
80 pub fn input(&self) -> &Option<String> {
81 &self.input
82 }
83
84 pub fn cursor(&self) -> Option<usize> {
85 self.cursor
86 }
87}
88
89impl Debug for CommandSyntaxError {
90 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91 write!(f, "{}", self.message())
92 }
93}