diff options
| author | Laurenz <laurmaedje@gmail.com> | 2020-08-17 23:45:03 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2020-08-17 23:45:03 +0200 |
| commit | 6d7e7d945b315469b80bca3466a96534b2a17639 (patch) | |
| tree | 1b6c5e0ae7fb683ff7f3b6b1d961151a8e467a80 /src/compute | |
| parent | 3cbca56a7195bb2a7996530d584300d697c11dc8 (diff) | |
Tidy up library functions 🧺
Diffstat (limited to 'src/compute')
| -rw-r--r-- | src/compute/scope.rs | 6 | ||||
| -rw-r--r-- | src/compute/table.rs | 26 | ||||
| -rw-r--r-- | src/compute/value.rs | 35 |
3 files changed, 43 insertions, 24 deletions
diff --git a/src/compute/scope.rs b/src/compute/scope.rs index 1fd4db0b..1c297fde 100644 --- a/src/compute/scope.rs +++ b/src/compute/scope.rs @@ -31,12 +31,6 @@ impl Scope { self.functions.get(name) } - /// Return the function with the given name or the fallback if there is no - /// such function. - pub fn func_or_fallback(&self, name: &str) -> &FuncValue { - self.func(name).unwrap_or_else(|| self.fallback()) - } - /// Return the fallback function. pub fn fallback(&self) -> &FuncValue { &self.fallback diff --git a/src/compute/table.rs b/src/compute/table.rs index 75effd60..e8c4b307 100644 --- a/src/compute/table.rs +++ b/src/compute/table.rs @@ -1,7 +1,7 @@ //! A key-value map that can also model array-like structures. use std::collections::BTreeMap; -use std::fmt::{self, Debug, Formatter}; +use std::fmt::{self, Debug, Display, Formatter}; use std::ops::Index; use crate::syntax::span::{Span, Spanned}; @@ -180,25 +180,31 @@ impl<V: Debug> Debug for Table<V> { let mut builder = f.debug_tuple(""); - struct Entry<'a>(&'a dyn Debug, &'a dyn Debug); + struct Entry<'a>(bool, &'a dyn Display, &'a dyn Debug); impl<'a> Debug for Entry<'a> { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - self.0.fmt(f)?; + if self.0 { + f.write_str("\"")?; + } + self.1.fmt(f)?; + if self.0 { + f.write_str("\"")?; + } if f.alternate() { f.write_str(" = ")?; } else { f.write_str("=")?; } - self.1.fmt(f) + self.2.fmt(f) } } for (key, value) in self.nums() { - builder.field(&Entry(&key, &value)); + builder.field(&Entry(false, &key, &value)); } for (key, value) in self.strs() { - builder.field(&Entry(&key, &value)); + builder.field(&Entry(key.contains(' '), &key, &value)); } builder.finish() @@ -358,21 +364,21 @@ mod tests { #[test] fn test_table_format_debug() { let mut table = Table::new(); - assert_eq!(format!("{:?}", table), r#"()"#); - assert_eq!(format!("{:#?}", table), r#"()"#); + assert_eq!(format!("{:?}", table), "()"); + assert_eq!(format!("{:#?}", table), "()"); table.insert(10, "hello"); table.insert("twenty", "there"); table.insert("sp ace", "quotes"); assert_eq!( format!("{:?}", table), - r#"(10="hello", "sp ace"="quotes", "twenty"="there")"#, + r#"(10="hello", "sp ace"="quotes", twenty="there")"#, ); assert_eq!(format!("{:#?}", table).lines().collect::<Vec<_>>(), [ "(", r#" 10 = "hello","#, r#" "sp ace" = "quotes","#, - r#" "twenty" = "there","#, + r#" twenty = "there","#, ")", ]); } diff --git a/src/compute/value.rs b/src/compute/value.rs index daa3b17b..32f2778b 100644 --- a/src/compute/value.rs +++ b/src/compute/value.rs @@ -1,6 +1,7 @@ //! Computational values: Syntactical expressions can be evaluated into these. use std::fmt::{self, Debug, Formatter}; +use std::ops::Deref; use std::rc::Rc; use fontdock::{FontStyle, FontWeight, FontWidth}; @@ -13,7 +14,7 @@ use crate::syntax::span::{Span, Spanned}; use crate::syntax::tree::SyntaxTree; use crate::syntax::Ident; use crate::{DynFuture, Feedback, Pass}; -use super::table::{BorrowedKey, SpannedEntry, Table}; +use super::table::{SpannedEntry, Table}; /// A computational value. #[derive(Clone)] @@ -110,7 +111,7 @@ impl PartialEq for Value { /// /// The dynamic function object is wrapped in an `Rc` to keep `Value` clonable. pub type FuncValue = Rc< - dyn Fn(TableValue, LayoutContext<'_>) -> DynFuture<Pass<Value>> + dyn Fn(Span, TableValue, LayoutContext<'_>) -> DynFuture<Pass<Value>> >; /// A table of values. @@ -138,13 +139,21 @@ impl TableValue { /// Retrieve and remove the matching value with the lowest number key, /// removing and generating errors for all non-matching entries with lower /// keys. - pub fn expect<T: TryFromValue>(&mut self, f: &mut Feedback) -> Option<T> { + /// + /// Generates an error at `err_span` when no matching value was found. + pub fn expect<T: TryFromValue>( + &mut self, + name: &str, + span: Span, + f: &mut Feedback, + ) -> Option<T> { while let Some((num, _)) = self.first() { let entry = self.remove(num).unwrap(); if let Some(val) = T::try_from_value(entry.val.as_ref(), f) { return Some(val); } } + error!(@f, span, "missing argument: {}", name); None } @@ -152,9 +161,8 @@ impl TableValue { /// there is any. /// /// Generates an error if the key exists but the value does not match. - pub fn take_with_key<'a, K, T>(&mut self, key: K, f: &mut Feedback) -> Option<T> + pub fn take_key<'a, T>(&mut self, key: &str, f: &mut Feedback) -> Option<T> where - K: Into<BorrowedKey<'a>>, T: TryFromValue, { self.remove(key).and_then(|entry| { @@ -312,6 +320,14 @@ impl_match!(ScaleLength, "number or length", /// `Into<String>`. pub struct StringLike(pub String); +impl Deref for StringLike { + type Target = str; + + fn deref(&self) -> &str { + self.0.as_str() + } +} + impl From<StringLike> for String { fn from(like: StringLike) -> String { like.0 @@ -441,7 +457,10 @@ mod tests { table.insert(1, entry(Value::Bool(false))); table.insert(3, entry(Value::Str("hi".to_string()))); table.insert(5, entry(Value::Bool(true))); - assert_eq!(table.expect::<String>(&mut f), Some("hi".to_string())); + assert_eq!( + table.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); } @@ -452,8 +471,8 @@ mod tests { let mut table = Table::new(); table.insert(1, entry(Value::Bool(false))); table.insert("hi", entry(Value::Bool(true))); - assert_eq!(table.take_with_key::<_, bool>(1, &mut f), Some(false)); - assert_eq!(table.take_with_key::<_, f64>("hi", &mut f), None); + assert_eq!(table.take::<bool>(), Some(false)); + assert_eq!(table.take_key::<f64>("hi", &mut f), None); assert_eq!(f.diagnostics, [error!(Span::ZERO, "expected number, found bool")]); assert!(table.is_empty()); } |
