#![no_std]
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct SectorMap {
pub input_start: usize,
pub input_end: usize,
pub sector_start: usize,
pub sector_end: usize,
pub sector_index: usize,
}
pub struct SectorizeIter {
sector_size: usize,
input_start: usize,
input_len: usize,
s: usize,
}
impl SectorizeIter {
pub fn new(sector_size: usize, input_start: usize, input_len: usize) -> Self {
Self {
sector_size,
input_start,
input_len,
s: input_start / sector_size,
}
}
}
impl Iterator for SectorizeIter {
type Item = SectorMap;
fn next(&mut self) -> Option<Self::Item> {
let idx = self.s;
let sector_start = self.s * self.sector_size;
self.s += 1;
let sector_end = self.s * self.sector_size;
let overlap_start = sector_start.max(self.input_start);
let overlap_end = sector_end.min(self.input_start + self.input_len);
if overlap_start >= overlap_end {
return None;
}
Some(SectorMap {
input_start: overlap_start - self.input_start,
input_end: overlap_end - self.input_start,
sector_start: overlap_start - sector_start,
sector_end: overlap_end - sector_start,
sector_index: idx,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn basic_case() {
let mut iter = SectorizeIter::new(4, 3, 10);
assert_eq!(
SectorMap {
input_start: 0,
input_end: 1,
sector_start: 3,
sector_end: 4,
sector_index: 0
},
iter.next().unwrap()
);
assert_eq!(
SectorMap {
input_start: 1,
input_end: 5,
sector_start: 0,
sector_end: 4,
sector_index: 1
},
iter.next().unwrap()
);
assert_eq!(
SectorMap {
input_start: 5,
input_end: 9,
sector_start: 0,
sector_end: 4,
sector_index: 2
},
iter.next().unwrap()
);
assert_eq!(
SectorMap {
input_start: 9,
input_end: 10,
sector_start: 0,
sector_end: 1,
sector_index: 3
},
iter.next().unwrap()
);
assert_eq!(None, iter.next());
}
#[test]
fn matching_perfectly() {
let mut iter = SectorizeIter::new(4, 0, 12);
assert_eq!(
SectorMap {
input_start: 0,
input_end: 4,
sector_start: 0,
sector_end: 4,
sector_index: 0
},
iter.next().unwrap()
);
assert_eq!(
SectorMap {
input_start: 4,
input_end: 8,
sector_start: 0,
sector_end: 4,
sector_index: 1
},
iter.next().unwrap()
);
assert_eq!(
SectorMap {
input_start: 8,
input_end: 12,
sector_start: 0,
sector_end: 4,
sector_index: 2
},
iter.next().unwrap()
);
assert_eq!(None, iter.next());
}
#[test]
fn start_higher_sector() {
let mut iter = SectorizeIter::new(4, 11, 10);
assert_eq!(
SectorMap {
input_start: 0,
input_end: 1,
sector_start: 3,
sector_end: 4,
sector_index: 2
},
iter.next().unwrap()
);
assert_eq!(
SectorMap {
input_start: 1,
input_end: 5,
sector_start: 0,
sector_end: 4,
sector_index: 3
},
iter.next().unwrap()
);
assert_eq!(
SectorMap {
input_start: 5,
input_end: 9,
sector_start: 0,
sector_end: 4,
sector_index: 4
},
iter.next().unwrap()
);
assert_eq!(
SectorMap {
input_start: 9,
input_end: 10,
sector_start: 0,
sector_end: 1,
sector_index: 5
},
iter.next().unwrap()
);
assert_eq!(None, iter.next());
}
}