///| RLE error types
///|
/// Internal invariant violations - indicates bugs, not user errors
pub(all) suberror InternalError {
EmptyElement // Attempted to add element with span == 0
InvalidState(detail~ : String)
} derive(Debug)
///|
pub impl Show for InternalError with fn output(self, logger) {
logger.write_string(@debug.to_string(self))
}
///|
/// Slice errors when extracting sub-ranges from a run.
///
/// These are raised when a slice lands outside the valid bounds or splits a
/// UTF-16 surrogate pair (string slicing is done in code units).
pub(all) suberror SliceError {
/// Start/end fall outside the run bounds.
IndexOutOfBounds
/// Start/end split a UTF-16 surrogate pair.
InvalidIndex
} derive(Debug, Eq)
///|
pub impl Show for SliceError with fn output(self, logger) {
logger.write_string(@debug.to_string(self))
}
///|
/// Why a range is invalid
pub enum RangeIssue {
NegativeStart
NegativeEnd
StartAfterEnd
ExceedsLength
} derive(Debug, Eq)
///|
pub impl Show for RangeIssue with fn output(self, logger) {
logger.write_string(@debug.to_string(self))
}
///|
/// User-facing errors with context for friendly messages
pub(all) suberror RleError {
PositionOutOfBounds(position~ : Int, length~ : Int)
InvalidRange(start~ : Int, end~ : Int, length~ : Int, reason~ : RangeIssue)
/// A slice failed to produce a valid value (e.g., invalid UTF-16 boundary).
InvalidSlice(reason~ : SliceError)
Internal(InternalError)
} derive(Debug)
///|
pub impl Show for RleError with fn output(self, logger) {
logger.write_string(@debug.to_string(self))
}
///|
/// Rust style wrapper struct for user-friendly error display
///
/// https://doc.rust-lang.org/stable/std/path/struct.Display.html
pub struct ErrorMessage {
priv error : RleError
}
///|
/// Get a user-friendly message wrapper for this error
pub fn RleError::message(self : RleError) -> ErrorMessage {
{ error: self }
}
///|
/// Display user-friendly error message
pub impl Show for ErrorMessage with fn output(self, logger) {
match self.error {
PositionOutOfBounds(position~, length~) =>
logger.write_string(
"Position \{position} is outside the document (length: \{length})",
)
InvalidRange(start~, end~, length~, reason~) =>
match reason {
NegativeStart =>
logger.write_string("Range start (\{start}) cannot be negative")
NegativeEnd =>
logger.write_string("Range end (\{end}) cannot be negative")
StartAfterEnd =>
logger.write_string(
"Range start (\{start}) must come before end (\{end})",
)
ExceedsLength =>
logger.write_string(
"Range end (\{end}) exceeds document length (\{length})",
)
}
InvalidSlice(reason~) =>
match reason {
IndexOutOfBounds =>
logger.write_string("Slice indices are out of bounds")
InvalidIndex =>
logger.write_string("Slice indices are not on valid boundaries")
}
Internal(_) =>
logger.write_string(
"An internal error occurred. Please report this as a bug.",
)
}
}