@@ -110,6 +110,14 @@ impl<'bp> Attributes<'bp> {
110110 }
111111 }
112112
113+ /// Set an attribute value.
114+ /// ```
115+ /// # use anathema_value_resolver::{Attributes, ValueKind};
116+ ///
117+ /// let mut attributes = Attributes::empty();
118+ /// attributes.set("name", "Nonsense");
119+ /// attributes.get_as::<&str>("name").unwrap();
120+ /// ```
113121 pub fn set ( & mut self , key : & ' bp str , value : impl Into < ValueKind < ' bp > > ) {
114122 let key = ValueKey :: Attribute ( key) ;
115123 let value = value. into ( ) ;
@@ -123,13 +131,15 @@ impl<'bp> Attributes<'bp> {
123131 self . attribs . set ( key, value) ;
124132 }
125133
134+ #[ doc( hidden) ]
126135 pub fn insert_with < F > ( & mut self , key : ValueKey < ' bp > , f : F ) -> SmallIndex
127136 where
128137 F : FnMut ( SmallIndex ) -> Value < ' bp > ,
129138 {
130139 self . attribs . insert_with ( key, f)
131140 }
132141
142+ /// Remove a value from attributes
133143 pub fn remove ( & mut self , key : & ' bp str ) -> Option < Value < ' bp > > {
134144 let key = ValueKey :: Attribute ( key) ;
135145 self . attribs . remove ( & key)
@@ -146,13 +156,37 @@ impl<'bp> Attributes<'bp> {
146156 self . attribs . get ( key) . map ( |val| & val. kind )
147157 }
148158
159+ /// Get a value as a given type.
160+ /// If the value doesn't exist or can not be cast to the
161+ /// expected type `None` is returned.
162+ /// ```
163+ /// # use anathema_value_resolver::{Attributes, ValueKind};
164+ ///
165+ /// let mut attributes = Attributes::empty();
166+ /// attributes.set("num", 123);
167+ ///
168+ /// assert_eq!(attributes.get_as::<u32>("num").unwrap(), 123);
169+ /// assert_eq!(attributes.get_as::<i16>("num").unwrap(), 123);
170+ /// ```
149171 pub fn get_as < ' a , T > ( & ' a self , key : & str ) -> Option < T >
150172 where
151173 T : TryFrom < & ' a ValueKind < ' bp > > ,
152174 {
153175 self . attribs . get ( key) . and_then ( |val| ( & val. kind ) . try_into ( ) . ok ( ) )
154176 }
155177
178+ /// Iterate over values of a given type
179+ /// ```
180+ /// # use anathema_value_resolver::{Attributes, ValueKind};
181+ ///
182+ /// let mut attributes = Attributes::empty();
183+ /// let values =
184+ /// ValueKind::List([ValueKind::Int(1), ValueKind::Bool(true), ValueKind::Int(2)].into());
185+ /// attributes.set("mixed_list", values);
186+ ///
187+ /// let iter = attributes.iter_as::<u32>("mixed_list");
188+ /// assert_eq!(vec![1u32, 2], iter.collect::<Vec<_>>());
189+ /// ```
156190 pub fn iter_as < ' a , T > ( & ' a self , key : & str ) -> impl Iterator < Item = T >
157191 where
158192 T : TryFrom < & ' a ValueKind < ' bp > > ,
@@ -171,6 +205,9 @@ impl<'bp> Attributes<'bp> {
171205 . flatten ( )
172206 }
173207
208+ #[ doc( hidden) ]
209+ /// This should only be used internally by the widgets
210+ /// when updating a value.
174211 pub fn get_mut_with_index ( & mut self , index : SmallIndex ) -> Option < & mut Value < ' bp > > {
175212 self . attribs . get_mut_with_index ( index)
176213 }
@@ -192,18 +229,87 @@ impl<'bp> Attributes<'bp> {
192229
193230#[ cfg( test) ]
194231mod test {
232+ use anathema_state:: { Color , Hex } ;
233+
195234 use super :: * ;
196235
197- #[ test]
198- fn iter_as_int ( ) {
236+ fn attribs ( ) -> Attributes < ' static > {
199237 let mut attributes = Attributes :: empty ( ) ;
238+
200239 let values = ValueKind :: List ( [ ValueKind :: Int ( 1 ) , ValueKind :: Bool ( true ) , ValueKind :: Int ( 2 ) ] . into ( ) ) ;
201- attributes. set ( "a" , values) ;
240+ attributes. set ( "mixed_list" , values) ;
241+ attributes. set ( "num" , 123 ) ;
242+ attributes. set ( "static_str" , "static" ) ;
243+ attributes. set ( "string" , String :: from ( "string" ) ) ;
244+ attributes. set ( "hex" , Hex :: from ( ( 1 , 2 , 3 ) ) ) ;
245+ attributes. set ( "red" , Color :: Red ) ;
246+ attributes. set ( "float" , 1.23 ) ;
247+ attributes. set ( "bool" , true ) ;
248+ attributes. set ( "char" , 'a' ) ;
249+
250+ attributes
251+ }
252+
253+ #[ test]
254+ fn iter_as_type ( ) {
255+ let attributes = attribs ( ) ;
202256
203- let values = attributes. iter_as :: < u8 > ( "a " ) . collect :: < Vec < _ > > ( ) ;
257+ let values = attributes. iter_as :: < u8 > ( "mixed_list " ) . collect :: < Vec < _ > > ( ) ;
204258 assert_eq ! ( vec![ 1 , 2 ] , values) ;
205259
206- let values = attributes. iter_as :: < bool > ( "a " ) . collect :: < Vec < _ > > ( ) ;
260+ let values = attributes. iter_as :: < bool > ( "mixed_list " ) . collect :: < Vec < _ > > ( ) ;
207261 assert_eq ! ( vec![ true ] , values) ;
208262 }
263+
264+ #[ test]
265+ fn get_as_int ( ) {
266+ assert_eq ! ( 123 , attribs( ) . get_as:: <u8 >( "num" ) . unwrap( ) ) ;
267+ assert_eq ! ( 123 , attribs( ) . get_as:: <i8 >( "num" ) . unwrap( ) ) ;
268+ assert_eq ! ( 123 , attribs( ) . get_as:: <u16 >( "num" ) . unwrap( ) ) ;
269+ assert_eq ! ( 123 , attribs( ) . get_as:: <i16 >( "num" ) . unwrap( ) ) ;
270+ assert_eq ! ( 123 , attribs( ) . get_as:: <u32 >( "num" ) . unwrap( ) ) ;
271+ assert_eq ! ( 123 , attribs( ) . get_as:: <i32 >( "num" ) . unwrap( ) ) ;
272+ assert_eq ! ( 123 , attribs( ) . get_as:: <u64 >( "num" ) . unwrap( ) ) ;
273+ assert_eq ! ( 123 , attribs( ) . get_as:: <i64 >( "num" ) . unwrap( ) ) ;
274+ assert_eq ! ( 123 , attribs( ) . get_as:: <usize >( "num" ) . unwrap( ) ) ;
275+ assert_eq ! ( 123 , attribs( ) . get_as:: <isize >( "num" ) . unwrap( ) ) ;
276+ }
277+
278+ #[ test]
279+ fn get_as_strings ( ) {
280+ let attributes = attribs ( ) ;
281+ assert_eq ! ( "static" , attributes. get_as:: <& str >( "static_str" ) . unwrap( ) ) ;
282+ assert_eq ! ( "string" , attributes. get_as:: <& str >( "string" ) . unwrap( ) ) ;
283+ }
284+
285+ #[ test]
286+ fn get_as_hex ( ) {
287+ let attributes = attribs ( ) ;
288+ assert_eq ! ( Hex :: from( ( 1 , 2 , 3 ) ) , attributes. get_as:: <Hex >( "hex" ) . unwrap( ) ) ;
289+ }
290+
291+ #[ test]
292+ fn get_as_color ( ) {
293+ let attributes = attribs ( ) ;
294+ assert_eq ! ( Color :: Red , attributes. get_as:: <Color >( "red" ) . unwrap( ) ) ;
295+ }
296+
297+ #[ test]
298+ fn get_as_float ( ) {
299+ let attributes = attribs ( ) ;
300+ assert_eq ! ( 1.23 , attributes. get_as:: <f32 >( "float" ) . unwrap( ) ) ;
301+ assert_eq ! ( 1.23 , attributes. get_as:: <f64 >( "float" ) . unwrap( ) ) ;
302+ }
303+
304+ #[ test]
305+ fn get_as_bool ( ) {
306+ let attributes = attribs ( ) ;
307+ assert_eq ! ( true , attributes. get_as:: <bool >( "bool" ) . unwrap( ) ) ;
308+ }
309+
310+ #[ test]
311+ fn get_as_char ( ) {
312+ let attributes = attribs ( ) ;
313+ assert_eq ! ( 'a' , attributes. get_as:: <char >( "char" ) . unwrap( ) ) ;
314+ }
209315}
0 commit comments