@@ -2,8 +2,10 @@ mod iter;
22
33pub use iter:: * ;
44
5- use crate :: rawvalue:: RawValue ;
6- use crate :: { PropertyKey , PropertyValue } ;
5+ use crate :: {
6+ string:: { SharedString , ToSharedString } ,
7+ PropertyKey , PropertyValue ,
8+ } ;
79
810/// Map of property names to property values.
911///
@@ -14,17 +16,11 @@ use crate::{PropertyKey, PropertyValue};
1416/// It's the caller's responsibility to ensure all keys and values are lowercased.
1517#[ derive( Clone , Default ) ]
1618pub struct Properties {
17- // Don't use Cow<'static, str> here because it's actually less-optimal
18- // for the vastly more-common case of reading parsed properties.
19- // It's a micro-optimization anyway.
2019 /// Key-value pairs, ordered from oldest to newest.
21- pairs : Vec < ( String , RawValue ) > ,
20+ pairs : Vec < ( SharedString , SharedString ) > ,
2221 /// Indices of `pairs`, ordered matching the key of the pair each index refers to.
2322 /// This part is what allows logarithmic lookups.
2423 idxes : Vec < usize > ,
25- // Unfortunately, we hand out `&mut RawValue`s all over the place,
26- // so "no empty RawValues in Properties" cannot be made an invariant
27- // without breaking API changes.
2824}
2925
3026// TODO: Deletion.
@@ -53,32 +49,42 @@ impl Properties {
5349 fn find_idx ( & self , key : & str ) -> Result < usize , usize > {
5450 self . idxes
5551 . as_slice ( )
56- . binary_search_by_key ( & key, |ki| self . pairs [ * ki] . 0 . as_str ( ) )
52+ . binary_search_by_key ( & key, |ki| & self . pairs [ * ki] . 0 )
5753 . map ( |idx| self . idxes [ idx] )
5854 }
5955
6056 /// Returns the unparsed "raw" value for the specified key.
61- ///
62- /// Does not test for the "unset" value. Use [`RawValue::filter_unset`].
63- pub fn get_raw_for_key ( & self , key : impl AsRef < str > ) -> & RawValue {
57+ pub fn get_raw_for_key ( & self , key : impl AsRef < str > ) -> Option < & SharedString > {
6458 self . find_idx ( key. as_ref ( ) )
6559 . ok ( )
66- . map_or ( & crate :: rawvalue :: UNSET , |idx| & self . pairs [ idx] . 1 )
60+ . map ( |idx| & self . pairs [ idx] . 1 )
6761 }
6862
6963 /// Returns the unparsed "raw" value for the specified property.
70- ///
71- /// Does not test for the "unset" value. Use [`RawValue::filter_unset`].
72- pub fn get_raw < T : PropertyKey > ( & self ) -> & RawValue {
64+ pub fn get_raw < T : PropertyKey > ( & self ) -> Option < & SharedString > {
7365 self . get_raw_for_key ( T :: key ( ) )
7466 }
7567
7668 /// Returns the parsed value for the specified property.
7769 ///
78- /// Does not test for the "unset" value if parsing fails. Use [`RawValue::filter_unset`].
79- pub fn get < T : PropertyKey + PropertyValue > ( & self ) -> Result < T , & RawValue > {
80- let retval = self . get_raw :: < T > ( ) ;
81- retval. parse :: < T > ( ) . or ( Err ( retval) )
70+ /// If `self` does not contain a key matching [`T::key()`][PropertyKey::key()],
71+ /// `Err(None)` is returned. Otherwise attempts to parse `T`
72+ /// out of the string value, and returns `Err(Some)` if the parse fails.
73+ pub fn get < T : PropertyKey + PropertyValue > (
74+ & self ,
75+ ) -> Result < T , Option < crate :: string:: ParseError < T :: Err > > > {
76+ // The Option is on the error because all PropertyValues implement Default and the default
77+ // should be assumed if the property is unset, meaning handling invalid values and unset
78+ // values can be done with just one unwrap_or_default.
79+ let Some ( raw) = self . get_raw :: < T > ( ) else {
80+ return Err ( None ) ;
81+ } ;
82+ raw. parse :: < T > ( ) . map_err ( |error| {
83+ Some ( crate :: string:: ParseError {
84+ error,
85+ string : raw. clone ( ) ,
86+ } )
87+ } )
8288 }
8389
8490 /// Returns an iterator over the key-value pairs.
@@ -103,36 +109,48 @@ impl Properties {
103109 IterMut ( self . pairs . iter_mut ( ) )
104110 }
105111
106- fn get_at_mut ( & mut self , idx : usize ) -> & mut RawValue {
112+ fn get_at_mut ( & mut self , idx : usize ) -> & mut SharedString {
113+ // PANIC: idx needs to be within the bounds of the pairs vec.
107114 & mut self . pairs . get_mut ( idx) . unwrap ( ) . 1
108115 }
109116
110- fn insert_at ( & mut self , idx : usize , key : String , val : RawValue ) {
117+ fn insert_at ( & mut self , idx : usize , key : SharedString , val : SharedString ) {
111118 self . idxes . insert ( idx, self . pairs . len ( ) ) ;
112119 self . pairs . push ( ( key, val) ) ;
113120 }
114121
115122 /// Sets the value for a specified key.
116- pub fn insert_raw_for_key ( & mut self , key : impl AsRef < str > , val : impl Into < RawValue > ) {
117- let key_str = key. as_ref ( ) ;
118- match self . find_idx ( key_str) {
119- Ok ( idx) => {
120- * self . get_at_mut ( idx) = val. into ( ) ;
123+ pub fn insert_raw_for_key ( & mut self , key : impl ToSharedString , val : impl ToSharedString ) {
124+ if let Some ( key_str) = key. try_as_str ( ) {
125+ match self . find_idx ( key_str) {
126+ Ok ( idx) => {
127+ * self . get_at_mut ( idx) = val. to_shared_string ( ) ;
128+ }
129+ Err ( idx) => {
130+ self . insert_at ( idx, key. to_shared_string ( ) , val. to_shared_string ( ) ) ;
131+ }
121132 }
122- Err ( idx) => {
123- self . insert_at ( idx, key_str. to_owned ( ) , val. into ( ) ) ;
133+ } else {
134+ let key = key. to_shared_string ( ) ;
135+ match self . find_idx ( & key) {
136+ Ok ( idx) => {
137+ * self . get_at_mut ( idx) = val. to_shared_string ( ) ;
138+ }
139+ Err ( idx) => {
140+ self . insert_at ( idx, key, val. to_shared_string ( ) ) ;
141+ }
124142 }
125143 }
126144 }
127145
128146 /// Sets the value for a specified property's key.
129- pub fn insert_raw < K : PropertyKey , V : Into < RawValue > > ( & mut self , val : V ) {
147+ pub fn insert_raw < K : PropertyKey , V : ToSharedString > ( & mut self , val : V ) {
130148 self . insert_raw_for_key ( K :: key ( ) , val)
131149 }
132150
133151 /// Inserts a specified property into the map.
134- pub fn insert < T : PropertyKey + Into < RawValue > > ( & mut self , prop : T ) {
135- self . insert_raw_for_key ( T :: key ( ) , prop. into ( ) )
152+ pub fn insert < T : PropertyKey + PropertyValue > ( & mut self , prop : T ) {
153+ self . insert_raw_for_key ( T :: key ( ) , prop)
136154 }
137155
138156 /// Attempts to add a new key-value pair to the map.
@@ -141,45 +159,49 @@ impl Properties {
141159 /// returns a mutable reference to the old value and does not update the map.
142160 pub fn try_insert_raw_for_key (
143161 & mut self ,
144- key : impl AsRef < str > ,
145- value : impl Into < RawValue > ,
146- ) -> Result < ( ) , & mut RawValue > {
147- let key_str = key. as_ref ( ) ;
148- #[ allow( clippy:: unit_arg) ]
149- match self . find_idx ( key_str) {
150- Ok ( idx) => {
151- let valref = self . get_at_mut ( idx) ;
152- if valref. is_unset ( ) {
153- * valref = value. into ( ) ;
162+ key : impl ToSharedString ,
163+ val : impl ToSharedString ,
164+ ) -> Result < ( ) , & mut SharedString > {
165+ if let Some ( key_str) = key. try_as_str ( ) {
166+ match self . find_idx ( key_str) {
167+ Ok ( idx) => Err ( self . get_at_mut ( idx) ) ,
168+ Err ( idx) => {
169+ self . insert_at ( idx, key. to_shared_string ( ) , val. to_shared_string ( ) ) ;
170+ Ok ( ( ) )
171+ }
172+ }
173+ } else {
174+ let key = key. to_shared_string ( ) ;
175+ match self . find_idx ( & key) {
176+ Ok ( idx) => Err ( self . get_at_mut ( idx) ) ,
177+ Err ( idx) => {
178+ self . insert_at ( idx, key, val. to_shared_string ( ) ) ;
154179 Ok ( ( ) )
155- } else {
156- Err ( valref)
157180 }
158181 }
159- Err ( idx) => Ok ( self . insert_at ( idx, key_str. to_owned ( ) , value. into ( ) ) ) ,
160182 }
161183 }
162184
163185 /// Attempts to add a new property to the map with a specified value.
164186 ///
165187 /// If the key was already associated with a value,
166188 /// returns a mutable reference to the old value and does not update the map.
167- pub fn try_insert_raw < K : PropertyKey , V : Into < RawValue > > (
189+ pub fn try_insert_raw < K : PropertyKey , V : ToSharedString > (
168190 & mut self ,
169191 val : V ,
170- ) -> Result < ( ) , & mut RawValue > {
192+ ) -> Result < ( ) , & mut SharedString > {
171193 self . try_insert_raw_for_key ( K :: key ( ) , val)
172194 }
173195
174196 /// Attempts to add a new property to the map.
175197 ///
176198 /// If the key was already associated with a value,
177199 /// returns a mutable reference to the old value and does not update the map.
178- pub fn try_insert < T : PropertyKey + Into < RawValue > > (
200+ pub fn try_insert < T : PropertyKey + PropertyValue > (
179201 & mut self ,
180202 prop : T ,
181- ) -> Result < ( ) , & mut RawValue > {
182- self . try_insert_raw_for_key ( T :: key ( ) , prop. into ( ) )
203+ ) -> Result < ( ) , & mut SharedString > {
204+ self . try_insert_raw_for_key ( T :: key ( ) , prop)
183205 }
184206
185207 /// Adds fallback values for certain common key-value pairs.
@@ -242,22 +264,22 @@ impl<'a> IntoIterator for &'a mut Properties {
242264 }
243265}
244266
245- impl < K : AsRef < str > , V : Into < RawValue > > FromIterator < ( K , V ) > for Properties {
267+ impl < K : Into < SharedString > , V : Into < SharedString > > FromIterator < ( K , V ) > for Properties {
246268 fn from_iter < T : IntoIterator < Item = ( K , V ) > > ( iter : T ) -> Self {
247269 let mut result = Properties :: new ( ) ;
248270 result. extend ( iter) ;
249271 result
250272 }
251273}
252274
253- impl < K : AsRef < str > , V : Into < RawValue > > Extend < ( K , V ) > for Properties {
275+ impl < K : Into < SharedString > , V : Into < SharedString > > Extend < ( K , V ) > for Properties {
254276 fn extend < T : IntoIterator < Item = ( K , V ) > > ( & mut self , iter : T ) {
255277 let iter = iter. into_iter ( ) ;
256278 let min_len = iter. size_hint ( ) . 0 ;
257279 self . pairs . reserve ( min_len) ;
258280 self . idxes . reserve ( min_len) ;
259281 for ( k, v) in iter {
260- let k = k. as_ref ( ) ;
282+ let k = k. into ( ) ;
261283 let v = v. into ( ) ;
262284 self . insert_raw_for_key ( k, v) ;
263285 }
0 commit comments