const_format_proc_macros/format_str/
errors.rs1use proc_macro2::Span;
2
3use std::{
4 fmt::{self, Display},
5 ops::Range,
6};
7
8#[derive(Debug, PartialEq)]
9pub(crate) struct ParseError {
10 pub(crate) pos: usize,
11 pub(crate) kind: ParseErrorKind,
12}
13
14#[derive(Debug, PartialEq)]
15pub(crate) enum ParseErrorKind {
16 UnclosedArg,
18 InvalidClosedArg,
20 NotANumber {
22 what: String,
23 },
24 NotAnIdent {
26 what: String,
27 },
28 UnknownFormatting {
29 what: String,
30 },
31}
32
33#[allow(dead_code)]
34impl ParseErrorKind {
35 pub fn not_a_number(what: &str) -> Self {
36 Self::NotANumber {
37 what: what.to_string(),
38 }
39 }
40 pub fn not_an_ident(what: &str) -> Self {
41 Self::NotAnIdent {
42 what: what.to_string(),
43 }
44 }
45 pub fn unknown_formatting(what: &str) -> Self {
46 Self::UnknownFormatting {
47 what: what.to_string(),
48 }
49 }
50}
51
52#[derive(Debug, PartialEq)]
55pub(crate) struct DisplayParseError<'a> {
56 pub(crate) str: &'a str,
57 pub(crate) error_span: Range<usize>,
58 pub(crate) kind: ParseErrorKind,
59}
60impl ParseError {
61 fn error_span(&self) -> Range<usize> {
62 let len = match &self.kind {
63 ParseErrorKind::UnclosedArg => 0,
64 ParseErrorKind::InvalidClosedArg => 0,
65 ParseErrorKind::NotANumber { what } => what.len(),
66 ParseErrorKind::NotAnIdent { what } => what.len(),
67 ParseErrorKind::UnknownFormatting { what } => what.len(),
68 };
69
70 self.pos..self.pos + len
71 }
72
73 pub(crate) fn into_crate_err(self, span: Span, original_str: &str) -> crate::Error {
74 let display = DisplayParseError {
75 str: original_str,
76 error_span: self.error_span(),
77 kind: self.kind,
78 };
79
80 crate::Error::new(span, display)
81 }
82}
83
84impl Display for ParseErrorKind {
85 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86 match self {
87 ParseErrorKind::UnclosedArg => f.write_str("unclosed argument"),
88 ParseErrorKind::InvalidClosedArg => f.write_str("`}` closing a nonexistent argument"),
89 ParseErrorKind::NotANumber { what } => writeln!(f, "not a number: \"{}\"", what),
90 ParseErrorKind::NotAnIdent { what } => {
91 writeln!(f, "not a valid identifier: \"{}\"", what)
92 }
93 ParseErrorKind::UnknownFormatting { what } => {
94 writeln!(f, "unknown formatting: \"{}\"", what)
95 }
96 }
97 }
98}
99
100impl Display for DisplayParseError<'_> {
101 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102 f.write_str("failed to parse the format string ")?;
103
104 let chars = self.str[..self.error_span.start].chars().count();
108 writeln!(f, "at the character number {}, ", chars)?;
109
110 Display::fmt(&self.kind, f)?;
111
112 Ok(())
113 }
114}