#[derive(Debug)] pub enum Format { Bold, Italics, BoldItalics, } #[derive(Debug)] pub struct TagEntry { pub start: i32, pub end: i32, pub style: Format, } /// State differentiator for tag entry bounds #[derive(Debug, PartialEq)] pub enum BoundState { /// Other is before Self BeforeOverlap, /// Other is after Self AfterOverlap, /// Other is inside Self FullOverlap, /// There is no overlap NoOverlap, } /// Indicate whether a section is in range of a target #[derive(Debug, PartialEq)] pub(crate) enum RangeState { Under, InRange, Over, } impl TagEntry { /// Create a new TagEntry pub(crate) fn new(start: i32, end: i32, style: Format) -> Self { Self { start, end, style } } fn test(start: i32, end: i32) -> Self { Self::new(start, end, Format::Bold) } pub(crate) fn in_range(&self, other: &TagEntry) -> RangeState { match (self.start, other.start, self.end, other.end) { (_s1, s2, e1, _e2) if e1 < s2 => RangeState::Under, (s1, s2, e1, e2) if e1 > s2 && s1 < e2 => RangeState::InRange, (s1, _s2, _e1, e2) if s1 > e2 => RangeState::Over, (_, _, _, _) => unreachable!(), } } /// Compare self bounds to other bounds pub(crate) fn check_bounds(&self, other: &TagEntry) -> BoundState { // s1/e1 = self, s2/e2 = other match (self.start, other.start, self.end, other.end) { (s1, s2, _e1, e2) if s2 < s1 && e2 >= s1 => BoundState::BeforeOverlap, (s1, s2, e1, e2) if s2 > s1 && s2 <= e1 && e2 > e1 => BoundState::AfterOverlap, (s1, s2, e1, e2) if s2 >= s1 && e2 <= e1 => BoundState::FullOverlap, _ => BoundState::NoOverlap, } } } #[test] fn tag_entry_test1() { let one = TagEntry::test(0, 9); let two = TagEntry::test(13, 18); let one_two_bound = one.check_bounds(&two); assert_eq!(one_two_bound, BoundState::NoOverlap); } #[test] fn tag_entry_test2() { let one = TagEntry::test(0, 9); let two = TagEntry::test(8, 12); let one_two_bound = one.check_bounds(&two); assert_eq!(one_two_bound, BoundState::AfterOverlap); } #[test] fn tag_entry_test3() { let one = TagEntry::test(8, 12); let two = TagEntry::test(4, 8); let one_two_bound = one.check_bounds(&two); assert_eq!(one_two_bound, BoundState::BeforeOverlap); } #[test] fn tag_entry_test4() { let one = TagEntry::test(9, 12); let two = TagEntry::test(4, 8); let one_two_bound = one.check_bounds(&two); assert_eq!(one_two_bound, BoundState::NoOverlap); }