diff options
| author | Laurenz <laurmaedje@gmail.com> | 2020-10-01 13:15:10 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2020-10-01 13:15:10 +0200 |
| commit | aafd3c95cacd829b647cfab1533de5d4833b9a04 (patch) | |
| tree | 3a16ea942eb71dcda46dd9a3112fa83db0729a7b /src/compute | |
| parent | 885bfec5d7524845b41e180fadc9cf5626157eec (diff) | |
Rename table to dict ✏
Diffstat (limited to 'src/compute')
| -rw-r--r-- | src/compute/dict.rs (renamed from src/compute/table.rs) | 158 | ||||
| -rw-r--r-- | src/compute/mod.rs | 2 | ||||
| -rw-r--r-- | src/compute/value.rs | 88 |
3 files changed, 124 insertions, 124 deletions
diff --git a/src/compute/table.rs b/src/compute/dict.rs index 7abb565b..e4df0048 100644 --- a/src/compute/table.rs +++ b/src/compute/dict.rs @@ -6,21 +6,21 @@ use std::ops::Index; use crate::syntax::{Span, Spanned}; -/// A table data structure, which maps from integers (`u64`) or strings to a -/// generic value type. +/// A dictionary data structure, which maps from integers (`u64`) or strings to +/// a generic value type. /// -/// The table can be used to model arrays by assigns values to successive -/// indices from `0..n`. The table type offers special support for this pattern -/// through the `push` method. +/// The dictionary can be used to model arrays by assigning values to successive +/// indices from `0..n`. The `push` method offers special support for this +/// pattern. #[derive(Clone)] -pub struct Table<V> { +pub struct Dict<V> { nums: BTreeMap<u64, V>, strs: BTreeMap<String, V>, lowest_free: u64, } -impl<V> Table<V> { - /// Create a new empty table. +impl<V> Dict<V> { + /// Create a new empty dictionary. pub fn new() -> Self { Self { nums: BTreeMap::new(), @@ -29,12 +29,12 @@ impl<V> Table<V> { } } - /// The total number of entries in the table. + /// The total number of entries in the dictionary. pub fn len(&self) -> usize { self.nums.len() + self.strs.len() } - /// Whether the table contains no entries. + /// Whether the dictionary contains no entries. pub fn is_empty(&self) -> bool { self.len() == 0 } @@ -71,7 +71,7 @@ impl<V> Table<V> { } } - /// Insert a value into the table. + /// Insert a value into the dictionary. pub fn insert<K>(&mut self, key: K, value: V) where K: Into<OwnedKey>, @@ -89,7 +89,7 @@ impl<V> Table<V> { } } - /// Remove the value with the given key from the table. + /// Remove the value with the given key from the dictionary. pub fn remove<'a, K>(&mut self, key: K) -> Option<V> where K: Into<BorrowedKey<'a>>, @@ -103,7 +103,7 @@ impl<V> Table<V> { } } - /// Append a value to the table. + /// Append a value to the dictionary. /// /// This will associate the `value` with the lowest free number key (zero if /// there is no number key so far). @@ -122,7 +122,7 @@ impl<V> Table<V> { .chain(self.strs().map(|(k, v)| (BorrowedKey::Str(k), v))) } - /// Iterate over all values in the table. + /// Iterate over all values in the dictionary. pub fn values(&self) -> impl Iterator<Item = &V> { self.nums().map(|(_, v)| v).chain(self.strs().map(|(_, v)| v)) } @@ -145,7 +145,7 @@ impl<V> Table<V> { .chain(self.strs.into_iter().map(|(k, v)| (OwnedKey::Str(k), v))) } - /// Move into an owned iterator over all values in the table. + /// Move into an owned iterator over all values in the dictionary. pub fn into_values(self) -> impl Iterator<Item = V> { self.nums .into_iter() @@ -164,32 +164,32 @@ impl<V> Table<V> { } } -impl<'a, K, V> Index<K> for Table<V> +impl<'a, K, V> Index<K> for Dict<V> where K: Into<BorrowedKey<'a>>, { type Output = V; fn index(&self, index: K) -> &Self::Output { - self.get(index).expect("key not in table") + self.get(index).expect("key not in dict") } } -impl<V> Default for Table<V> { +impl<V> Default for Dict<V> { fn default() -> Self { Self::new() } } -impl<V: Eq> Eq for Table<V> {} +impl<V: Eq> Eq for Dict<V> {} -impl<V: PartialEq> PartialEq for Table<V> { +impl<V: PartialEq> PartialEq for Dict<V> { fn eq(&self, other: &Self) -> bool { self.iter().eq(other.iter()) } } -impl<V: Debug> Debug for Table<V> { +impl<V: Debug> Debug for Dict<V> { fn fmt(&self, f: &mut Formatter) -> fmt::Result { if self.is_empty() { return f.write_str("()"); @@ -228,7 +228,7 @@ impl<V: Debug> Debug for Table<V> { } } -/// The owned variant of a table key. +/// The owned variant of a dictionary key. #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)] pub enum OwnedKey { Num(u64), @@ -262,7 +262,7 @@ impl From<&'static str> for OwnedKey { } } -/// The borrowed variant of a table key. +/// The borrowed variant of a dictionary key. #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] pub enum BorrowedKey<'a> { Num(u64), @@ -287,7 +287,7 @@ impl<'a> From<&'a str> for BorrowedKey<'a> { } } -/// An table entry which tracks key and value span. +/// A dictionary entry which tracks key and value span. #[derive(Clone, PartialEq)] pub struct SpannedEntry<V> { pub key: Span, @@ -329,78 +329,78 @@ impl<V: Debug> Debug for SpannedEntry<V> { #[cfg(test)] mod tests { - use super::Table; + use super::Dict; #[test] - fn test_table_different_key_types_dont_interfere() { - let mut table = Table::new(); - table.insert(10, "hello"); - table.insert("twenty", "there"); - assert_eq!(table.len(), 2); - assert_eq!(table[10], "hello"); - assert_eq!(table["twenty"], "there"); + fn test_dict_different_key_types_dont_interfere() { + let mut dict = Dict::new(); + dict.insert(10, "hello"); + dict.insert("twenty", "there"); + assert_eq!(dict.len(), 2); + assert_eq!(dict[10], "hello"); + assert_eq!(dict["twenty"], "there"); } #[test] - fn test_table_push_skips_already_inserted_keys() { - let mut table = Table::new(); - table.insert(2, "2"); - table.push("0"); - table.insert(3, "3"); - table.push("1"); - table.push("4"); - assert_eq!(table.len(), 5); - assert_eq!(table[0], "0"); - assert_eq!(table[1], "1"); - assert_eq!(table[2], "2"); - assert_eq!(table[3], "3"); - assert_eq!(table[4], "4"); + fn test_dict_push_skips_already_inserted_keys() { + let mut dict = Dict::new(); + dict.insert(2, "2"); + dict.push("0"); + dict.insert(3, "3"); + dict.push("1"); + dict.push("4"); + assert_eq!(dict.len(), 5); + assert_eq!(dict[0], "0"); + assert_eq!(dict[1], "1"); + assert_eq!(dict[2], "2"); + assert_eq!(dict[3], "3"); + assert_eq!(dict[4], "4"); } #[test] - fn test_table_push_remove_push_reuses_index() { - let mut table = Table::new(); - table.push("0"); - table.push("1"); - table.push("2"); - table.remove(1); - table.push("a"); - table.push("3"); - assert_eq!(table.len(), 4); - assert_eq!(table[0], "0"); - assert_eq!(table[1], "a"); - assert_eq!(table[2], "2"); - assert_eq!(table[3], "3"); + fn test_dict_push_remove_push_reuses_index() { + let mut dict = Dict::new(); + dict.push("0"); + dict.push("1"); + dict.push("2"); + dict.remove(1); + dict.push("a"); + dict.push("3"); + assert_eq!(dict.len(), 4); + assert_eq!(dict[0], "0"); + assert_eq!(dict[1], "a"); + assert_eq!(dict[2], "2"); + assert_eq!(dict[3], "3"); } #[test] - fn test_table_first_and_last_are_correct() { - let mut table = Table::new(); - assert_eq!(table.first(), None); - assert_eq!(table.last(), None); - table.insert(4, "hi"); - table.insert("string", "hi"); - assert_eq!(table.first(), Some((4, &"hi"))); - assert_eq!(table.last(), Some((4, &"hi"))); - table.insert(2, "bye"); - assert_eq!(table.first(), Some((2, &"bye"))); - assert_eq!(table.last(), Some((4, &"hi"))); + fn test_dict_first_and_last_are_correct() { + let mut dict = Dict::new(); + assert_eq!(dict.first(), None); + assert_eq!(dict.last(), None); + dict.insert(4, "hi"); + dict.insert("string", "hi"); + assert_eq!(dict.first(), Some((4, &"hi"))); + assert_eq!(dict.last(), Some((4, &"hi"))); + dict.insert(2, "bye"); + assert_eq!(dict.first(), Some((2, &"bye"))); + assert_eq!(dict.last(), Some((4, &"hi"))); } #[test] - fn test_table_format_debug() { - let mut table = Table::new(); - assert_eq!(format!("{:?}", table), "()"); - assert_eq!(format!("{:#?}", table), "()"); - - table.insert(10, "hello"); - table.insert("twenty", "there"); - table.insert("sp ace", "quotes"); + fn test_dict_format_debug() { + let mut dict = Dict::new(); + assert_eq!(format!("{:?}", dict), "()"); + assert_eq!(format!("{:#?}", dict), "()"); + + dict.insert(10, "hello"); + dict.insert("twenty", "there"); + dict.insert("sp ace", "quotes"); assert_eq!( - format!("{:?}", table), + format!("{:?}", dict), r#"(10="hello", "sp ace"="quotes", twenty="there")"#, ); - assert_eq!(format!("{:#?}", table).lines().collect::<Vec<_>>(), [ + assert_eq!(format!("{:#?}", dict).lines().collect::<Vec<_>>(), [ "(", r#" 10 = "hello","#, r#" "sp ace" = "quotes","#, diff --git a/src/compute/mod.rs b/src/compute/mod.rs index ac278243..a67d65b6 100644 --- a/src/compute/mod.rs +++ b/src/compute/mod.rs @@ -1,5 +1,5 @@ //! Building blocks for the computational part. +pub mod dict; pub mod scope; -pub mod table; pub mod value; diff --git a/src/compute/value.rs b/src/compute/value.rs index e8e4cbe1..1fcc4be2 100644 --- a/src/compute/value.rs +++ b/src/compute/value.rs @@ -6,7 +6,7 @@ use std::rc::Rc; use fontdock::{FontStretch, FontStyle, FontWeight}; -use super::table::{SpannedEntry, Table}; +use super::dict::{Dict, SpannedEntry}; use crate::color::RgbaColor; use crate::layout::{Command, Commands, Dir, LayoutContext, SpecAlign}; use crate::length::{Length, ScaleLength}; @@ -29,8 +29,8 @@ pub enum Value { Length(Length), /// A color value with alpha channel: `#f79143ff`. Color(RgbaColor), - /// A table value: `(false, 12cm, greeting="hi")`. - Table(TableValue), + /// A dictionary value: `(false, 12cm, greeting="hi")`. + Dict(DictValue), /// A syntax tree containing typesetting content. Tree(SyntaxTree), /// An executable function. @@ -51,7 +51,7 @@ impl Value { Number(_) => "number", Length(_) => "length", Color(_) => "color", - Table(_) => "table", + Dict(_) => "dict", Tree(_) => "syntax tree", Func(_) => "function", Commands(_) => "commands", @@ -70,10 +70,10 @@ impl Spanned<Value> { Value::Tree(tree) => vec![Command::LayoutSyntaxTree(tree)], // Forward to each entry, separated with spaces. - Value::Table(table) => { + Value::Dict(dict) => { let mut commands = vec![]; let mut end = None; - for entry in table.into_values() { + for entry in dict.into_values() { if let Some(last_end) = end { let span = Span::new(last_end, entry.key.start); let tree = vec![SyntaxNode::Spacing.span_with(span)]; @@ -106,7 +106,7 @@ impl Debug for Value { Number(n) => n.fmt(f), Length(s) => s.fmt(f), Color(c) => c.fmt(f), - Table(t) => t.fmt(f), + Dict(t) => t.fmt(f), Tree(t) => t.fmt(f), Func(_) => f.pad("<function>"), Commands(c) => c.fmt(f), @@ -124,7 +124,7 @@ impl PartialEq for Value { (Number(a), Number(b)) => a == b, (Length(a), Length(b)) => a == b, (Color(a), Color(b)) => a == b, - (Table(a), Table(b)) => a == b, + (Dict(a), Dict(b)) => a == b, (Tree(a), Tree(b)) => a == b, (Func(a), Func(b)) => Rc::ptr_eq(a, b), (Commands(a), Commands(b)) => a == b, @@ -135,7 +135,7 @@ impl PartialEq for Value { /// An executable function value. /// -/// The first argument is a table containing the arguments passed to the +/// The first argument is a dictionary containing the arguments passed to the /// function. The function may be asynchronous (as such it returns a dynamic /// future) and it may emit diagnostics, which are contained in the returned /// `Pass`. In the end, the function must evaluate to `Value`. Your typical @@ -144,17 +144,17 @@ impl PartialEq for Value { /// /// The dynamic function object is wrapped in an `Rc` to keep `Value` clonable. pub type FuncValue = - Rc<dyn Fn(Span, TableValue, LayoutContext<'_>) -> DynFuture<Pass<Value>>>; + Rc<dyn Fn(Span, DictValue, LayoutContext<'_>) -> DynFuture<Pass<Value>>>; -/// A table of values. +/// A dictionary of values. /// /// # Example /// ```typst /// (false, 12cm, greeting="hi") /// ``` -pub type TableValue = Table<SpannedEntry<Value>>; +pub type DictValue = Dict<SpannedEntry<Value>>; -impl TableValue { +impl DictValue { /// Retrieve and remove the matching value with the lowest number key, /// skipping and ignoring all non-matching entries with lower keys. pub fn take<T: TryFromValue>(&mut self) -> Option<T> { @@ -341,7 +341,7 @@ impl_match!(bool, "bool", &Value::Bool(b) => b); impl_match!(f64, "number", &Value::Number(n) => n); impl_match!(Length, "length", &Value::Length(l) => l); impl_match!(SyntaxTree, "tree", Value::Tree(t) => t.clone()); -impl_match!(TableValue, "table", Value::Table(t) => t.clone()); +impl_match!(DictValue, "dict", Value::Dict(t) => t.clone()); impl_match!(FuncValue, "function", Value::Func(f) => f.clone()); impl_match!(ScaleLength, "number or length", &Value::Length(length) => ScaleLength::Absolute(length), @@ -437,60 +437,60 @@ mod tests { } #[test] - fn test_table_take_removes_correct_entry() { - let mut table = Table::new(); - table.insert(1, entry(Value::Bool(false))); - table.insert(2, entry(Value::Str("hi".to_string()))); - assert_eq!(table.take::<String>(), Some("hi".to_string())); - assert_eq!(table.len(), 1); - assert_eq!(table.take::<bool>(), Some(false)); - assert!(table.is_empty()); + fn test_dict_take_removes_correct_entry() { + let mut dict = Dict::new(); + dict.insert(1, entry(Value::Bool(false))); + dict.insert(2, entry(Value::Str("hi".to_string()))); + assert_eq!(dict.take::<String>(), Some("hi".to_string())); + assert_eq!(dict.len(), 1); + assert_eq!(dict.take::<bool>(), Some(false)); + assert!(dict.is_empty()); } #[test] - fn test_table_expect_errors_about_previous_entries() { + fn test_dict_expect_errors_about_previous_entries() { let mut f = Feedback::new(); - let mut table = Table::new(); - table.insert(1, entry(Value::Bool(false))); - table.insert(3, entry(Value::Str("hi".to_string()))); - table.insert(5, entry(Value::Bool(true))); + let mut dict = Dict::new(); + dict.insert(1, entry(Value::Bool(false))); + dict.insert(3, entry(Value::Str("hi".to_string()))); + dict.insert(5, entry(Value::Bool(true))); assert_eq!( - table.expect::<String>("", Span::ZERO, &mut f), + dict.expect::<String>("", Span::ZERO, &mut f), Some("hi".to_string()) ); assert_eq!(f.diagnostics, [error!( Span::ZERO, "expected string, found bool" )]); - assert_eq!(table.len(), 1); + assert_eq!(dict.len(), 1); } #[test] - fn test_table_take_with_key_removes_the_entry() { + fn test_dict_take_with_key_removes_the_entry() { let mut f = Feedback::new(); - let mut table = Table::new(); - table.insert(1, entry(Value::Bool(false))); - table.insert("hi", entry(Value::Bool(true))); - assert_eq!(table.take::<bool>(), Some(false)); - assert_eq!(table.take_key::<f64>("hi", &mut f), None); + let mut dict = Dict::new(); + dict.insert(1, entry(Value::Bool(false))); + dict.insert("hi", entry(Value::Bool(true))); + assert_eq!(dict.take::<bool>(), Some(false)); + assert_eq!(dict.take_key::<f64>("hi", &mut f), None); assert_eq!(f.diagnostics, [error!( Span::ZERO, "expected number, found bool" )]); - assert!(table.is_empty()); + assert!(dict.is_empty()); } #[test] - fn test_table_take_all_removes_the_correct_entries() { - let mut table = Table::new(); - table.insert(1, entry(Value::Bool(false))); - table.insert(3, entry(Value::Number(0.0))); - table.insert(7, entry(Value::Bool(true))); - assert_eq!(table.take_all_num::<bool>().collect::<Vec<_>>(), [ + fn test_dict_take_all_removes_the_correct_entries() { + let mut dict = Dict::new(); + dict.insert(1, entry(Value::Bool(false))); + dict.insert(3, entry(Value::Number(0.0))); + dict.insert(7, entry(Value::Bool(true))); + assert_eq!(dict.take_all_num::<bool>().collect::<Vec<_>>(), [ (1, false), (7, true) ],); - assert_eq!(table.len(), 1); - assert_eq!(table[3].val.v, Value::Number(0.0)); + assert_eq!(dict.len(), 1); + assert_eq!(dict[3].val.v, Value::Number(0.0)); } } |
