3
3
4
4
use std:: collections:: { BTreeMap , BTreeSet } ;
5
5
6
- use crate :: cast:: { Downcast , DowncastFrom , DowncastTo , Upcast , UpcastFrom } ;
6
+ use crate :: cast:: { DowncastTo , Upcast , UpcastFrom , Upcasted } ;
7
7
8
8
pub type Map < K , V > = BTreeMap < K , V > ;
9
9
pub type Set < E > = BTreeSet < E > ;
@@ -58,6 +58,17 @@ macro_rules! seq {
58
58
59
59
}
60
60
61
+ pub trait VecExt < T > : Sized {
62
+ fn with_pushed ( self , other : T ) -> Self ;
63
+ }
64
+
65
+ impl < T : Ord + Clone > VecExt < T > for Vec < T > {
66
+ fn with_pushed ( mut self , other : T ) -> Self {
67
+ self . push ( other) ;
68
+ self
69
+ }
70
+ }
71
+
61
72
pub trait SetExt < T > : Sized {
62
73
fn split_first ( self ) -> Option < ( T , Self ) > ;
63
74
@@ -69,7 +80,9 @@ pub trait SetExt<T>: Sized {
69
80
impl < T : Ord + Clone > SetExt < T > for Set < T > {
70
81
fn split_first ( self ) -> Option < ( T , Set < T > ) > {
71
82
let mut iter = self . into_iter ( ) ;
72
- iter. next ( ) . map ( |e| ( e, iter. collect ( ) ) )
83
+ let e = iter. next ( ) ?;
84
+ let c = iter. collect ( ) ;
85
+ Some ( ( e, c) )
73
86
}
74
87
75
88
fn union_with ( mut self , other : Self ) -> Self {
@@ -106,60 +119,67 @@ impl<T> DowncastTo<()> for Vec<T> {
106
119
}
107
120
108
121
macro_rules! tuple_upcast {
109
- ( $( $name: ident) ,* ) => {
122
+ ( $coll: ident : $( $name: ident) ,* ) => {
123
+ /// Upcast from a tuple of iterable things into a collection.
124
+ /// Downcasting doesn't work, because how would we know how many
125
+ /// things to put in each collection? But see `Cons` below.
110
126
#[ allow( non_snake_case) ]
111
- impl <$( $name, ) * T > UpcastFrom <( $( $name, ) * ) > for Set <T >
127
+ impl <$( $name, ) * T > UpcastFrom <( $( $name, ) * ) > for $coll <T >
112
128
where
113
- $( $name: Upcast <Set <T >>, ) *
129
+ $( $name: IntoIterator + Clone , ) *
130
+ $( <$name as IntoIterator >:: Item : Upcast <T >, ) *
114
131
T : Ord + Clone ,
115
132
{
116
133
fn upcast_from( ( $( $name, ) * ) : ( $( $name, ) * ) ) -> Self {
117
134
let c = None . into_iter( ) ;
118
135
$(
119
- let $name: Set <T > = $name. upcast( ) ;
120
- let c = c. chain( $name) ;
136
+ let c = c. chain( $name. into_iter( ) . upcasted( ) ) ;
121
137
) *
122
138
c. collect( )
123
139
}
124
140
}
125
141
}
126
142
}
127
143
128
- tuple_upcast ! ( A , B ) ;
129
- tuple_upcast ! ( A , B , C ) ;
130
- tuple_upcast ! ( A , B , C , D ) ;
144
+ tuple_upcast ! ( Set : ) ;
145
+ tuple_upcast ! ( Set : A , B ) ;
146
+ tuple_upcast ! ( Set : A , B , C ) ;
147
+ tuple_upcast ! ( Set : A , B , C , D ) ;
148
+
149
+ tuple_upcast ! ( Vec : ) ;
150
+ tuple_upcast ! ( Vec : A , B ) ;
151
+ tuple_upcast ! ( Vec : A , B , C ) ;
152
+ tuple_upcast ! ( Vec : A , B , C , D ) ;
131
153
132
- impl < A , T > DowncastTo < ( A , Set < T > ) > for Set < T >
154
+ /// This type exists to be used in judgment functions.
155
+ /// You can downcast a `Vec` or `Set` to `Cons(head, tail)`
156
+ /// where `head` will be the first item in the collection
157
+ /// and tail will be a collection with the remaining items.
158
+ /// Both can also be downcast to `()` which matches an empty collection.
159
+ pub struct Cons < T , C > ( pub T , pub C ) ;
160
+
161
+ impl < T > DowncastTo < Cons < T , Set < T > > > for Set < T >
133
162
where
134
- A : DowncastFrom < T > ,
135
163
T : Ord + Clone ,
136
164
{
137
- fn downcast_to ( & self ) -> Option < ( A , Set < T > ) > {
165
+ fn downcast_to ( & self ) -> Option < Cons < T , Set < T > > > {
138
166
if self . is_empty ( ) {
139
167
None
140
168
} else {
141
169
let r = self . clone ( ) ;
142
170
let ( a, bs) = r. split_first ( ) . unwrap ( ) ;
143
- let a: A = a. downcast ( ) ?;
144
- Some ( ( a, bs) )
171
+ Some ( Cons ( a, bs) )
145
172
}
146
173
}
147
174
}
148
175
149
- impl < A , T > DowncastTo < ( A , Vec < T > ) > for Vec < T >
176
+ impl < T > DowncastTo < Cons < T , Vec < T > > > for Vec < T >
150
177
where
151
- A : DowncastFrom < T > ,
152
178
T : Ord + Clone ,
153
179
{
154
- fn downcast_to ( & self ) -> Option < ( A , Vec < T > ) > {
155
- if self . is_empty ( ) {
156
- None
157
- } else {
158
- let r = self . clone ( ) ;
159
- let ( a, bs) = r. split_first ( ) . unwrap ( ) ;
160
- let a: A = a. downcast ( ) ?;
161
- Some ( ( a, bs. to_vec ( ) ) )
162
- }
180
+ fn downcast_to ( & self ) -> Option < Cons < T , Vec < T > > > {
181
+ let ( a, bs) = self . split_first ( ) ?;
182
+ Some ( Cons ( a. clone ( ) , bs. to_vec ( ) ) )
163
183
}
164
184
}
165
185
0 commit comments