Skip to content

Commit ebe2da6

Browse files
committed
wip
1 parent 1647de9 commit ebe2da6

15 files changed

Lines changed: 200 additions & 93 deletions

File tree

anathema-core/src/attributes.rs

Lines changed: 126 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
//! Element attributes
22
use std::borrow::Borrow;
3-
// #![deny(missing_docs)]
43
use std::ops::Deref;
54

65
use anathema_store::remotecell::RemoteCell;
@@ -10,12 +9,13 @@ use anathema_store::smallmap::{SmallIndex, SmallMap};
109
use crate::runtime::elements::ElementId;
1110
use crate::runtime::eval::values::TemplateValue;
1211

12+
// All attributes for all elements
1313
#[derive(Debug)]
14-
pub struct AllAttributes<'bp> {
14+
pub(crate) struct AttributeRegistry<'bp> {
1515
attributes: SecondaryMap<ElementId, Attributes<'bp>>,
1616
}
1717

18-
impl<'bp> AllAttributes<'bp> {
18+
impl<'bp> AttributeRegistry<'bp> {
1919
pub(crate) fn empty() -> Self {
2020
Self {
2121
attributes: SecondaryMap::empty(),
@@ -27,14 +27,15 @@ impl<'bp> AllAttributes<'bp> {
2727
}
2828
}
2929

30+
// The access key for attributes.
3031
#[derive(Debug, Copy, Clone, PartialEq)]
31-
pub enum ValueKey<'bp> {
32+
pub(crate) enum ValueKey<'bp> {
3233
Value,
3334
Attribute(&'bp str),
3435
}
3536

3637
impl ValueKey<'_> {
37-
pub fn as_str(&self) -> &str {
38+
fn as_str(&self) -> &str {
3839
match self {
3940
ValueKey::Value => "[value]",
4041
ValueKey::Attribute(name) => name,
@@ -48,12 +49,20 @@ impl Borrow<str> for ValueKey<'_> {
4849
}
4950
}
5051

52+
/// Element attributes
53+
///
54+
/// ```text
55+
/// text [foreground: "red", bold: true] "hello world"
56+
/// ```
57+
///
58+
/// Attributes can be set / replaced or read, but never mutated because of the `RemoteCell`.
5159
#[derive(Debug)]
5260
pub struct Attributes<'bp> {
5361
inner: SmallMap<ValueKey<'bp>, RemoteCell<TemplateValue<'bp>>>,
5462
}
5563

5664
impl<'bp> Attributes<'bp> {
65+
/// Create a new instance of en empty set of attributes
5766
pub fn empty() -> Self {
5867
Self {
5968
inner: SmallMap::empty(),
@@ -102,8 +111,9 @@ impl<'bp> Attributes<'bp> {
102111
self.inner.remove(key)
103112
}
104113

105-
pub(crate) fn get(&self, key: &str) -> Option<&RemoteCell<TemplateValue<'bp>>> {
106-
self.inner.get(key)
114+
pub(crate) fn get(&self, key: &str) -> Option<&TemplateValue<'bp>> {
115+
let val = self.inner.get(key)?;
116+
Some(&*val)
107117
}
108118

109119
/// Get a value as a given type.
@@ -129,6 +139,7 @@ impl<'bp> Attributes<'bp> {
129139
pub fn value_as<'a, T>(&'a self) -> Option<T>
130140
where
131141
T: TryFrom<&'a TemplateValue<'bp>>,
142+
T: ?Sized,
132143
{
133144
self.inner
134145
.get(&ValueKey::Value)
@@ -177,12 +188,116 @@ impl<'bp> Attributes<'bp> {
177188
.flatten()
178189
}
179190

180-
/// Iterate over attributes.
181-
/// This will skip the value
182-
pub fn iter(&self) -> impl Iterator<Item = (&ValueKey<'_>, &RemoteCell<TemplateValue<'bp>>)> {
191+
/// Iterator of keys and values.
192+
/// NOTE: This will skip the value
193+
pub fn iter(&self) -> impl Iterator<Item = (&str, &TemplateValue<'bp>)> {
183194
self.inner.iter().filter_map(|(key, val)| match key {
184195
ValueKey::Value => None,
185-
ValueKey::Attribute(_) => Some((key, &*val)),
196+
&ValueKey::Attribute(key) => Some((key, &**val)),
186197
})
187198
}
199+
200+
/// Iterator of keys
201+
pub fn iter_keys(&self) -> impl Iterator<Item = &str> {
202+
self.inner.iter().filter_map(|(key, _)| match key {
203+
ValueKey::Value => None,
204+
&ValueKey::Attribute(key) => Some(key),
205+
})
206+
}
207+
208+
/// Iterator of values
209+
pub fn iter_values(&self) -> impl Iterator<Item = &TemplateValue<'bp>> {
210+
self.inner.iter().filter_map(|(key, value)| match key {
211+
ValueKey::Value => None,
212+
&ValueKey::Attribute(_) => Some(&**value),
213+
})
214+
}
215+
}
216+
217+
#[cfg(test)]
218+
mod test {
219+
use super::*;
220+
221+
fn attributes() -> Attributes<'static> {
222+
let mut attributes = Attributes::empty();
223+
attributes.set("int", 1);
224+
attributes.set("strings", vec!["one", "two"]);
225+
attributes.set("numbers", vec![1, 2, 3]);
226+
attributes.set(
227+
"mixed",
228+
TemplateValue::List(vec![true.into(), 1.into(), "string".into()].into()),
229+
);
230+
attributes
231+
}
232+
233+
#[test]
234+
fn replace_attribute() {
235+
let mut attributes = attributes();
236+
assert_eq!(attributes.get_as::<u32>("int").unwrap(), 1);
237+
attributes.set("int", 2);
238+
assert_eq!(attributes.get_as::<u32>("int").unwrap(), 2);
239+
}
240+
241+
#[test]
242+
fn set_value() {
243+
let mut attributes = attributes();
244+
attributes.set("other", 2);
245+
assert_eq!(attributes.get_as::<u32>("other").unwrap(), 2);
246+
}
247+
248+
#[test]
249+
fn remove() {
250+
let mut attributes = attributes();
251+
attributes.remove("int");
252+
assert!(attributes.get("int").is_none());
253+
}
254+
255+
#[test]
256+
fn get_attribute() {
257+
let attributes = attributes();
258+
assert_eq!(attributes.get("int"), Some(&TemplateValue::Int(1)));
259+
}
260+
261+
#[test]
262+
fn get_attribute_as() {
263+
let attributes = attributes();
264+
assert_eq!(attributes.get_as::<u8>("int").unwrap(), 1);
265+
assert!(attributes.get_as::<bool>("int").is_none());
266+
}
267+
268+
#[test]
269+
fn get_value_as() {
270+
let mut attributes = attributes();
271+
attributes.set_value("hello world");
272+
assert_eq!(attributes.value_as::<&str>().unwrap(), "hello world");
273+
274+
attributes.set_value("hello world".to_string());
275+
assert_eq!(attributes.value_as::<&str>().unwrap(), "hello world");
276+
}
277+
278+
#[test]
279+
fn iterate_as() {
280+
let attributes = attributes();
281+
let numbers = attributes.iter_as::<u32>("numbers").collect::<Vec<_>>();
282+
assert_eq!(numbers, vec![1, 2, 3]);
283+
284+
let strings = attributes.iter_as::<&str>("strings").collect::<Vec<_>>();
285+
assert_eq!(strings, vec!["one", "two"]);
286+
}
287+
288+
#[test]
289+
fn iter() {
290+
let attributes = attributes();
291+
let mut iter = attributes.iter();
292+
assert_eq!(("int", &TemplateValue::Int(1)), iter.next().unwrap());
293+
}
294+
295+
#[test]
296+
fn iter_keys() {
297+
let attributes = attributes();
298+
let mut iter = attributes.iter_keys();
299+
assert_eq!("int", iter.next().unwrap());
300+
assert_eq!("strings", iter.next().unwrap());
301+
assert_eq!("numbers", iter.next().unwrap());
302+
}
188303
}

anathema-core/src/layout.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
1+
//! Storing the calculated layout of each element.
2+
//!
3+
//! The calculating the layout it self is done elsewhere.
14
use anathema_geometry::{Pos, Region, Size};
25
use anathema_store::slab::SecondaryMap;
36

47
use crate::runtime::elements::ElementId;
58

9+
/// Store the layout for each element.
610
#[derive(Debug)]
711
pub struct Layout {
812
regions: SecondaryMap<ElementId, Region>,
913
}
1014

1115
impl Layout {
12-
pub fn empty() -> Self {
16+
pub(crate) fn empty() -> Self {
1317
Self {
1418
regions: SecondaryMap::empty(),
1519
}

anathema-core/src/lib.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@
22
#[allow(unused_extern_crates)]
33
extern crate anathema_state as anathema;
44

5+
// Has docs
56
pub mod attributes;
67
pub mod frontend;
78
pub mod layout;
9+
10+
// Dosn't like has docs so is a bit mid
811
pub mod runtime;
912
pub mod templates;
10-
pub mod ui;
13+
14+
// Decide what to do here
15+
// pub mod ui;
1116

1217
pub(crate) mod testing;

anathema-core/src/runtime/eval/mod.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use anathema_store::remotecell::RemoteHandle;
55

66
use self::scope::Scope;
77
use super::error::Result;
8-
use crate::attributes::{AllAttributes, Attributes, ValueKey};
8+
use crate::attributes::{AttributeRegistry, Attributes, ValueKey};
99
use crate::runtime::components::Components;
1010
use crate::runtime::elements::{Element, ElementId, Elements};
1111
use crate::runtime::eval::expression::{eval_by_id, RuntimeExpression, RuntimeExpressions};
@@ -14,7 +14,6 @@ use crate::runtime::functions::{Function, FunctionTable};
1414
use crate::runtime::widgets::RegisteredWidgets;
1515
use crate::templates::expressions::{self, Expressions};
1616
use crate::templates::{Blueprint, Component, ExpressionId, For, Single, Variables};
17-
use crate::ui::Document;
1817

1918
mod assoc;
2019
pub(crate) mod expression;
@@ -24,7 +23,7 @@ pub(crate) mod values;
2423
#[derive(Debug)]
2524
pub struct EvalCtx<'a, 'bp> {
2625
pub(crate) elements: &'a mut Elements<'bp>,
27-
pub(crate) attributes: &'a mut AllAttributes<'bp>,
26+
pub(crate) attributes: &'a mut AttributeRegistry<'bp>,
2827
pub(crate) components: &'a mut Components,
2928
pub(crate) variables: &'a Variables,
3029
pub(crate) expressions: &'bp Expressions,
@@ -37,7 +36,7 @@ pub struct EvalCtx<'a, 'bp> {
3736
impl<'frame, 'bp> EvalCtx<'frame, 'bp> {
3837
pub(crate) fn new(
3938
elements: &'frame mut Elements<'bp>,
40-
attributes: &'frame mut AllAttributes<'bp>,
39+
attributes: &'frame mut AttributeRegistry<'bp>,
4140
components: &'frame mut Components,
4241
variables: &'frame Variables,
4342
expressions: &'bp Expressions,
@@ -239,7 +238,7 @@ mod test {
239238
use anathema_state::Value;
240239

241240
use super::*;
242-
use crate::attributes::AllAttributes;
241+
use crate::attributes::AttributeRegistry;
243242
use crate::layout::Layout;
244243
use crate::testing::{RunBuilder, TestWidget};
245244

anathema-core/src/templates/blueprints.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,17 @@ pub struct Component {
6060
/// A blueprint represents what widget should be built from the information
6161
#[derive(Clone, Debug, PartialEq)]
6262
pub enum Blueprint {
63+
/// A singular widget
6364
Single(Single),
65+
/// A for-loop
6466
For(For),
67+
/// A `with` statement
6568
With(With),
69+
/// If / else
6670
ControlFlow(ControlFlow),
71+
/// A component
6772
Component(Component),
73+
/// A slot for a component
6874
Slot(Vec<Self>),
6975
}
7076

0 commit comments

Comments
 (0)