ranges/generic_range/
difference.rs1use core::ops::Sub;
2
3use crate::{Arrangement, Domain, GenericRange, OperationResult};
4
5impl<T: Domain> GenericRange<T> {
6 pub fn difference(self, other: Self) -> OperationResult<T> {
31 match self.arrangement(&other) {
32 Arrangement::Disjoint { .. } | Arrangement::Touching { .. } => OperationResult::Single(self),
33 Arrangement::Overlapping { self_less: true, .. }
34 | Arrangement::Ending {
35 self_shorter: false, ..
36 } => OperationResult::Single(Self {
37 start: self.start,
38 end: Self::invert_border(other.start),
39 }),
40 Arrangement::Overlapping { self_less: false, .. }
41 | Arrangement::Starting {
42 self_shorter: false, ..
43 } => OperationResult::Single(Self {
44 start: Self::invert_border(other.end),
45 end: self.end,
46 }),
47 Arrangement::Containing { self_shorter: true }
48 | Arrangement::Starting { self_shorter: true, .. }
49 | Arrangement::Ending { self_shorter: true, .. }
50 | Arrangement::Equal => OperationResult::Empty,
51 Arrangement::Containing { self_shorter: false } => OperationResult::Double(
52 Self {
53 start: self.start,
54 end: Self::invert_border(other.start),
55 },
56 Self {
57 start: Self::invert_border(other.end),
58 end: self.end,
59 },
60 ),
61 Arrangement::Empty {
62 self_empty: Some(true) | None,
63 } => {
64 OperationResult::Empty
66 }
67 Arrangement::Empty {
68 self_empty: Some(false),
69 } => {
70 OperationResult::Single(self)
72 }
73 }
74 }
75}
76
77impl<T, I> Sub<I> for GenericRange<T>
79where
80 I: Into<GenericRange<T>>,
81 T: Domain,
82{
83 type Output = OperationResult<T>;
84
85 #[must_use]
86 fn sub(self, rhs: I) -> Self::Output {
87 self.difference(rhs.into())
88 }
89}
90
91#[cfg(test)]
92mod tests {
93 use crate::{GenericRange, OperationResult};
94
95 #[test]
96 fn disjoint() {
97 let range = GenericRange::new_less_than(5);
98 let range2 = GenericRange::new_at_least(10);
99
100 assert_eq!(range.difference(range2), OperationResult::Single(range));
101 assert_eq!(range2.difference(range), OperationResult::Single(range2));
102
103 assert_eq!(range - range2, OperationResult::Single(range));
104 assert_eq!(range2 - range, OperationResult::Single(range2));
105 }
106
107 #[test]
108 fn touching() {
109 let range = GenericRange::from(0..10);
110 let range2 = GenericRange::from(10..=20);
111
112 assert_eq!(range.difference(range2), OperationResult::Single(range));
113 assert_eq!(range2.difference(range), OperationResult::Single(range2));
114
115 assert_eq!(range - range2, OperationResult::Single(range));
116 assert_eq!(range2 - range, OperationResult::Single(range2));
117 }
118
119 #[test]
120 fn overlapping() {
121 let range = GenericRange::from(0..10);
122 let range2 = GenericRange::from(5..=15);
123
124 assert_eq!(
125 range.difference(range2),
126 OperationResult::Single(GenericRange::from(0..5))
127 );
128 assert_eq!(
129 range2.difference(range),
130 OperationResult::Single(GenericRange::from(10..=15))
131 );
132
133 assert_eq!(range - range2, OperationResult::Single(GenericRange::from(0..5)));
134 assert_eq!(range2 - range, OperationResult::Single(GenericRange::from(10..=15)));
135 }
136
137 #[test]
138 fn containing() {
139 let range = GenericRange::from(0..10);
140 let range2 = GenericRange::from(5..=8);
141
142 assert_eq!(
143 range.difference(range2),
144 OperationResult::Double(GenericRange::from(0..5), GenericRange::new_open(8, 10))
145 );
146 assert_eq!(range2.difference(range), OperationResult::Empty);
147
148 assert_eq!(
149 range - range2,
150 OperationResult::Double(GenericRange::from(0..5), GenericRange::new_open(8, 10))
151 );
152 assert_eq!(range2 - range, OperationResult::Empty);
153 }
154
155 #[test]
156 fn starting() {
157 let range = GenericRange::from(0..10);
158 let range2 = GenericRange::from(0..=8);
159
160 assert_eq!(
161 range.difference(range2),
162 OperationResult::Single(GenericRange::new_open(8, 10))
163 );
164 assert_eq!(range2.difference(range), OperationResult::Empty);
165
166 assert_eq!(range - range2, OperationResult::Single(GenericRange::new_open(8, 10)));
167 assert_eq!(range2 - range, OperationResult::Empty);
168 }
169
170 #[test]
171 fn ending() {
172 let range = GenericRange::from(3..=10);
173 let range2 = GenericRange::from(5..=10);
174
175 assert_eq!(
176 range.difference(range2),
177 OperationResult::Single(GenericRange::from(3..5))
178 );
179 assert_eq!(range2.difference(range), OperationResult::Empty);
180
181 assert_eq!(range - range2, OperationResult::Single(GenericRange::from(3..5)));
182 assert_eq!(range2 - range, OperationResult::Empty);
183 }
184
185 #[test]
186 fn equal() {
187 let range = GenericRange::from(5..=10);
188 let range2 = range;
189
190 assert_eq!(range.difference(range2), OperationResult::Empty);
191 assert_eq!(range2.difference(range), OperationResult::Empty);
192
193 assert_eq!(range - range2, OperationResult::Empty);
194 assert_eq!(range2 - range, OperationResult::Empty);
195 }
196}