Skip to content

Commit 15e972d

Browse files
committed
attributes.set now supports adding owned strings, added missing u64 to try_from. more tests
1 parent c8d35e4 commit 15e972d

File tree

2 files changed

+119
-5
lines changed

2 files changed

+119
-5
lines changed

anathema-value-resolver/src/attributes.rs

Lines changed: 111 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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)]
194231
mod 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
}

anathema-value-resolver/src/value.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,12 @@ impl<'a> From<&'a str> for ValueKind<'a> {
385385
}
386386
}
387387

388+
impl From<String> for ValueKind<'_> {
389+
fn from(value: String) -> Self {
390+
ValueKind::Str(value.into())
391+
}
392+
}
393+
388394
// -----------------------------------------------------------------------------
389395
// - Try From -
390396
// -----------------------------------------------------------------------------
@@ -426,11 +432,13 @@ try_from_valuekind!(Hex, Hex);
426432
try_from_valuekind!(Color, Color);
427433

428434
try_from_valuekind_int!(usize, Int);
435+
try_from_valuekind_int!(isize, Int);
429436
try_from_valuekind_int!(i32, Int);
430437
try_from_valuekind_int!(f32, Float);
431438
try_from_valuekind_int!(i16, Int);
432439
try_from_valuekind_int!(i8, Int);
433440
try_from_valuekind_int!(u32, Int);
441+
try_from_valuekind_int!(u64, Int);
434442
try_from_valuekind_int!(u16, Int);
435443
try_from_valuekind_int!(u8, Int);
436444

0 commit comments

Comments
 (0)