use candid::CandidType;
use core::fmt;
use serde::{Deserialize, Serialize};
use std::ops::{Range, RangeBounds};
#[derive(Serialize, Deserialize, CandidType, Copy, Clone, Default, PartialEq, Eq, Hash)]
#[doc(alias = "..")]
pub struct CandidRange<Idx: CandidType> {
pub start: Idx,
pub end: Idx,
}
impl<Idx: fmt::Debug + CandidType> fmt::Debug for CandidRange<Idx> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
self.start.fmt(fmt)?;
write!(fmt, "..")?;
self.end.fmt(fmt)?;
Ok(())
}
}
impl<Idx: PartialOrd<Idx> + CandidType> RangeBounds<Idx> for CandidRange<Idx> {
fn start_bound(&self) -> std::ops::Bound<&Idx> {
std::ops::Bound::Included(&self.start)
}
fn end_bound(&self) -> std::ops::Bound<&Idx> {
std::ops::Bound::Excluded(&self.end)
}
}
impl<Idx: PartialOrd<Idx> + CandidType> CandidRange<Idx> {
pub fn contains<U>(&self, item: &U) -> bool
where
Idx: PartialOrd<U>,
U: ?Sized + PartialOrd<Idx>,
{
<Self as RangeBounds<Idx>>::contains(self, item)
}
pub fn is_empty(&self) -> bool {
!(self.start < self.end)
}
}
impl<Idx: PartialOrd<Idx> + CandidType, Idx2> From<CandidRange<Idx>> for Range<Idx2>
where
Idx: Into<Idx2>,
{
fn from(range: CandidRange<Idx>) -> Self {
Range {
start: range.start.into(),
end: range.end.into(),
}
}
}
impl<Idx, Idx2: PartialOrd<Idx> + CandidType> From<Range<Idx>> for CandidRange<Idx2>
where
Idx: Into<Idx2>,
{
fn from(range: Range<Idx>) -> Self {
CandidRange {
start: range.start.into(),
end: range.end.into(),
}
}
}