#[repr(C)]
#[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
pub struct GpuMatch(pub [u32; 4]);
#[repr(C)]
#[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable, Default)]
pub struct Match {
pub pattern_id: u32,
pub start: u32,
pub end: u32,
pub padding: u32,
}
impl PartialEq for Match {
fn eq(&self, other: &Self) -> bool {
self.pattern_id == other.pattern_id && self.start == other.start && self.end == other.end
}
}
impl Eq for Match {}
impl PartialOrd for Match {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Match {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.start
.cmp(&other.start)
.then(self.pattern_id.cmp(&other.pattern_id))
.then(self.end.cmp(&other.end))
}
}
impl Match {
#[must_use]
pub const fn from_parts(pattern_id: u32, start: u32, end: u32) -> Self {
Self {
pattern_id,
start,
end,
padding: 0,
}
}
#[must_use]
pub const fn padding(&self) -> u32 {
self.padding
}
#[must_use]
pub const fn from_parts_with_padding(
pattern_id: u32,
start: u32,
end: u32,
padding: u32,
) -> Self {
Self {
pattern_id,
start,
end,
padding,
}
}
#[must_use]
pub const fn contains(&self, other: &Match) -> bool {
self.start <= other.start && self.end >= other.end
}
#[must_use]
pub const fn overlaps(&self, other: &Match) -> bool {
self.start < other.end && other.start < self.end
}
#[must_use]
pub const fn len(&self) -> u32 {
self.end.saturating_sub(self.start)
}
#[must_use]
pub const fn is_empty(&self) -> bool {
self.start == self.end
}
}
impl From<GpuMatch> for Match {
fn from(value: GpuMatch) -> Self {
Self {
pattern_id: value.0[0],
start: value.0[1],
end: value.0[2],
padding: value.0[3],
}
}
}