summaryrefslogtreecommitdiff
path: root/src/compute
diff options
context:
space:
mode:
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.rs2
-rw-r--r--src/compute/value.rs88
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));
}
}