/// Error types for Rope operations, based on Ropey's Error enum
///|
/// Result type for Rope operations
pub type RopeResult[T] = Result[T, RopeError]
///|
/// Error types that can occur during Rope operations
pub enum RopeError {
/// Indicates that the passed character index was out of bounds
/// Contains the index attempted and the actual length in characters
CharIndexOutOfBounds(Int, Int)
/// Indicates that the passed UTF-16 code unit index was out of bounds
/// Contains the index attempted and the actual length in UTF-16 code units
Utf16IndexOutOfBounds(Int, Int)
/// Indicates that the passed line index was out of bounds
/// Contains the index attempted and the actual number of lines
LineIndexOutOfBounds(Int, Int)
/// Indicates that a reversed range (end < start) was encountered
/// Contains the start and end indices
CharRangeInvalid(Int, Int)
/// Indicates that the passed range was partially or fully out of bounds
/// Contains the start, end, and rope length
CharRangeOutOfBounds(Int, Int, Int)
/// Indicates a general invalid operation
InvalidOperation(String)
}
///|
/// Convert RopeError to String for display
pub fn RopeError::error_to_string(self : RopeError) -> String {
match self {
CharIndexOutOfBounds(index, len) =>
"Character index out of bounds: char index \{index}, Rope char length \{len}"
Utf16IndexOutOfBounds(index, len) =>
"UTF-16 index out of bounds: utf16 index \{index}, Rope utf16 length \{len}"
LineIndexOutOfBounds(index, len) =>
"Line index out of bounds: line index \{index}, Rope line count \{len}"
CharRangeInvalid(start, end) =>
"Invalid char range \{start}..\{end}: start must be <= end"
CharRangeOutOfBounds(start, end, len) =>
"Character range out of bounds: char range \{start}..\{end}, Rope char length \{len}"
InvalidOperation(msg) => "Invalid operation: \{msg}"
}
}
///|
/// Check if a character index is valid
pub fn check_char_index(char_idx : Int, rope_len : Int) -> RopeResult[Unit] {
if char_idx < 0 || char_idx >= rope_len {
Err(CharIndexOutOfBounds(char_idx, rope_len))
} else {
Ok(())
}
}
///|
/// Check if a character index is valid for insertion (can be equal to length)
pub fn check_char_index_for_insert(
char_idx : Int,
rope_len : Int,
) -> RopeResult[Unit] {
if char_idx < 0 || char_idx > rope_len {
Err(CharIndexOutOfBounds(char_idx, rope_len))
} else {
Ok(())
}
}
///|
/// Check if a UTF-16 index is valid
pub fn check_utf16_index(
utf16_idx : Int,
rope_utf16_len : Int,
) -> RopeResult[Unit] {
if utf16_idx < 0 || utf16_idx >= rope_utf16_len {
Err(Utf16IndexOutOfBounds(utf16_idx, rope_utf16_len))
} else {
Ok(())
}
}
///|
/// Check if a line index is valid
pub fn check_line_index(
line_idx : Int,
rope_line_count : Int,
) -> RopeResult[Unit] {
if line_idx < 0 || line_idx >= rope_line_count {
Err(LineIndexOutOfBounds(line_idx, rope_line_count))
} else {
Ok(())
}
}
///|
/// Check if a character range is valid
pub fn check_char_range(
start : Int,
end : Int,
rope_len : Int,
) -> RopeResult[Unit] {
if start > end {
Err(CharRangeInvalid(start, end))
} else if start < 0 || end > rope_len {
Err(CharRangeOutOfBounds(start, end, rope_len))
} else {
Ok(())
}
}