#![allow(incomplete_features)]
#![feature(generic_const_exprs)]
#![allow(clippy::collapsible_if)]
#![allow(clippy::inline_always)]
#![allow(clippy::needless_return)]
#![allow(clippy::redundant_field_names)]
#![allow(clippy::type_complexity)]
mod rope;
mod rope_builder;
mod slice;
mod slice_utils;
mod tree;
pub mod iter;
use std::ops::Bound;
pub use crate::rope::{Measurable, Rope};
pub use crate::rope_builder::RopeBuilder;
pub use crate::slice::RopeSlice;
pub use crate::tree::{max_children, max_len};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Lipsum {
Lorem,
Ipsum,
Dolor(usize),
Sit,
Amet,
Consectur(&'static str),
Adipiscing(bool),
}
impl Measurable for Lipsum {
fn width(&self) -> usize {
match self {
Lipsum::Lorem => 1,
Lipsum::Ipsum => 2,
Lipsum::Dolor(width) => *width,
Lipsum::Sit => 0,
Lipsum::Amet => 0,
Lipsum::Consectur(text) => text.len(),
Lipsum::Adipiscing(boolean) => *boolean as usize,
}
}
}
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Clone, Copy)]
#[non_exhaustive]
pub enum Error {
IndexOutOfBounds(usize, usize),
WidthOutOfBounds(usize, usize),
IndexRangeInvalid(
usize, usize, ),
WidthRangeInvalid(
usize, usize, ),
IndexRangeOutOfBounds(
Option<usize>, Option<usize>, usize, ),
WidthRangeOutOfBounds(
Option<usize>, Option<usize>, usize, ),
}
impl std::fmt::Debug for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match *self {
Error::IndexOutOfBounds(index, len) => {
write!(
f,
"Index out of bounds: index {}, Rope/RopeSlice length {}",
index, len
)
}
Error::WidthOutOfBounds(index, len) => {
write!(
f,
"Width out of bounds: width {}, Rope/RopeSlice char length {}",
index, len
)
}
Error::IndexRangeInvalid(start_idx, end_idx) => {
write!(
f,
"Invalid index range {}..{}: start must be <= end",
start_idx, end_idx
)
}
Error::WidthRangeInvalid(start_idx, end_idx) => {
write!(
f,
"Invalid width range {}..{}: start must be <= end",
start_idx, end_idx
)
}
Error::IndexRangeOutOfBounds(start_idx_opt, end_idx_opt, len) => {
write!(f, "Index range out of bounds: index range ")?;
write_range(f, start_idx_opt, end_idx_opt)?;
write!(f, ", Rope/RopeSlice byte length {}", len)
}
Error::WidthRangeOutOfBounds(start_idx_opt, end_idx_opt, len) => {
write!(f, "Width range out of bounds: width range ")?;
write_range(f, start_idx_opt, end_idx_opt)?;
write!(f, ", Rope/RopeSlice char length {}", len)
}
}
}
}
impl std::error::Error for Error {}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Debug::fmt(self, f)
}
}
fn write_range(
f: &mut std::fmt::Formatter<'_>,
start_idx: Option<usize>,
end_idx: Option<usize>,
) -> std::fmt::Result {
match (start_idx, end_idx) {
(None, None) => write!(f, ".."),
(Some(start), None) => write!(f, "{}..", start),
(None, Some(end)) => write!(f, "..{}", end),
(Some(start), Some(end)) => write!(f, "{}..{}", start, end),
}
}
#[inline(always)]
pub(crate) fn start_bound_to_num(b: Bound<&usize>) -> Option<usize> {
match b {
Bound::Included(n) => Some(*n),
Bound::Excluded(n) => Some(*n + 1),
Bound::Unbounded => None,
}
}
#[inline(always)]
pub(crate) fn end_bound_to_num(b: Bound<&usize>) -> Option<usize> {
match b {
Bound::Included(n) => Some(*n + 1),
Bound::Excluded(n) => Some(*n),
Bound::Unbounded => None,
}
}
#[macro_export]
#[doc(hidden)]
macro_rules! log_info {
($($text:tt)*) => {{
use std::{fs, io::Write};
let mut log = fs::OpenOptions::new().append(true).open("log").unwrap();
log.write_fmt(format_args!($($text)*)).unwrap();
}};
}