use core::ops::{AddAssign, Range};
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
pub struct SimpleSpan<Offset = usize> {
pub(crate) start: Offset,
pub(crate) end: Offset,
}
impl<O> core::fmt::Display for SimpleSpan<O>
where
O: core::fmt::Display,
{
#[cfg_attr(not(tarpaulin), inline(always))]
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{}..{}", self.start, self.end)
}
}
impl<O> SimpleSpan<&O>
where
O: Clone,
{
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn cloned(self) -> SimpleSpan<O> {
SimpleSpan {
start: self.start.clone(),
end: self.end.clone(),
}
}
}
impl SimpleSpan {
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn const_new(start: usize, end: usize) -> Self {
assert!(end >= start, "end must be greater than or equal to start");
Self { start, end }
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn try_const_new(start: usize, end: usize) -> Option<Self> {
if end >= start {
Some(Self { start, end })
} else {
None
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn bump_start_const(&mut self, n: usize) -> &mut Self {
self.start += n;
assert!(
self.start <= self.end,
"start must be less than or equal to end"
);
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn bump_end_const(&mut self, n: usize) -> &mut Self {
self.end += n;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn bump_const(&mut self, n: usize) -> &mut Self {
self.start += n;
self.end += n;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_start_const(&mut self, start: usize) -> &mut Self {
self.start = start;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_end_const(&mut self, end: usize) -> &mut Self {
self.end = end;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_start_const(mut self, start: usize) -> Self {
self.start = start;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_end_const(mut self, end: usize) -> Self {
self.end = end;
self
}
}
impl<O> SimpleSpan<O> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn as_ref(&self) -> SimpleSpan<&O> {
SimpleSpan {
start: &self.start,
end: &self.end,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn as_mut(&mut self) -> SimpleSpan<&mut O> {
SimpleSpan {
start: &mut self.start,
end: &mut self.end,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn new(start: O, end: O) -> Self
where
O: Ord,
{
assert!(end >= start, "end must be greater than or equal to start");
Self { start, end }
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn try_new(start: O, end: O) -> Option<Self>
where
O: Ord,
{
if end >= start {
Some(Self { start, end })
} else {
None
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn bump_start(&mut self, n: O) -> &mut Self
where
O: AddAssign<O> + Ord,
{
self.start += n;
assert!(
self.start <= self.end,
"start must be less than or equal to end"
);
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn bump_end(&mut self, n: O) -> &mut Self
where
O: AddAssign<O>,
{
self.end += n;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn bump(&mut self, n: &O) -> &mut Self
where
O: for<'a> AddAssign<&'a O> + Clone,
{
self.start += n;
self.end += n;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn set_start(&mut self, start: O) -> &mut Self {
self.start = start;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn set_end(&mut self, end: O) -> &mut Self {
self.end = end;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn with_start(mut self, start: O) -> Self {
self.start = start;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn with_end(mut self, end: O) -> Self {
self.end = end;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn start(&self) -> O
where
O: Copy,
{
self.start
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn start_ref(&self) -> &O {
&self.start
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn start_mut(&mut self) -> &mut O {
&mut self.start
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn end(&self) -> O
where
O: Copy,
{
self.end
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn end_ref(&self) -> &O {
&self.end
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn end_mut(&mut self) -> &mut O {
&mut self.end
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn len(&self) -> O
where
O: for<'a> core::ops::Sub<&'a O, Output = O> + Clone,
{
self.end.clone().sub(&self.start)
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn is_empty(&self) -> bool
where
O: PartialEq,
{
self.start == self.end
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn range(&self) -> Range<&O> {
&self.start..&self.end
}
}
impl<O> From<Range<O>> for SimpleSpan<O>
where
O: Ord,
{
#[cfg_attr(not(tarpaulin), inline(always))]
fn from(range: Range<O>) -> Self {
Self::new(range.start, range.end)
}
}
impl<O> From<SimpleSpan<O>> for Range<O> {
#[cfg_attr(not(tarpaulin), inline(always))]
fn from(span: SimpleSpan<O>) -> Self {
span.start..span.end
}
}
impl<O> From<(O, O)> for SimpleSpan<O>
where
O: Ord,
{
#[cfg_attr(not(tarpaulin), inline(always))]
fn from((start, end): (O, O)) -> Self {
Self::new(start, end)
}
}
impl<O> From<SimpleSpan<O>> for (O, O) {
#[cfg_attr(not(tarpaulin), inline(always))]
fn from(span: SimpleSpan<O>) -> Self {
(span.start, span.end)
}
}