1#![feature(test)]
2#[macro_use]
17extern crate lazy_static;
18
19pub mod trim;
20
21pub trait Prune: IsNone {
22 fn prune(self) -> Self;
23}
24
25pub trait IsNone {
26 fn is_none(&self) -> bool {
27 false
28 }
29}
30
31impl<T> IsNone for Option<T> {
32 fn is_none(&self) -> bool {
33 self.is_none()
34 }
35}
36
37impl<T> Prune for Option<T>
38where
39 T: Prune + IsNone,
40{
41 fn prune(self) -> Self {
42 match self {
43 None => None,
44 Some(s) => {
45 let s = s.prune();
46 if s.is_none() {
47 None
48 } else {
49 Some(s)
50 }
51 }
52 }
53 }
54}
55
56impl<T> IsNone for Vec<T> {}
57
58impl<T> Prune for Vec<T>
59where
60 T: Prune,
61{
62 fn prune(self) -> Self {
63 self.into_iter().map(Prune::prune).collect()
64 }
65}
66
67#[derive(Debug)]
68pub enum Operator {
69 Trim,
70 TrimStart,
71 TrimEnd,
72 NoWhitespace,
73 Nested,
74 Custom(String),
75}
76
77macro_rules! tuple_impls {
78 ($(
79 ($(($idx:tt)),+)
80 )+) => {
81 tuple_impls! {
82 $(
83 ($((T, $idx)),+)
84 )+
85 }
86 };
87 ($(
88 ($(($T:ident, $idx:tt)),+)
89 )+) => {
90 $(
91 impl<T> IsNone for ($($T),+) {}
92
93 impl<T> Prune for ($($T),+) where T: Prune {
94 fn prune(self) -> Self {
95 (
96 $(self.$idx.prune()),+
97 )
98 }
99 }
100 )+
101 };
102}
103
104tuple_impls! {
105 ((0), (1))
106 ((0), (1), (2))
107 ((0), (1), (2), (3))
108 ((0), (1), (2), (3), (4))
109 ((0), (1), (2), (3), (4), (5))
110 ((0), (1), (2), (3), (4), (5), (6))
111 ((0), (1), (2), (3), (4), (5), (6), (7))
112 ((0), (1), (2), (3), (4), (5), (6), (7), (8))
113 ((0), (1), (2), (3), (4), (5), (6), (7), (8), (9))
114 ((0), (1), (2), (3), (4), (5), (6), (7), (8), (9), (10))
115 ((0), (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11))
116 ((0), (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12))
117}