synkit_core/error.rs
1//! Core error types for synkit.
2//!
3//! User-defined error types should implement `From<synkit::Error>` to integrate
4//! with synkit's built-in error handling.
5
6use core::fmt;
7
8/// Core synkit error type.
9///
10/// This enum captures errors that originate from synkit's internal operations.
11/// User-defined parsers should define their own error types and implement
12/// `From<Error>` to convert synkit errors into their domain-specific errors.
13///
14/// # Example
15///
16/// ```ignore
17/// use thiserror::Error;
18///
19/// #[derive(Error, Debug)]
20/// pub enum MyParseError {
21/// #[error("stream not fully consumed: {remaining} tokens remaining")]
22/// StreamNotConsumed { remaining: usize },
23///
24/// #[error("expected {expect}, found {found}")]
25/// Expected { expect: &'static str, found: String },
26///
27/// // ... other variants
28/// }
29///
30/// impl From<synkit::Error> for MyParseError {
31/// fn from(err: synkit::Error) -> Self {
32/// match err {
33/// synkit::Error::StreamNotConsumed { remaining } => {
34/// MyParseError::StreamNotConsumed { remaining }
35/// }
36/// }
37/// }
38/// }
39/// ```
40#[derive(Debug, Clone, Copy, PartialEq, Eq)]
41pub enum Error {
42 /// The token stream was not fully consumed after parsing.
43 ///
44 /// This error is returned by `ensure_consumed()` when there are
45 /// remaining tokens (excluding whitespace) in the stream.
46 StreamNotConsumed {
47 /// Number of remaining tokens (excluding whitespace).
48 remaining: usize,
49 },
50
51 /// Recursion limit exceeded during parsing.
52 ///
53 /// This error is returned when nested parsing exceeds the configured
54 /// maximum recursion depth. This limit exists to prevent stack overflow
55 /// from deeply nested malicious input.
56 ///
57 /// # Example
58 ///
59 /// Input like `[[[[[[...]]]]]]` with thousands of nesting levels would
60 /// trigger this error with the default limit of 128.
61 RecursionLimitExceeded {
62 /// Current recursion depth when limit was exceeded.
63 depth: usize,
64 /// Maximum allowed recursion depth.
65 limit: usize,
66 },
67
68 /// Token limit exceeded during parsing.
69 ///
70 /// This error is returned when the parser has consumed more tokens than
71 /// the configured maximum. This limit exists to prevent resource exhaustion
72 /// from extremely long inputs.
73 TokenLimitExceeded {
74 /// Number of tokens consumed when limit was exceeded.
75 consumed: usize,
76 /// Maximum allowed token count.
77 limit: usize,
78 },
79}
80
81impl fmt::Display for Error {
82 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83 match self {
84 Error::StreamNotConsumed { remaining } => {
85 write!(
86 f,
87 "stream not fully consumed: {} tokens remaining",
88 remaining
89 )
90 }
91 Error::RecursionLimitExceeded { depth, limit } => {
92 write!(
93 f,
94 "recursion limit exceeded: depth {} > limit {}",
95 depth, limit
96 )
97 }
98 Error::TokenLimitExceeded { consumed, limit } => {
99 write!(
100 f,
101 "token limit exceeded: consumed {} > limit {}",
102 consumed, limit
103 )
104 }
105 }
106 }
107}
108
109#[cfg(feature = "std")]
110impl std::error::Error for Error {}