@@ -2,44 +2,25 @@ use std::ops::Deref;
2
2
3
3
/// A set of modifiers.
4
4
///
5
- /// Beware: The [`Eq`] and [`Hash`] implementations are dependent on the ordering
6
- /// of the modifiers, in opposition to what a set would usually constitute.
7
- /// To test for set-wise equality, use [`iter`](Self::iter) and collect into a
8
- /// true set type like [`HashSet`](std::collections::HashSet).
5
+ /// Beware: The [`Eq`] and [`Hash`] implementations are dependent on the
6
+ /// ordering of the modifiers, in opposition to what a set would usually
7
+ /// constitute. To test for set-wise equality, use [`iter`](Self::iter) and
8
+ /// collect into a true set type like [`HashSet`](std::collections::HashSet).
9
9
#[ derive( Debug , Copy , Clone , PartialEq , Eq , Hash ) ]
10
- // note: the visibility needs to be `pub(crate)`,
11
- // since build.rs outputs `ModifierSet(...)`
12
- pub struct ModifierSet < S > ( pub ( crate ) S ) ;
13
-
14
- impl < S : Default > Default for ModifierSet < S > {
15
- /// Construct the default modifier set.
16
- ///
17
- /// This is typically the empty set,
18
- /// though the remark from [`Self::new_unchecked`] applies
19
- /// since `S::default()` could technically be anything.
20
- fn default ( ) -> Self {
21
- Self ( S :: default ( ) )
22
- }
23
- }
10
+ pub struct ModifierSet < S > (
11
+ // Note: the visibility needs to be `pub(crate)`, since build.rs outputs
12
+ // `ModifierSet(...)`.
13
+ pub ( crate ) S ,
14
+ ) ;
24
15
25
16
impl < S : Deref < Target = str > > ModifierSet < S > {
26
- /// Convert the underlying string to a slice.
27
- pub fn as_deref ( & self ) -> ModifierSet < & str > {
28
- ModifierSet ( & self . 0 )
29
- }
30
-
31
- /// Get the string of modifiers separated by `.`.
32
- pub fn as_str ( & self ) -> & str {
33
- & self . 0
34
- }
35
-
36
- /// Construct a modifier set from a string,
37
- /// where modifiers are separated by the character `.`.
17
+ /// Constructs a modifier set from a string, where modifiers are separated by
18
+ /// the character `.`.
38
19
///
39
20
/// It is not unsafe to use this function wrongly, but it can produce
40
- /// unexpected results down the line. Correct usage should ensure that
41
- /// `s` does not contain any empty modifiers (i.e. the sequence `..`)
42
- /// and that no modifier occurs twice.
21
+ /// unexpected results down the line. Correct usage should ensure that `s`
22
+ /// does not contain any empty modifiers (i.e. the sequence `..`) and that
23
+ /// no modifier occurs twice.
43
24
pub fn new_unchecked ( s : S ) -> Self {
44
25
Self ( s)
45
26
}
@@ -49,6 +30,16 @@ impl<S: Deref<Target = str>> ModifierSet<S> {
49
30
self . 0 . is_empty ( )
50
31
}
51
32
33
+ /// Gets the string of modifiers separated by `.`.
34
+ pub fn as_str ( & self ) -> & str {
35
+ & self . 0
36
+ }
37
+
38
+ /// Converts the underlying string to a slice.
39
+ pub fn as_deref ( & self ) -> ModifierSet < & str > {
40
+ ModifierSet ( & self . 0 )
41
+ }
42
+
52
43
/// Add a modifier to the set, without checking that it is a valid modifier.
53
44
///
54
45
/// It is not unsafe to use this method wrongly, but that can produce
@@ -64,7 +55,7 @@ impl<S: Deref<Target = str>> ModifierSet<S> {
64
55
self . 0 += m;
65
56
}
66
57
67
- /// Iterate over the list of modifiers in an arbitrary order.
58
+ /// Iterates over the list of modifiers in an arbitrary order.
68
59
pub fn iter ( & self ) -> impl Iterator < Item = & str > {
69
60
self . into_iter ( )
70
61
}
@@ -74,12 +65,7 @@ impl<S: Deref<Target = str>> ModifierSet<S> {
74
65
self . iter ( ) . any ( |lhs| lhs == m)
75
66
}
76
67
77
- /// Whether all modifiers in `self` are also present in `other`.
78
- pub fn is_subset ( & self , other : ModifierSet < & str > ) -> bool {
79
- self . iter ( ) . all ( |m| other. contains ( m) )
80
- }
81
-
82
- /// Find the best match from the list.
68
+ /// Finds the best match from the list.
83
69
///
84
70
/// To be considered a match, the modifier set must be a superset of
85
71
/// (or equal to) `self`. Among different matches, the best one is selected
@@ -115,6 +101,22 @@ impl<S: Deref<Target = str>> ModifierSet<S> {
115
101
116
102
best
117
103
}
104
+
105
+ /// Whether all modifiers in `self` are also present in `other`.
106
+ pub fn is_subset ( & self , other : ModifierSet < & str > ) -> bool {
107
+ self . iter ( ) . all ( |m| other. contains ( m) )
108
+ }
109
+ }
110
+
111
+ impl < S : Default > Default for ModifierSet < S > {
112
+ /// Constructs the default modifier set.
113
+ ///
114
+ /// This is typically the empty set, though the remark from
115
+ /// [`Self::new_unchecked`] applies since `S::default()` could technically
116
+ /// be anything.
117
+ fn default ( ) -> Self {
118
+ Self ( S :: default ( ) )
119
+ }
118
120
}
119
121
120
122
impl < ' a , S : Deref < Target = str > > IntoIterator for & ' a ModifierSet < S > {
@@ -180,34 +182,46 @@ mod tests {
180
182
fn best_match ( ) {
181
183
// 1. more modifiers in common with self
182
184
assert_eq ! (
183
- ModifierSet :: new_unchecked( "a.b" ) . best_match_in( [
184
- ( ModifierSet :: new_unchecked( "a.c" ) , 1 ) ,
185
- ( ModifierSet :: new_unchecked( "a.b" ) , 2 ) ,
186
- ] . into_iter( ) ) ,
185
+ ModifierSet :: new_unchecked( "a.b" ) . best_match_in(
186
+ [
187
+ ( ModifierSet :: new_unchecked( "a.c" ) , 1 ) ,
188
+ ( ModifierSet :: new_unchecked( "a.b" ) , 2 ) ,
189
+ ]
190
+ . into_iter( )
191
+ ) ,
187
192
Some ( 2 )
188
193
) ;
189
194
// 2. fewer modifiers in general
190
195
assert_eq ! (
191
- ModifierSet :: new_unchecked( "a" ) . best_match_in( [
192
- ( ModifierSet :: new_unchecked( "a" ) , 1 ) ,
193
- ( ModifierSet :: new_unchecked( "a.b" ) , 2 ) ,
194
- ] . into_iter( ) ) ,
196
+ ModifierSet :: new_unchecked( "a" ) . best_match_in(
197
+ [
198
+ ( ModifierSet :: new_unchecked( "a" ) , 1 ) ,
199
+ ( ModifierSet :: new_unchecked( "a.b" ) , 2 ) ,
200
+ ]
201
+ . into_iter( )
202
+ ) ,
195
203
Some ( 1 )
196
204
) ;
197
205
// the first rule takes priority over the second
198
206
assert_eq ! (
199
- ModifierSet :: new_unchecked( "a.b" ) . best_match_in( [
200
- ( ModifierSet :: new_unchecked( "a" ) , 1 ) ,
201
- ( ModifierSet :: new_unchecked( "a.b" ) , 2 ) ,
202
- ] . into_iter( ) ) ,
207
+ ModifierSet :: new_unchecked( "a.b" ) . best_match_in(
208
+ [
209
+ ( ModifierSet :: new_unchecked( "a" ) , 1 ) ,
210
+ ( ModifierSet :: new_unchecked( "a.b" ) , 2 ) ,
211
+ ]
212
+ . into_iter( )
213
+ ) ,
203
214
Some ( 2 )
204
215
) ;
205
216
// among multiple best matches, the first one is returned
206
217
assert_eq ! (
207
- ModifierSet :: default ( ) . best_match_in( [
208
- ( ModifierSet :: new_unchecked( "a" ) , 1 ) ,
209
- ( ModifierSet :: new_unchecked( "b" ) , 2 )
210
- ] . into_iter( ) ) ,
218
+ ModifierSet :: default ( ) . best_match_in(
219
+ [
220
+ ( ModifierSet :: new_unchecked( "a" ) , 1 ) ,
221
+ ( ModifierSet :: new_unchecked( "b" ) , 2 )
222
+ ]
223
+ . into_iter( )
224
+ ) ,
211
225
Some ( 1 )
212
226
) ;
213
227
}
0 commit comments