Fix all set operations on selections

This commit is contained in:
Austen Adler 2022-08-09 18:18:06 -04:00
parent d10a02573b
commit 780ea7c2f9

View File

@ -111,15 +111,33 @@ impl SelectionDesc {
// Set a and b to the leftmost and rightmost selection // Set a and b to the leftmost and rightmost selection
let (a, b) = (min(self, other).sort(), max(self, other).sort()); let (a, b) = (min(self, other).sort(), max(self, other).sort());
if a.contains(&b.left) match (b.contains(&a.left), b.contains(&a.right), a.contains(&b)) {
|| a.contains(&b.right) (false, false, false) => {
|| b.contains(&a.left) // There is no intersection
|| b.contains(&a.right) None
{ }
// Some(Self {}) (true, true, _) => {
None // a is contained by b
} else { Some(a)
None }
(false, false, true) => {
// b is contained and it does not intersect with left or right
Some(b)
}
(true, false, _) => {
// Only a's left is contained
Some(Self {
left: a.left,
right: b.right,
})
}
(false, true, _) => {
// Only a's right is contained
Some(Self {
left: b.left,
right: a.right,
})
}
} }
} }
@ -127,36 +145,42 @@ impl SelectionDesc {
pub fn partial_union(&self, other: &Self) -> Option<Self> { pub fn partial_union(&self, other: &Self) -> Option<Self> {
// Set a and b to the leftmost and rightmost selection // Set a and b to the leftmost and rightmost selection
let (a, b) = (min(self, other).sort(), max(self, other).sort()); let (a, b) = (min(self, other).sort(), max(self, other).sort());
eprintln!("Partial union args: a: {a:#?}, b: {b:#?}");
eprintln!( match (b.contains(&a.left), b.contains(&a.right), a.contains(&b)) {
"Checking if {} contains {}: {}", (false, false, false) => {
a, // There is no intersection
b.left, // TODO: Do the weird boundary ones
a.contains(&b.left) // None
); if a.right.row == b.left.row && a.right.col == b.left.col.saturating_sub(1) {
eprintln!( Some(Self {
"Checking if {} contains {}: {}", left: a.left,right: b.right
b, })
a.right, } else {
b.contains(&a.right) None
); }
}
// Either the left side of b is contained b a, or (true, true, _) => {
// This will not work when the right side of a is the end of line and the left side of b is beginning of line // a is contained by b
// This is because selection descs do not know when a selection desc is at the end of a line Some(b)
if a.contains(&b.left) || b.contains(&a.right) }
// If b's left is one col off from a's right (false, false, true) => {
// || (a.right.row == b_left.row && a.right.col == b.left.col.saturating_sub(1)) // b is contained and it does not intersect with left or right
// Or b's right is Some(a)
// || (a.left.row == b_left.row && a.left.col == b.right.col.saturating_sub(1)) }
{ (true, false, _) => {
Some(SelectionDesc { // Only a's left is contained
left: min(a.left, b.left), Some(Self {
right: max(a.right, b.right), left: b.left,
}) right: a.right,
} else { })
None }
(false, true, _) => {
// Only a's right is contained
Some(Self {
left: a.left,
right: b.right,
})
}
} }
} }
@ -170,16 +194,16 @@ impl SelectionDesc {
sorted_b.contains(&sorted_self.right), sorted_b.contains(&sorted_self.right),
sorted_self.contains(&sorted_b), sorted_self.contains(&sorted_b),
) { ) {
(true, true, _) => {
// sorted_self is contained by sorted_b
MaybeSplit::Nothing
}
(false, false, false) => { (false, false, false) => {
// There is no intersection // There is no intersection
MaybeSplit::Just(sorted_self) MaybeSplit::Just(sorted_self)
} }
(true, true, _) => {
// sorted_self is contained by sorted_b
MaybeSplit::Nothing
}
(false, false, true) => { (false, false, true) => {
// B is contained and it does not intersect with left or right // sorted_b is contained and it does not intersect with left or right
MaybeSplit::JustTwo( MaybeSplit::JustTwo(
Self { Self {
left: sorted_self.left, left: sorted_self.left,
@ -747,6 +771,81 @@ mod test {
assert!(!SD.contains(&sdr!(10, 0, 18, 9))); assert!(!SD.contains(&sdr!(10, 0, 18, 9)));
} }
#[test]
fn test_intersect() {
// Testing a+b
// 01234567
// a: ^_^
// b: ^____^
mixed_test!((1, 3), intersect, (0, 5), Some(sd!(1, 3)));
// 01234567
// a: ^__^
// b: ^____^
mixed_test!((0, 3), intersect, (0, 5), Some(sd!(0, 3)));
// 01234567
// a: ^___^
// b: ^___^
mixed_test!((1, 5), intersect, (1, 5), Some(sd!(1, 5)));
// 01234567
// a: ^_____^
// b: ^____^
mixed_test!((0, 6), intersect, (0, 5), Some(sd!(0, 5)));
// 01234567
// a: ^____^
// b: ^____^
mixed_test!((1, 6), intersect, (0, 5), Some(sd!(1, 5)));
// 01234567
// a: ^____^
// b: ^____^
mixed_test!((0, 5), intersect, (1, 6), Some(sd!(1, 5)));
// 01234567
// a: ^______^
// b: ^____^
mixed_test!((0, 7), intersect, (1, 6), Some(sd!(1, 6)));
// 01234567
// a: ^
// b: ^____^
mixed_test!((3, 3), intersect, (0, 5), Some(sd!(3, 3)));
// 01234567
// a: ^
// b: ^____^
mixed_test!((0, 0), intersect, (0, 5), Some(sd!(0, 0)));
// 01234567
// a: ^
// b: ^____^
mixed_test!((0, 0), intersect, (1, 6), None);
// 01234567
// a: ^
// b: ^____^
mixed_test!((5, 5), intersect, (0, 5), Some(sd!(5, 5)));
// 01234567
// a: ^
// b: ^____^
mixed_test!((6, 6), intersect, (0, 5), None);
// 01234567
// a: ^
// b: ^____^
mixed_test!((7, 7), intersect, (0, 5), None);
// 01234567
// a: ^
// b: ^____^
mixed_test!((0, 0), intersect, (2, 7), None);
}
#[test] #[test]
fn test_partial_union() { fn test_partial_union() {
// Testing a+b // Testing a+b