@@ -2,44 +2,25 @@ use std::ops::Deref;
22
33/// A set of modifiers.
44///
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).
99#[ 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+ ) ;
2415
2516impl < 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 `.`.
3819 ///
3920 /// 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.
4324 pub fn new_unchecked ( s : S ) -> Self {
4425 Self ( s)
4526 }
@@ -49,6 +30,16 @@ impl<S: Deref<Target = str>> ModifierSet<S> {
4930 self . 0 . is_empty ( )
5031 }
5132
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+
5243 /// Add a modifier to the set, without checking that it is a valid modifier.
5344 ///
5445 /// It is not unsafe to use this method wrongly, but that can produce
@@ -64,7 +55,7 @@ impl<S: Deref<Target = str>> ModifierSet<S> {
6455 self . 0 += m;
6556 }
6657
67- /// Iterate over the list of modifiers in an arbitrary order.
58+ /// Iterates over the list of modifiers in an arbitrary order.
6859 pub fn iter ( & self ) -> impl Iterator < Item = & str > {
6960 self . into_iter ( )
7061 }
@@ -74,12 +65,7 @@ impl<S: Deref<Target = str>> ModifierSet<S> {
7465 self . iter ( ) . any ( |lhs| lhs == m)
7566 }
7667
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.
8369 ///
8470 /// To be considered a match, the modifier set must be a superset of
8571 /// (or equal to) `self`. Among different matches, the best one is selected
@@ -115,6 +101,22 @@ impl<S: Deref<Target = str>> ModifierSet<S> {
115101
116102 best
117103 }
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+ }
118120}
119121
120122impl < ' a , S : Deref < Target = str > > IntoIterator for & ' a ModifierSet < S > {
@@ -180,34 +182,46 @@ mod tests {
180182 fn best_match ( ) {
181183 // 1. more modifiers in common with self
182184 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+ ) ,
187192 Some ( 2 )
188193 ) ;
189194 // 2. fewer modifiers in general
190195 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+ ) ,
195203 Some ( 1 )
196204 ) ;
197205 // the first rule takes priority over the second
198206 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+ ) ,
203214 Some ( 2 )
204215 ) ;
205216 // among multiple best matches, the first one is returned
206217 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+ ) ,
211225 Some ( 1 )
212226 ) ;
213227 }
0 commit comments