1use kind::*;
10use ops::*;
11use std::ops::*;
12
13fn binary_map_unwrap_or<T, U, R, F>(x: &Optional<T>, y: &Optional<U>, default: R, f: F) -> R where
14 F: FnOnce(&T, &U) -> R
15{
16 if let Some(ref x) = x.as_ref() {
17 if let Some(ref y) = y.as_ref() {
18 return f(x, y)
19 }
20 }
21 default
22}
23
24fn binary_value_map_unwrap_or<T, U, R, F>(x: &Optional<T>, y: &U, default: R, f: F) -> R where
25 F: FnOnce(&T, &U) -> R
26{
27 x.as_ref().map_or(default, |x| f(x, y))
28}
29
30fn binary_value_map<T, U, R, F>(x: Optional<T>, y: U, f: F) -> Optional<R> where
31 F: FnOnce(T, U) -> R
32{
33 x.unwrap().map_or(Optional::empty(), |x|
34 Optional::singleton(f(x, y)))
35}
36
37fn binary_map<T, U, R, F>(x: Optional<T>, y: Optional<U>, f: F) -> Optional<R> where
38 F: FnOnce(T, U) -> R
39{
40 x.unwrap().map_or(Optional::empty(), |x|
41 y.unwrap().map_or(Optional::empty(), |y|
42 Optional::singleton(f(x, y))))
43}
44
45#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
46pub struct Optional<T>
47{
48 value: Option<T>
49}
50
51impl<T> Optional<T>
52{
53 pub fn wrap(value: Option<T>) -> Optional<T> {
54 Optional {
55 value: value
56 }
57 }
58
59 pub fn unwrap(self) -> Option<T> {
60 self.value
61 }
62}
63
64impl<T> Collection for Optional<T> {
65 type Item = T;
66}
67
68impl<T> Deref for Optional<T>
69{
70 type Target = Option<T>;
71
72 fn deref<'a>(&'a self) -> &'a Option<T> {
73 &self.value
74 }
75}
76
77impl<T> DerefMut for Optional<T>
78{
79 fn deref_mut<'a>(&'a mut self) -> &'a mut Option<T> {
80 &mut self.value
81 }
82}
83
84impl<T> Cardinality for Optional<T>
85{
86 type Size = usize;
87 fn size(&self) -> usize {
88 self.is_some() as usize
89 }
90}
91
92impl<T> Singleton for Optional<T>
93{
94 fn singleton(value: T) -> Optional<T> {
95 Optional::wrap(Some(value))
96 }
97}
98
99impl<T> Empty for Optional<T>
100{
101 fn empty() -> Optional<T> {
102 Optional::wrap(None)
103 }
104}
105
106impl<T> Intersection<Optional<T>> for Optional<T> where
107 T: Clone + PartialEq
108{
109 type Output = Optional<T>;
110
111 fn intersection(&self, other: &Optional<T>) -> Self::Output {
112 if self.is_empty() || other.is_empty() || self != other {
113 Optional::empty()
114 }
115 else {
116 self.clone()
117 }
118 }
119}
120
121impl<T> Intersection<T> for Optional<T> where
122 T: Clone + PartialEq
123{
124 type Output = Optional<T>;
125
126 fn intersection(&self, other: &T) -> Self::Output {
127 if self.is_empty() || self.as_ref().unwrap() != other {
128 Optional::empty()
129 }
130 else {
131 self.clone()
132 }
133 }
134}
135
136macro_rules! primitive_optional_intersection_operation
137{
138 ( $( $source:ty ),* ) =>
139 {$(
140 impl Intersection<Optional<$source>> for $source
141 {
142 type Output = Optional<$source>;
143
144 fn intersection(&self, other: &Optional<$source>) -> Self::Output {
145 other.intersection(self)
146 }
147 }
148 )*}
149}
150
151primitive_optional_intersection_operation!(i8,u8,i16,u16,i32,u32,i64,u64,isize,usize,f32,f64,bool,char);
152
153impl<T> Difference<Optional<T>> for Optional<T> where
154 T: Clone + PartialEq
155{
156 type Output = Optional<T>;
157
158 fn difference(&self, other: &Optional<T>) -> Self::Output {
159 if self.is_empty() || self == other {
160 Optional::empty()
161 }
162 else {
163 self.clone()
164 }
165 }
166}
167
168impl<T> Difference<T> for Optional<T> where
169 T: Clone + PartialEq
170{
171 type Output = Optional<T>;
172
173 fn difference(&self, other: &T) -> Self::Output {
174 if self.is_empty() || self.as_ref().unwrap() == other {
175 Optional::empty()
176 }
177 else {
178 self.clone()
179 }
180 }
181}
182
183macro_rules! primitive_optional_difference_operation
184{
185 ( $( $source:ty ),* ) =>
186 {$(
187 impl Difference<Optional<$source>> for $source
188 {
189 type Output = Optional<$source>;
190
191 fn difference(&self, other: &Optional<$source>) -> Self::Output {
192 if other.is_empty() || self != other.as_ref().unwrap() {
193 Optional::singleton(self.clone())
194 }
195 else {
196 Optional::empty()
197 }
198 }
199 }
200 )*}
201}
202
203primitive_optional_difference_operation!(i8,u8,i16,u16,i32,u32,i64,u64,isize,usize,f32,f64,bool,char);
204
205impl<T, U> Disjoint<Optional<U>> for Optional<T> where
206 T: Disjoint<U>
207{
208 fn is_disjoint(&self, other: &Optional<U>) -> bool {
209 self.is_empty() || other.is_empty() ||
210 self.as_ref().unwrap().is_disjoint(other.as_ref().unwrap())
211 }
212}
213
214impl<T, U> Disjoint<U> for Optional<T> where
215 T: Disjoint<U>,
216 U: GroundType
217{
218 fn is_disjoint(&self, other: &U) -> bool {
219 self.is_empty() ||
220 self.as_ref().unwrap().is_disjoint(other)
221 }
222}
223
224macro_rules! primitive_optional_disjoint_operation
225{
226 ( $( $source:ty ),* ) =>
227 {$(
228 impl<T> Disjoint<Optional<T>> for $source where
229 T: Disjoint<$source>
230 {
231 fn is_disjoint(&self, other: &Optional<T>) -> bool {
232 other.is_disjoint(self)
233 }
234 }
235 )*}
236}
237
238primitive_optional_disjoint_operation!(i8,u8,i16,u16,i32,u32,i64,u64,isize,usize,f32,f64,bool,char);
239
240impl<T> Contains for Optional<T> where
241 T: Eq
242{
243 fn contains(&self, value: &T) -> bool {
244 self.as_ref().map_or(false, |x| x == value)
245 }
246}
247
248impl<T> Subset<Optional<T>> for Optional<T> where
249 T: Subset
250{
251 fn is_subset(&self, other: &Optional<T>) -> bool {
252 if self.is_empty() { true }
253 else if other.is_empty() { false }
254 else {
255 self.as_ref().unwrap().is_subset(other.as_ref().unwrap())
256 }
257 }
258}
259
260impl<T> ProperSubset<Optional<T>> for Optional<T> where
261 T: Subset + PartialEq
262{
263 fn is_proper_subset(&self, other: &Optional<T>) -> bool {
264 self.is_subset(other) && self != other
265 }
266}
267
268impl<T, U> Overlap<Optional<U>> for Optional<T> where
269 T: Overlap<U>
270{
271 fn overlap(&self, other: &Optional<U>) -> bool {
272 binary_map_unwrap_or(self, other, false, T::overlap)
273 }
274}
275
276impl<T, U> Overlap<U> for Optional<T> where
277 T: Overlap<U>,
278 U: GroundType
279{
280 fn overlap(&self, other: &U) -> bool {
281 binary_value_map_unwrap_or(self, other, false, T::overlap)
282 }
283}
284
285macro_rules! primitive_optional_overlap_operation
286{
287 ( $( $source:ty ),* ) =>
288 {$(
289 impl<T> Overlap<Optional<T>> for $source where
290 T: Overlap<$source>
291 {
292 fn overlap(&self, other: &Optional<T>) -> bool {
293 other.overlap(self)
294 }
295 }
296 )*}
297}
298
299primitive_optional_overlap_operation!(i8,u8,i16,u16,i32,u32,i64,u64,isize,usize,f32,f64,bool,char);
300
301impl<T, U, R> Add<Optional<U>> for Optional<T> where
302 T: Add<U, Output=R>
303{
304 type Output = Optional<R>;
305
306 fn add(self, other: Optional<U>) -> Self::Output {
307 binary_map(self, other, T::add)
308 }
309}
310
311impl<T, U, R> Add<U> for Optional<T> where
312 T: Add<U, Output=R>,
313 U: GroundType
314{
315 type Output = Optional<R>;
316
317 fn add(self, other: U) -> Self::Output {
318 binary_value_map(self, other, T::add)
319 }
320}
321
322macro_rules! add_optional_arithmetics
323{
324 ( $( $source:ty ),* ) =>
325 {$(
326 impl<T, R> Add<Optional<T>> for $source where
327 T: Add<$source, Output=R>
328 {
329 type Output = Optional<R>;
330
331 fn add(self, rhs: Optional<T>) -> Self::Output {
332 rhs + self
333 }
334 }
335 )*}
336}
337
338add_optional_arithmetics!(i8,u8,i16,u16,i32,u32,i64,u64,isize,usize,f32,f64,bool,char);
339
340impl<T, U, R> Sub<Optional<U>> for Optional<T> where
341 T: Sub<U, Output=R>
342{
343 type Output = Optional<R>;
344
345 fn sub(self, other: Optional<U>) -> Self::Output {
346 binary_map(self, other, T::sub)
347 }
348}
349
350impl<T, U, R> Sub<U> for Optional<T> where
351 T: Sub<U, Output=R>,
352 U: GroundType
353{
354 type Output = Optional<R>;
355
356 fn sub(self, other: U) -> Self::Output {
357 binary_value_map(self, other, T::sub)
358 }
359}
360
361macro_rules! sub_optional_arithmetics
362{
363 ( $( $source:ty ),* ) =>
364 {$(
365 impl Sub<Optional<$source>> for $source
366 {
367 type Output = Optional<$source>;
368
369 fn sub(self, other: Optional<$source>) -> Self::Output {
370 binary_value_map(other, self, |x, y| y - x)
371 }
372 }
373 )*}
374}
375
376sub_optional_arithmetics!(i8,u8,i16,u16,i32,u32,i64,u64,isize,usize,f32,f64);
377
378impl<T, U, R> Mul<Optional<U>> for Optional<T> where
379 T: Mul<U, Output=R>
380{
381 type Output = Optional<R>;
382
383 fn mul(self, other: Optional<U>) -> Self::Output {
384 binary_map(self, other, T::mul)
385 }
386}
387
388impl<T, U, R> Mul<U> for Optional<T> where
389 T: Mul<U, Output=R>,
390 U: GroundType
391{
392 type Output = Optional<R>;
393
394 fn mul(self, other: U) -> Self::Output {
395 binary_value_map(self, other, T::mul)
396 }
397}
398
399macro_rules! mul_optional_arithmetics
400{
401 ( $( $source:ty ),* ) =>
402 {$(
403 impl<T, R> Mul<Optional<T>> for $source where
404 T: Mul<$source, Output=R>
405 {
406 type Output = Optional<R>;
407
408 fn mul(self, other: Optional<T>) -> Self::Output {
409 other.mul(self)
410 }
411 }
412 )*}
413}
414
415mul_optional_arithmetics!(i8,u8,i16,u16,i32,u32,i64,u64,isize,usize,f32,f64,bool,char);
416
417#[allow(non_upper_case_globals)]
418#[cfg(test)]
419mod tests {
420 use super::*;
421
422 const empty: Optional<i32> = Optional { value: None };
423 const zero: Optional<i32> = Optional { value: Some(0) };
424 const ten: Optional<i32> = Optional { value: Some(10) };
425
426 #[test]
427 fn cardinality_test() {
428 assert_eq!(empty.size(), 0);
429 assert_eq!(zero.size(), 1);
430 assert_eq!(ten.size(), 1);
431 assert!(empty.is_empty());
432 assert!(!empty.is_singleton());
433 assert!(!zero.is_empty());
434 assert!(zero.is_singleton());
435 }
436
437 #[test]
438 fn constructors_test() {
439 assert_eq!(empty, Empty::empty());
440 assert_eq!(zero, Singleton::singleton(0));
441 }
442
443 #[test]
444 fn intersection_test() {
445 let sym_cases = vec![
446 (empty, empty, empty),
447 (empty, zero, empty),
448 (zero, zero, zero),
449 (zero, ten, empty),
450 (ten, ten, ten)
451 ];
452
453 for (x,y,r) in sym_cases.into_iter() {
454 assert!(x.intersection(&y) == r, "{:?} intersection {:?} is not equal to {:?}", x, y, r);
455 assert!(y.intersection(&x) == r, "{:?} intersection {:?} is not equal to {:?}", y, x, r);
456 }
457 }
458
459 #[test]
460 fn difference_test() {
461 let cases = vec![
462 (empty, empty, empty, empty),
463 (empty, zero, empty, zero),
464 (zero, zero, empty, empty),
465 (zero, ten, zero, ten),
466 (ten, ten, empty, empty)
467 ];
468
469 for (x,y,r1,r2) in cases.into_iter() {
470 assert!(x.difference(&y) == r1, "{:?} difference {:?} is not equal to {:?}", x, y, r1);
471 assert!(y.difference(&x) == r2, "{:?} difference {:?} is not equal to {:?}", y, x, r2);
472 }
473 }
474
475 #[test]
476 fn intersection_value_test() {
477 let sym_cases = vec![
478 (empty, 0, empty),
479 (empty, 1, empty),
480 (zero, 0, zero),
481 (zero, 1, empty),
482 (ten, 10, ten)
483 ];
484
485 for (x,y,r) in sym_cases.into_iter() {
486 assert!(x.intersection(&y) == r, "{:?} intersection {:?} is not equal to {:?}", x, y, r);
487 assert!(y.intersection(&x) == r, "{:?} intersection {:?} is not equal to {:?}", y, x, r);
488 }
489 }
490
491 #[test]
492 fn difference_value_test() {
493 let cases = vec![
494 (empty, 0, empty, zero),
495 (zero, 0, empty, empty),
496 (zero, 10, zero, ten),
497 (ten, 10, empty, empty)
498 ];
499
500 for (x,y,r1,r2) in cases.into_iter() {
501 assert!(x.difference(&y) == r1, "{:?} difference {:?} is not equal to {:?}", x, y, r1);
502 assert!(y.difference(&x) == r2, "{:?} difference {:?} is not equal to {:?}", y, x, r2);
503 }
504 }
505
506 #[test]
507 fn is_disjoint_and_overlap_test() {
508 let sym_cases = vec![
509 (empty, empty, true),
510 (empty, zero, true),
511 (zero, zero, false),
512 (zero, ten, true),
513 (ten, ten, false)
514 ];
515
516 for (x,y,r) in sym_cases.into_iter() {
517 assert!(x.is_disjoint(&y) == r, "{:?} disjoint {:?} is not equal to {:?}", x, y, r);
518 assert!(y.is_disjoint(&x) == r, "{:?} disjoint {:?} is not equal to {:?}", y, x, r);
519 assert!(x.overlap(&y) == !r, "{:?} overlap {:?} is not equal to {:?}", x, y, !r);
520 assert!(y.overlap(&x) == !r, "{:?} overlap {:?} is not equal to {:?}", y, x, !r);
521 }
522 }
523
524 #[test]
525 fn contains_test() {
526 let cases = vec![
527 (empty, 0, false),
528 (empty, 1, false),
529 (zero, 0, true),
530 (zero, 1, false),
531 (ten, 9, false),
532 (ten, 10, true)
533 ];
534
535 for (x,y,r) in cases.into_iter() {
536 assert!(x.contains(&y) == r, "{:?} contains {:?} is not equal to {:?}", x, y, r);
537 }
538 }
539
540 #[test]
541 fn subset_test() {
542 let cases = vec![
543 (empty, empty, true, true),
544 (empty, zero, true, false),
545 (zero, zero, true, true),
546 (zero, ten, false, false),
547 (ten, ten, true, true)
548 ];
549
550 for (x,y,r1,r2) in cases.into_iter() {
551 assert!(x.is_subset(&y) == r1, "{:?} subset {:?} is not equal to {:?}", x, y, r1);
552 assert!(y.is_subset(&x) == r2, "{:?} subset {:?} is not equal to {:?}", y, x, r2);
553 }
554 }
555
556 #[test]
557 fn proper_subset_test() {
558 let cases = vec![
559 (empty, empty, false, false),
560 (empty, zero, true, false),
561 (zero, zero, false, false),
562 (zero, ten, false, false),
563 (ten, ten, false, false)
564 ];
565
566 for (x,y,r1,r2) in cases.into_iter() {
567 assert!(x.is_proper_subset(&y) == r1, "{:?} proper_subset {:?} is not equal to {:?}", x, y, r1);
568 assert!(y.is_proper_subset(&x) == r2, "{:?} proper_subset {:?} is not equal to {:?}", y, x, r2);
569 }
570 }
571
572 #[test]
573 fn arithmetics_tests() {
574 let twenty = Optional::singleton(20);
575 let one_hundred = Optional::singleton(100);
576 let cases = vec![
577 (empty, empty, empty, empty, empty),
579 (empty, ten, empty, empty, empty),
580 (ten, empty, empty, empty, empty),
581 (ten, zero, ten, ten, zero),
582 (ten, ten, twenty,zero, one_hundred)
583 ];
584 for (x,y,add,sub,mul) in cases.into_iter() {
585 assert!(x + y == add, "{:?} + {:?} is not equal to {:?}", x, y, add);
586 assert!(x - y == sub, "{:?} - {:?} is not equal to {:?}", x, y, sub);
587 assert!(x * y == mul, "{:?} * {:?} is not equal to {:?}", x, y, mul);
588 }
589 }
590}