summaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2023-11-19 17:42:43 +0100
committerLaurenz <laurmaedje@gmail.com>2023-11-19 18:16:18 +0100
commitc97a01616abd3af6511ceac28a01ac6d3023ae83 (patch)
treeef3b11b776d88131f1b855d9a3dfefc1b210e2a3 /crates
parent2da619e17cb48efd468818ea35793b3f90b8aaea (diff)
More useful `Debug` impls
Diffstat (limited to 'crates')
-rw-r--r--crates/typst-library/src/meta/bibliography.rs9
-rw-r--r--crates/typst/src/eval/args.rs52
-rw-r--r--crates/typst/src/eval/auto.rs10
-rw-r--r--crates/typst/src/eval/bytes.rs28
-rw-r--r--crates/typst/src/eval/duration.rs10
-rw-r--r--crates/typst/src/eval/fields.rs4
-rw-r--r--crates/typst/src/eval/func.rs12
-rw-r--r--crates/typst/src/eval/module.rs14
-rw-r--r--crates/typst/src/eval/none.rs10
-rw-r--r--crates/typst/src/eval/str.rs186
-rw-r--r--crates/typst/src/eval/symbol.rs23
-rw-r--r--crates/typst/src/eval/ty.rs8
-rw-r--r--crates/typst/src/eval/value.rs48
-rw-r--r--crates/typst/src/font/book.rs9
-rw-r--r--crates/typst/src/geom/abs.rs8
-rw-r--r--crates/typst/src/geom/angle.rs8
-rw-r--r--crates/typst/src/geom/color.rs181
-rw-r--r--crates/typst/src/geom/corners.rs121
-rw-r--r--crates/typst/src/geom/em.rs8
-rw-r--r--crates/typst/src/geom/fr.rs8
-rw-r--r--crates/typst/src/geom/gradient.rs12
-rw-r--r--crates/typst/src/geom/length.rs12
-rw-r--r--crates/typst/src/geom/paint.rs29
-rw-r--r--crates/typst/src/geom/ratio.rs8
-rw-r--r--crates/typst/src/geom/rel.rs12
-rw-r--r--crates/typst/src/geom/scalar.rs26
-rw-r--r--crates/typst/src/geom/sides.rs173
-rw-r--r--crates/typst/src/model/block.rs12
-rw-r--r--crates/typst/src/model/content.rs10
-rw-r--r--crates/typst/src/model/element.rs2
-rw-r--r--crates/typst/src/model/label.rs2
-rw-r--r--crates/typst/src/model/styles.rs34
-rw-r--r--crates/typst/src/util/deferred.rs1
33 files changed, 688 insertions, 402 deletions
diff --git a/crates/typst-library/src/meta/bibliography.rs b/crates/typst-library/src/meta/bibliography.rs
index c258d19d..b84c330a 100644
--- a/crates/typst-library/src/meta/bibliography.rs
+++ b/crates/typst-library/src/meta/bibliography.rs
@@ -1,5 +1,6 @@
use std::collections::HashMap;
use std::ffi::OsStr;
+use std::fmt::{self, Debug, Formatter};
use std::hash::{Hash, Hasher};
use std::path::Path;
use std::sync::Arc;
@@ -296,7 +297,7 @@ impl LocalName for BibliographyElem {
/// A loaded bibliography.
#[ty]
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Clone, PartialEq)]
pub struct Bibliography {
map: Arc<IndexMap<PicoStr, hayagriva::Entry>>,
hash: u128,
@@ -378,6 +379,12 @@ impl Bibliography {
}
}
+impl Debug for Bibliography {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ f.debug_set().entries(self.map.keys()).finish()
+ }
+}
+
impl Hash for Bibliography {
fn hash<H: Hasher>(&self, state: &mut H) {
self.hash.hash(state);
diff --git a/crates/typst/src/eval/args.rs b/crates/typst/src/eval/args.rs
index 72051bf7..1cb175e3 100644
--- a/crates/typst/src/eval/args.rs
+++ b/crates/typst/src/eval/args.rs
@@ -48,18 +48,6 @@ pub struct Args {
pub items: EcoVec<Arg>,
}
-/// An argument to a function call: `12` or `draw: false`.
-#[derive(Debug, Clone, Hash)]
-#[allow(clippy::derived_hash_with_manual_eq)]
-pub struct Arg {
- /// The span of the whole argument.
- pub span: Span,
- /// The name of the argument (`None` for positional arguments).
- pub name: Option<Str>,
- /// The value of the argument.
- pub value: Spanned<Value>,
-}
-
impl Args {
/// Create positional arguments from a span and values.
pub fn new<T: IntoValue>(span: Span, values: impl IntoIterator<Item = T>) -> Self {
@@ -274,12 +262,6 @@ impl Args {
}
}
-impl PartialEq for Args {
- fn eq(&self, other: &Self) -> bool {
- self.to_pos() == other.to_pos() && self.to_named() == other.to_named()
- }
-}
-
impl Debug for Args {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
f.debug_list().entries(&self.items).finish()
@@ -293,9 +275,33 @@ impl Repr for Args {
}
}
-impl PartialEq for Arg {
+impl PartialEq for Args {
fn eq(&self, other: &Self) -> bool {
- self.name == other.name && self.value.v == other.value.v
+ self.to_pos() == other.to_pos() && self.to_named() == other.to_named()
+ }
+}
+
+/// An argument to a function call: `12` or `draw: false`.
+#[derive(Clone, Hash)]
+#[allow(clippy::derived_hash_with_manual_eq)]
+pub struct Arg {
+ /// The span of the whole argument.
+ pub span: Span,
+ /// The name of the argument (`None` for positional arguments).
+ pub name: Option<Str>,
+ /// The value of the argument.
+ pub value: Spanned<Value>,
+}
+
+impl Debug for Arg {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ if let Some(name) = &self.name {
+ name.fmt(f)?;
+ f.write_str(": ")?;
+ self.value.v.fmt(f)
+ } else {
+ self.value.v.fmt(f)
+ }
}
}
@@ -308,3 +314,9 @@ impl Repr for Arg {
}
}
}
+
+impl PartialEq for Arg {
+ fn eq(&self, other: &Self) -> bool {
+ self.name == other.name && self.value.v == other.value.v
+ }
+}
diff --git a/crates/typst/src/eval/auto.rs b/crates/typst/src/eval/auto.rs
index 011bf6d0..0dcf79c7 100644
--- a/crates/typst/src/eval/auto.rs
+++ b/crates/typst/src/eval/auto.rs
@@ -1,5 +1,5 @@
use ecow::EcoString;
-use std::fmt::Debug;
+use std::fmt::{self, Debug, Formatter};
use crate::diag::StrResult;
use crate::eval::{ty, CastInfo, FromValue, IntoValue, Reflect, Repr, Type, Value};
@@ -14,7 +14,7 @@ use crate::model::{Fold, Resolve, StyleChain};
/// parameter. Setting it to `{auto}` lets Typst automatically determine the
/// direction from the [text language]($text.lang).
#[ty(name = "auto")]
-#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct AutoValue;
impl IntoValue for AutoValue {
@@ -46,6 +46,12 @@ impl Reflect for AutoValue {
}
}
+impl Debug for AutoValue {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ f.write_str("Auto")
+ }
+}
+
impl Repr for AutoValue {
fn repr(&self) -> EcoString {
"auto".into()
diff --git a/crates/typst/src/eval/bytes.rs b/crates/typst/src/eval/bytes.rs
index 96415d20..0b074fac 100644
--- a/crates/typst/src/eval/bytes.rs
+++ b/crates/typst/src/eval/bytes.rs
@@ -1,5 +1,5 @@
use std::borrow::Cow;
-use std::fmt::Debug;
+use std::fmt::{self, Debug, Formatter};
use std::ops::{Add, AddAssign, Deref};
use std::sync::Arc;
@@ -38,7 +38,7 @@ use crate::eval::{cast, func, scope, ty, Array, Reflect, Repr, Str, Value};
/// #str(data.slice(1, 4))
/// ```
#[ty(scope)]
-#[derive(Debug, Clone, Hash, Eq, PartialEq)]
+#[derive(Clone, Hash, Eq, PartialEq)]
pub struct Bytes(Arc<Prehashed<Cow<'static, [u8]>>>);
impl Bytes {
@@ -153,15 +153,15 @@ impl Bytes {
}
}
-impl From<&[u8]> for Bytes {
- fn from(slice: &[u8]) -> Self {
- Self(Arc::new(Prehashed::new(slice.to_vec().into())))
+impl Debug for Bytes {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(f, "Bytes({})", self.len())
}
}
-impl From<Vec<u8>> for Bytes {
- fn from(vec: Vec<u8>) -> Self {
- Self(Arc::new(Prehashed::new(vec.into())))
+impl Repr for Bytes {
+ fn repr(&self) -> EcoString {
+ eco_format!("bytes({})", self.len())
}
}
@@ -179,9 +179,15 @@ impl AsRef<[u8]> for Bytes {
}
}
-impl Repr for Bytes {
- fn repr(&self) -> EcoString {
- eco_format!("bytes({})", self.len())
+impl From<&[u8]> for Bytes {
+ fn from(slice: &[u8]) -> Self {
+ Self(Arc::new(Prehashed::new(slice.to_vec().into())))
+ }
+}
+
+impl From<Vec<u8>> for Bytes {
+ fn from(vec: Vec<u8>) -> Self {
+ Self(Arc::new(Prehashed::new(vec.into())))
}
}
diff --git a/crates/typst/src/eval/duration.rs b/crates/typst/src/eval/duration.rs
index 775cd5b2..35f41603 100644
--- a/crates/typst/src/eval/duration.rs
+++ b/crates/typst/src/eval/duration.rs
@@ -1,6 +1,6 @@
use ecow::{eco_format, EcoString};
-use std::fmt::Debug;
+use std::fmt::{self, Debug, Formatter};
use std::ops::{Add, Div, Mul, Neg, Sub};
use time::ext::NumericalDuration;
@@ -8,7 +8,7 @@ use crate::eval::{func, repr, scope, ty, Repr};
/// Represents a positive or negative span of time.
#[ty(scope)]
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Duration(time::Duration);
impl Duration {
@@ -110,6 +110,12 @@ impl Duration {
}
}
+impl Debug for Duration {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ self.0.fmt(f)
+ }
+}
+
impl Repr for Duration {
fn repr(&self) -> EcoString {
let mut tmp = self.0;
diff --git a/crates/typst/src/eval/fields.rs b/crates/typst/src/eval/fields.rs
index f78339fb..a810d543 100644
--- a/crates/typst/src/eval/fields.rs
+++ b/crates/typst/src/eval/fields.rs
@@ -1,11 +1,9 @@
use ecow::{eco_format, EcoString};
use crate::diag::StrResult;
-use crate::eval::Version;
+use crate::eval::{IntoValue, Type, Value, Version};
use crate::geom::{Align, Length, Rel, Stroke};
-use crate::eval::{IntoValue, Type, Value};
-
/// Try to access a field on a value.
///
/// This function is exclusively for types which have predefined fields, such as
diff --git a/crates/typst/src/eval/func.rs b/crates/typst/src/eval/func.rs
index 3633fc89..8bcb7e46 100644
--- a/crates/typst/src/eval/func.rs
+++ b/crates/typst/src/eval/func.rs
@@ -1,4 +1,4 @@
-use std::fmt::Debug;
+use std::fmt::{self, Debug, Formatter};
use std::sync::Arc;
use comemo::{Prehashed, Tracked, TrackedMut};
@@ -128,7 +128,7 @@ pub use typst_macros::func;
/// [`array.push(value)`]($array.push). These can modify the values they are
/// called on.
#[ty(scope, name = "function")]
-#[derive(Debug, Clone, Hash)]
+#[derive(Clone, Hash)]
#[allow(clippy::derived_hash_with_manual_eq)]
pub struct Func {
/// The internal representation.
@@ -138,7 +138,7 @@ pub struct Func {
}
/// The different kinds of function representations.
-#[derive(Debug, Clone, PartialEq, Hash)]
+#[derive(Clone, PartialEq, Hash)]
enum Repr {
/// A native Rust function.
Native(Static<NativeFuncData>),
@@ -390,6 +390,12 @@ impl Func {
}
}
+impl Debug for Func {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(f, "Func({})", self.name().unwrap_or(".."))
+ }
+}
+
impl super::Repr for Func {
fn repr(&self) -> EcoString {
match self.name() {
diff --git a/crates/typst/src/eval/module.rs b/crates/typst/src/eval/module.rs
index 9480f797..26bf537d 100644
--- a/crates/typst/src/eval/module.rs
+++ b/crates/typst/src/eval/module.rs
@@ -1,4 +1,4 @@
-use std::fmt::Debug;
+use std::fmt::{self, Debug, Formatter};
use std::sync::Arc;
use ecow::{eco_format, EcoString};
@@ -24,7 +24,7 @@ use crate::eval::{ty, Content, Scope, Value};
/// >>> #(-3)
/// ```
#[ty]
-#[derive(Debug, Clone, Hash)]
+#[derive(Clone, Hash)]
#[allow(clippy::derived_hash_with_manual_eq)]
pub struct Module {
/// The module's name.
@@ -100,6 +100,16 @@ impl Module {
}
}
+impl Debug for Module {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ f.debug_struct("Module")
+ .field("name", &self.name)
+ .field("scope", &self.inner.scope)
+ .field("content", &self.inner.content)
+ .finish()
+ }
+}
+
impl super::Repr for Module {
fn repr(&self) -> EcoString {
eco_format!("<module {}>", self.name())
diff --git a/crates/typst/src/eval/none.rs b/crates/typst/src/eval/none.rs
index 896e2ceb..a022e578 100644
--- a/crates/typst/src/eval/none.rs
+++ b/crates/typst/src/eval/none.rs
@@ -1,5 +1,5 @@
use ecow::EcoString;
-use std::fmt::Debug;
+use std::fmt::{self, Debug, Formatter};
use serde::{Serialize, Serializer};
@@ -19,7 +19,7 @@ use crate::eval::{cast, ty, CastInfo, FromValue, IntoValue, Reflect, Repr, Type,
/// Not visible: #none
/// ```
#[ty(name = "none")]
-#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct NoneValue;
impl Reflect for NoneValue {
@@ -51,6 +51,12 @@ impl FromValue for NoneValue {
}
}
+impl Debug for NoneValue {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ f.pad("None")
+ }
+}
+
impl Repr for NoneValue {
fn repr(&self) -> EcoString {
"none".into()
diff --git a/crates/typst/src/eval/str.rs b/crates/typst/src/eval/str.rs
index 123c408b..70feae22 100644
--- a/crates/typst/src/eval/str.rs
+++ b/crates/typst/src/eval/str.rs
@@ -68,7 +68,7 @@ pub use ecow::eco_format;
/// - `[\t]` for a tab
/// - `[\u{1f600}]` for a hexadecimal Unicode escape sequence
#[ty(scope, title = "String")]
-#[derive(Debug, Default, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+#[derive(Default, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[derive(Serialize, Deserialize)]
#[serde(transparent)]
pub struct Str(EcoString);
@@ -598,77 +598,6 @@ impl Str {
}
}
-/// A value that can be cast to a string.
-pub enum ToStr {
- /// A string value ready to be used as-is.
- Str(Str),
- /// An integer about to be formatted in a given base.
- Int(i64),
-}
-
-cast! {
- ToStr,
- v: i64 => Self::Int(v),
- v: f64 => Self::Str(repr::format_float(v, None, "").into()),
- v: Version => Self::Str(format_str!("{}", v)),
- v: Bytes => Self::Str(
- std::str::from_utf8(&v)
- .map_err(|_| "bytes are not valid utf-8")?
- .into()
- ),
- v: Label => Self::Str(v.as_str().into()),
- v: Type => Self::Str(v.long_name().into()),
- v: Str => Self::Str(v),
-}
-
-/// The out of bounds access error message.
-#[cold]
-fn out_of_bounds(index: i64, len: usize) -> EcoString {
- eco_format!("string index out of bounds (index: {}, len: {})", index, len)
-}
-
-/// The out of bounds access error message when no default value was given.
-#[cold]
-fn no_default_and_out_of_bounds(index: i64, len: usize) -> EcoString {
- eco_format!("no default value was specified and string index out of bounds (index: {}, len: {})", index, len)
-}
-
-/// The char boundary access error message.
-#[cold]
-fn not_a_char_boundary(index: i64) -> EcoString {
- eco_format!("string index {} is not a character boundary", index)
-}
-
-/// The error message when the string is empty.
-#[cold]
-fn string_is_empty() -> EcoString {
- "string is empty".into()
-}
-
-/// Convert an item of std's `match_indices` to a dictionary.
-fn match_to_dict((start, text): (usize, &str)) -> Dict {
- dict! {
- "start" => start,
- "end" => start + text.len(),
- "text" => text,
- "captures" => Array::new(),
- }
-}
-
-/// Convert regex captures to a dictionary.
-fn captures_to_dict(cap: regex::Captures) -> Dict {
- let m = cap.get(0).expect("missing first match");
- dict! {
- "start" => m.start(),
- "end" => m.end(),
- "text" => m.as_str(),
- "captures" => cap.iter()
- .skip(1)
- .map(|opt| opt.map_or(Value::None, |m| m.as_str().into_value()))
- .collect::<Array>(),
- }
-}
-
impl Deref for Str {
type Target = str;
@@ -677,9 +606,15 @@ impl Deref for Str {
}
}
+impl Debug for Str {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ Debug::fmt(self.as_str(), f)
+ }
+}
+
impl Display for Str {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
- f.pad(self)
+ Display::fmt(self.as_str(), f)
}
}
@@ -689,6 +624,29 @@ impl Repr for Str {
}
}
+impl Repr for EcoString {
+ fn repr(&self) -> EcoString {
+ self.as_ref().repr()
+ }
+}
+
+impl Repr for &str {
+ fn repr(&self) -> EcoString {
+ let mut r = EcoString::with_capacity(self.len() + 2);
+ r.push('"');
+ for c in self.chars() {
+ match c {
+ '\0' => r.push_str(r"\u{0}"),
+ '\'' => r.push('\''),
+ '"' => r.push_str(r#"\""#),
+ _ => c.escape_debug().for_each(|c| r.push(c)),
+ }
+ }
+ r.push('"');
+ r
+ }
+}
+
impl Add for Str {
type Output = Self;
@@ -793,29 +751,77 @@ cast! {
v: Str => v.into(),
}
-impl Repr for &str {
- fn repr(&self) -> EcoString {
- let mut r = EcoString::with_capacity(self.len() + 2);
- r.push('"');
- for c in self.chars() {
- match c {
- '\0' => r.push_str(r"\u{0}"),
- '\'' => r.push('\''),
- '"' => r.push_str(r#"\""#),
- _ => c.escape_debug().for_each(|c| r.push(c)),
- }
- }
- r.push('"');
- r
+/// A value that can be cast to a string.
+pub enum ToStr {
+ /// A string value ready to be used as-is.
+ Str(Str),
+ /// An integer about to be formatted in a given base.
+ Int(i64),
+}
+
+cast! {
+ ToStr,
+ v: i64 => Self::Int(v),
+ v: f64 => Self::Str(repr::format_float(v, None, "").into()),
+ v: Version => Self::Str(format_str!("{}", v)),
+ v: Bytes => Self::Str(
+ std::str::from_utf8(&v)
+ .map_err(|_| "bytes are not valid utf-8")?
+ .into()
+ ),
+ v: Label => Self::Str(v.as_str().into()),
+ v: Type => Self::Str(v.long_name().into()),
+ v: Str => Self::Str(v),
+}
+
+/// Convert an item of std's `match_indices` to a dictionary.
+fn match_to_dict((start, text): (usize, &str)) -> Dict {
+ dict! {
+ "start" => start,
+ "end" => start + text.len(),
+ "text" => text,
+ "captures" => Array::new(),
}
}
-impl Repr for EcoString {
- fn repr(&self) -> EcoString {
- self.as_ref().repr()
+/// Convert regex captures to a dictionary.
+fn captures_to_dict(cap: regex::Captures) -> Dict {
+ let m = cap.get(0).expect("missing first match");
+ dict! {
+ "start" => m.start(),
+ "end" => m.end(),
+ "text" => m.as_str(),
+ "captures" => cap.iter()
+ .skip(1)
+ .map(|opt| opt.map_or(Value::None, |m| m.as_str().into_value()))
+ .collect::<Array>(),
}
}
+/// The out of bounds access error message.
+#[cold]
+fn out_of_bounds(index: i64, len: usize) -> EcoString {
+ eco_format!("string index out of bounds (index: {}, len: {})", index, len)
+}
+
+/// The out of bounds access error message when no default value was given.
+#[cold]
+fn no_default_and_out_of_bounds(index: i64, len: usize) -> EcoString {
+ eco_format!("no default value was specified and string index out of bounds (index: {}, len: {})", index, len)
+}
+
+/// The char boundary access error message.
+#[cold]
+fn not_a_char_boundary(index: i64) -> EcoString {
+ eco_format!("string index {} is not a character boundary", index)
+}
+
+/// The error message when the string is empty.
+#[cold]
+fn string_is_empty() -> EcoString {
+ "string is empty".into()
+}
+
/// A regular expression.
///
/// Can be used as a [show rule selector]($styling/#show-rules) and with
diff --git a/crates/typst/src/eval/symbol.rs b/crates/typst/src/eval/symbol.rs
index d15a8915..8219ec58 100644
--- a/crates/typst/src/eval/symbol.rs
+++ b/crates/typst/src/eval/symbol.rs
@@ -47,7 +47,7 @@ pub use typst_macros::symbols;
pub struct Symbol(Repr);
/// The internal representation.
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
+#[derive(Clone, Eq, PartialEq, Hash)]
enum Repr {
Single(char),
Const(&'static [(&'static str, char)]),
@@ -55,7 +55,7 @@ enum Repr {
}
/// A collection of symbols.
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
+#[derive(Clone, Eq, PartialEq, Hash)]
enum List {
Static(&'static [(&'static str, char)]),
Runtime(Box<[(EcoString, char)]>),
@@ -214,6 +214,25 @@ impl Display for Symbol {
}
}
+impl Debug for Repr {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ match self {
+ Self::Single(c) => Debug::fmt(c, f),
+ Self::Const(list) => list.fmt(f),
+ Self::Multi(lists) => lists.fmt(f),
+ }
+ }
+}
+
+impl Debug for List {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ match self {
+ Self::Static(list) => list.fmt(f),
+ Self::Runtime(list) => list.fmt(f),
+ }
+ }
+}
+
impl super::Repr for Symbol {
fn repr(&self) -> EcoString {
eco_format!("\"{}\"", self.get())
diff --git a/crates/typst/src/eval/ty.rs b/crates/typst/src/eval/ty.rs
index 56cc7822..3dc8f555 100644
--- a/crates/typst/src/eval/ty.rs
+++ b/crates/typst/src/eval/ty.rs
@@ -53,7 +53,7 @@ pub use typst_macros::{scope, ty};
/// - The `{in}` operator on a type and a dictionary will evaluate to `{true}`
/// if the dictionary has a string key matching the type's name
#[ty(scope)]
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub struct Type(Static<NativeTypeData>);
impl Type {
@@ -139,6 +139,12 @@ impl Type {
}
}
+impl Debug for Type {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(f, "Type({})", self.long_name())
+ }
+}
+
impl Repr for Type {
fn repr(&self) -> EcoString {
self.long_name().into()
diff --git a/crates/typst/src/eval/value.rs b/crates/typst/src/eval/value.rs
index 51006da0..baf18aa0 100644
--- a/crates/typst/src/eval/value.rs
+++ b/crates/typst/src/eval/value.rs
@@ -1,6 +1,6 @@
use std::any::Any;
use std::cmp::Ordering;
-use std::fmt::{self, Debug};
+use std::fmt::{self, Debug, Formatter};
use std::hash::{Hash, Hasher};
use std::sync::Arc;
@@ -22,7 +22,7 @@ use crate::model::{Label, Styles};
use crate::syntax::{ast, Span};
/// A computational value.
-#[derive(Debug, Default, Clone)]
+#[derive(Default, Clone)]
pub enum Value {
/// The value that indicates the absence of a meaningful value.
#[default]
@@ -218,6 +218,42 @@ impl Value {
}
}
+impl Debug for Value {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ match self {
+ Self::None => Debug::fmt(&NoneValue, f),
+ Self::Auto => Debug::fmt(&AutoValue, f),
+ Self::Bool(v) => Debug::fmt(v, f),
+ Self::Int(v) => Debug::fmt(v, f),
+ Self::Float(v) => Debug::fmt(v, f),
+ Self::Length(v) => Debug::fmt(v, f),
+ Self::Angle(v) => Debug::fmt(v, f),
+ Self::Ratio(v) => Debug::fmt(v, f),
+ Self::Relative(v) => Debug::fmt(v, f),
+ Self::Fraction(v) => Debug::fmt(v, f),
+ Self::Color(v) => Debug::fmt(v, f),
+ Self::Gradient(v) => Debug::fmt(v, f),
+ Self::Symbol(v) => Debug::fmt(v, f),
+ Self::Version(v) => Debug::fmt(v, f),
+ Self::Str(v) => Debug::fmt(v, f),
+ Self::Bytes(v) => Debug::fmt(v, f),
+ Self::Label(v) => Debug::fmt(v, f),
+ Self::Datetime(v) => Debug::fmt(v, f),
+ Self::Duration(v) => Debug::fmt(v, f),
+ Self::Content(v) => Debug::fmt(v, f),
+ Self::Styles(v) => Debug::fmt(v, f),
+ Self::Array(v) => Debug::fmt(v, f),
+ Self::Dict(v) => Debug::fmt(v, f),
+ Self::Func(v) => Debug::fmt(v, f),
+ Self::Args(v) => Debug::fmt(v, f),
+ Self::Type(v) => Debug::fmt(v, f),
+ Self::Module(v) => Debug::fmt(v, f),
+ Self::Plugin(v) => Debug::fmt(v, f),
+ Self::Dyn(v) => Debug::fmt(v, f),
+ }
+ }
+}
+
impl Repr for Value {
fn repr(&self) -> EcoString {
match self {
@@ -446,7 +482,7 @@ impl<'de> Visitor<'de> for ValueVisitor {
}
/// A value that is not part of the built-in enum.
-#[derive(Debug, Clone, Hash)]
+#[derive(Clone, Hash)]
#[allow(clippy::derived_hash_with_manual_eq)]
pub struct Dynamic(Arc<dyn Bounds>);
@@ -475,6 +511,12 @@ impl Dynamic {
}
}
+impl Debug for Dynamic {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ self.0.fmt(f)
+ }
+}
+
impl Repr for Dynamic {
fn repr(&self) -> EcoString {
self.0.repr()
diff --git a/crates/typst/src/font/book.rs b/crates/typst/src/font/book.rs
index 6450c882..dbdfab15 100644
--- a/crates/typst/src/font/book.rs
+++ b/crates/typst/src/font/book.rs
@@ -1,5 +1,6 @@
use std::cmp::Reverse;
use std::collections::BTreeMap;
+use std::fmt::{self, Debug, Formatter};
use serde::{Deserialize, Serialize};
use ttf_parser::{name_id, PlatformId, Tag};
@@ -442,7 +443,7 @@ fn shared_prefix_words(left: &str, right: &str) -> usize {
/// - 2 codepoints inside (18, 19)
///
/// So the resulting encoding is `[2, 3, 4, 3, 3, 1, 2, 2]`.
-#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
+#[derive(Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
#[serde(transparent)]
pub struct Coverage(Vec<u32>);
@@ -498,6 +499,12 @@ impl Coverage {
}
}
+impl Debug for Coverage {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ f.pad("Coverage(..)")
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;
diff --git a/crates/typst/src/geom/abs.rs b/crates/typst/src/geom/abs.rs
index 3b56f5f2..2a57e368 100644
--- a/crates/typst/src/geom/abs.rs
+++ b/crates/typst/src/geom/abs.rs
@@ -1,7 +1,7 @@
use super::*;
/// An absolute length.
-#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Abs(Scalar);
impl Abs {
@@ -133,6 +133,12 @@ impl Numeric for Abs {
}
}
+impl Debug for Abs {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(f, "{:?}pt", self.to_pt())
+ }
+}
+
impl Repr for Abs {
fn repr(&self) -> EcoString {
format_float(self.to_pt(), Some(2), "pt")
diff --git a/crates/typst/src/geom/angle.rs b/crates/typst/src/geom/angle.rs
index 2c379f26..b2f29b75 100644
--- a/crates/typst/src/geom/angle.rs
+++ b/crates/typst/src/geom/angle.rs
@@ -12,7 +12,7 @@ use super::*;
/// #rotate(10deg)[Hello there!]
/// ```
#[ty(scope)]
-#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Angle(Scalar);
impl Angle {
@@ -119,6 +119,12 @@ impl Numeric for Angle {
}
}
+impl Debug for Angle {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(f, "{:?}deg", self.to_deg())
+ }
+}
+
impl Repr for Angle {
fn repr(&self) -> EcoString {
format_float(self.to_deg(), Some(2), "deg")
diff --git a/crates/typst/src/geom/color.rs b/crates/typst/src/geom/color.rs
index e8413ada..247b424b 100644
--- a/crates/typst/src/geom/color.rs
+++ b/crates/typst/src/geom/color.rs
@@ -154,7 +154,7 @@ const ANGLE_EPSILON: f32 = 1e-5;
/// }))
/// ```
#[ty(scope)]
-#[derive(Debug, Copy, Clone)]
+#[derive(Copy, Clone)]
pub enum Color {
/// A 32-bit luma color.
Luma(Luma),
@@ -174,54 +174,6 @@ pub enum Color {
Hsv(Hsv),
}
-impl From<Luma> for Color {
- fn from(c: Luma) -> Self {
- Self::Luma(c)
- }
-}
-
-impl From<Oklab> for Color {
- fn from(c: Oklab) -> Self {
- Self::Oklab(c)
- }
-}
-
-impl From<Oklch> for Color {
- fn from(c: Oklch) -> Self {
- Self::Oklch(c)
- }
-}
-
-impl From<Rgb> for Color {
- fn from(c: Rgb) -> Self {
- Self::Rgb(c)
- }
-}
-
-impl From<LinearRgb> for Color {
- fn from(c: LinearRgb) -> Self {
- Self::LinearRgb(c)
- }
-}
-
-impl From<Cmyk> for Color {
- fn from(c: Cmyk) -> Self {
- Self::Cmyk(c)
- }
-}
-
-impl From<Hsl> for Color {
- fn from(c: Hsl) -> Self {
- Self::Hsl(c)
- }
-}
-
-impl From<Hsv> for Color {
- fn from(c: Hsv) -> Self {
- Self::Hsv(c)
- }
-}
-
#[scope]
impl Color {
/// The module of preset color maps.
@@ -1379,6 +1331,48 @@ impl Color {
}
}
+impl Debug for Color {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ match self {
+ Self::Luma(v) => write!(f, "Luma({})", v.luma),
+ Self::Oklab(v) => write!(f, "Oklab({}, {}, {}, {})", v.l, v.a, v.b, v.alpha),
+ Self::Oklch(v) => {
+ write!(
+ f,
+ "Oklch({}, {}, {:?}, {})",
+ v.l,
+ v.chroma,
+ hue_angle(v.hue.into_degrees()),
+ v.alpha
+ )
+ }
+ Self::Rgb(v) => {
+ write!(f, "Rgb({}, {}, {}, {})", v.red, v.green, v.blue, v.alpha)
+ }
+ Self::LinearRgb(v) => {
+ write!(f, "LinearRgb({}, {}, {}, {})", v.red, v.green, v.blue, v.alpha)
+ }
+ Self::Cmyk(v) => write!(f, "Cmyk({}, {}, {}, {})", v.c, v.m, v.y, v.k),
+ Self::Hsl(v) => write!(
+ f,
+ "Hsl({:?}, {}, {}, {})",
+ hue_angle(v.hue.into_degrees()),
+ v.saturation,
+ v.lightness,
+ v.alpha
+ ),
+ Self::Hsv(v) => write!(
+ f,
+ "Hsv({:?}, {}, {}, {})",
+ hue_angle(v.hue.into_degrees()),
+ v.saturation,
+ v.value,
+ v.alpha
+ ),
+ }
+ }
+}
+
impl Repr for Color {
fn repr(&self) -> EcoString {
match self {
@@ -1435,20 +1429,14 @@ impl Repr for Color {
"oklch({}, {}, {})",
Ratio::new(c.l as _).repr(),
format_float(c.chroma as _, Some(3), ""),
- Angle::deg(
- c.hue.into_degrees().rem_euclid(360.0 + ANGLE_EPSILON) as _
- )
- .repr()
+ hue_angle(c.hue.into_degrees()).repr(),
)
} else {
eco_format!(
"oklch({}, {}, {}, {})",
Ratio::new(c.l as _).repr(),
format_float(c.chroma as _, Some(3), ""),
- Angle::deg(
- c.hue.into_degrees().rem_euclid(360.0 + ANGLE_EPSILON) as _
- )
- .repr(),
+ hue_angle(c.hue.into_degrees()).repr(),
Ratio::new(c.alpha as _).repr(),
)
}
@@ -1457,20 +1445,14 @@ impl Repr for Color {
if c.alpha == 1.0 {
eco_format!(
"color.hsl({}, {}, {})",
- Angle::deg(
- c.hue.into_degrees().rem_euclid(360.0 + ANGLE_EPSILON) as _
- )
- .repr(),
+ hue_angle(c.hue.into_degrees()).repr(),
Ratio::new(c.saturation as _).repr(),
Ratio::new(c.lightness as _).repr(),
)
} else {
eco_format!(
"color.hsl({}, {}, {}, {})",
- Angle::deg(
- c.hue.into_degrees().rem_euclid(360.0 + ANGLE_EPSILON) as _
- )
- .repr(),
+ hue_angle(c.hue.into_degrees()).repr(),
Ratio::new(c.saturation as _).repr(),
Ratio::new(c.lightness as _).repr(),
Ratio::new(c.alpha as _).repr(),
@@ -1481,20 +1463,14 @@ impl Repr for Color {
if c.alpha == 1.0 {
eco_format!(
"color.hsv({}, {}, {})",
- Angle::deg(
- c.hue.into_degrees().rem_euclid(360.0 + ANGLE_EPSILON) as _
- )
- .repr(),
+ hue_angle(c.hue.into_degrees()).repr(),
Ratio::new(c.saturation as _).repr(),
Ratio::new(c.value as _).repr(),
)
} else {
eco_format!(
"color.hsv({}, {}, {}, {})",
- Angle::deg(
- c.hue.into_degrees().rem_euclid(360.0 + ANGLE_EPSILON) as _
- )
- .repr(),
+ hue_angle(c.hue.into_degrees()).repr(),
Ratio::new(c.saturation as _).repr(),
Ratio::new(c.value as _).repr(),
Ratio::new(c.alpha as _).repr(),
@@ -1505,6 +1481,10 @@ impl Repr for Color {
}
}
+fn hue_angle(degrees: f32) -> Angle {
+ Angle::deg(degrees.rem_euclid(360.0 + ANGLE_EPSILON) as _)
+}
+
impl PartialEq for Color {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
@@ -1579,6 +1559,54 @@ impl FromStr for Color {
}
}
+impl From<Luma> for Color {
+ fn from(c: Luma) -> Self {
+ Self::Luma(c)
+ }
+}
+
+impl From<Oklab> for Color {
+ fn from(c: Oklab) -> Self {
+ Self::Oklab(c)
+ }
+}
+
+impl From<Oklch> for Color {
+ fn from(c: Oklch) -> Self {
+ Self::Oklch(c)
+ }
+}
+
+impl From<Rgb> for Color {
+ fn from(c: Rgb) -> Self {
+ Self::Rgb(c)
+ }
+}
+
+impl From<LinearRgb> for Color {
+ fn from(c: LinearRgb) -> Self {
+ Self::LinearRgb(c)
+ }
+}
+
+impl From<Cmyk> for Color {
+ fn from(c: Cmyk) -> Self {
+ Self::Cmyk(c)
+ }
+}
+
+impl From<Hsl> for Color {
+ fn from(c: Hsl) -> Self {
+ Self::Hsl(c)
+ }
+}
+
+impl From<Hsv> for Color {
+ fn from(c: Hsv) -> Self {
+ Self::Hsv(c)
+ }
+}
+
/// An 8-bit CMYK color.
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Cmyk {
@@ -1681,25 +1709,18 @@ cast! {
pub enum ColorSpace {
/// The perceptual Oklab color space.
Oklab,
-
/// The perceptual Oklch color space.
Oklch,
-
/// The standard RGB color space.
Srgb,
-
/// The D65-gray color space.
D65Gray,
-
/// The linear RGB color space.
LinearRgb,
-
/// The HSL color space.
Hsl,
-
/// The HSV color space.
Hsv,
-
/// The CMYK color space.
Cmyk,
}
diff --git a/crates/typst/src/geom/corners.rs b/crates/typst/src/geom/corners.rs
index bb8a4e4c..e0b45314 100644
--- a/crates/typst/src/geom/corners.rs
+++ b/crates/typst/src/geom/corners.rs
@@ -2,7 +2,7 @@ use super::*;
use crate::eval::{CastInfo, FromValue, IntoValue, Reflect};
/// A container with components for the four corners of a rectangle.
-#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Hash)]
+#[derive(Default, Copy, Clone, Eq, PartialEq, Hash)]
pub struct Corners<T> {
/// The value for the top left corner.
pub top_left: T,
@@ -96,57 +96,19 @@ impl<T> Get<Corner> for Corners<T> {
}
}
-/// The four corners of a rectangle.
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum Corner {
- /// The top left corner.
- TopLeft,
- /// The top right corner.
- TopRight,
- /// The bottom right corner.
- BottomRight,
- /// The bottom left corner.
- BottomLeft,
-}
-
-impl Corner {
- /// The next corner, clockwise.
- pub fn next_cw(self) -> Self {
- match self {
- Self::TopLeft => Self::TopRight,
- Self::TopRight => Self::BottomRight,
- Self::BottomRight => Self::BottomLeft,
- Self::BottomLeft => Self::TopLeft,
- }
- }
-
- /// The next corner, counter-clockwise.
- pub fn next_ccw(self) -> Self {
- match self {
- Self::TopLeft => Self::BottomLeft,
- Self::TopRight => Self::TopLeft,
- Self::BottomRight => Self::TopRight,
- Self::BottomLeft => Self::BottomRight,
- }
- }
-
- /// The next side, clockwise.
- pub fn side_cw(self) -> Side {
- match self {
- Self::TopLeft => Side::Top,
- Self::TopRight => Side::Right,
- Self::BottomRight => Side::Bottom,
- Self::BottomLeft => Side::Left,
- }
- }
-
- /// The next side, counter-clockwise.
- pub fn side_ccw(self) -> Side {
- match self {
- Self::TopLeft => Side::Left,
- Self::TopRight => Side::Top,
- Self::BottomRight => Side::Right,
- Self::BottomLeft => Side::Bottom,
+impl<T: Debug + PartialEq> Debug for Corners<T> {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ if self.is_uniform() {
+ f.write_str("Corners::splat(")?;
+ self.top_left.fmt(f)?;
+ f.write_str(")")
+ } else {
+ f.debug_struct("Corners")
+ .field("top_left", &self.top_left)
+ .field("top_right", &self.top_right)
+ .field("bottom_right", &self.bottom_right)
+ .field("bottom_left", &self.bottom_left)
+ .finish()
}
}
}
@@ -262,3 +224,58 @@ impl<T: Fold> Fold for Corners<Option<T>> {
})
}
}
+
+/// The four corners of a rectangle.
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub enum Corner {
+ /// The top left corner.
+ TopLeft,
+ /// The top right corner.
+ TopRight,
+ /// The bottom right corner.
+ BottomRight,
+ /// The bottom left corner.
+ BottomLeft,
+}
+
+impl Corner {
+ /// The next corner, clockwise.
+ pub fn next_cw(self) -> Self {
+ match self {
+ Self::TopLeft => Self::TopRight,
+ Self::TopRight => Self::BottomRight,
+ Self::BottomRight => Self::BottomLeft,
+ Self::BottomLeft => Self::TopLeft,
+ }
+ }
+
+ /// The next corner, counter-clockwise.
+ pub fn next_ccw(self) -> Self {
+ match self {
+ Self::TopLeft => Self::BottomLeft,
+ Self::TopRight => Self::TopLeft,
+ Self::BottomRight => Self::TopRight,
+ Self::BottomLeft => Self::BottomRight,
+ }
+ }
+
+ /// The next side, clockwise.
+ pub fn side_cw(self) -> Side {
+ match self {
+ Self::TopLeft => Side::Top,
+ Self::TopRight => Side::Right,
+ Self::BottomRight => Side::Bottom,
+ Self::BottomLeft => Side::Left,
+ }
+ }
+
+ /// The next side, counter-clockwise.
+ pub fn side_ccw(self) -> Side {
+ match self {
+ Self::TopLeft => Side::Left,
+ Self::TopRight => Side::Top,
+ Self::BottomRight => Side::Right,
+ Self::BottomLeft => Side::Bottom,
+ }
+ }
+}
diff --git a/crates/typst/src/geom/em.rs b/crates/typst/src/geom/em.rs
index 9cb0c55a..81c4a350 100644
--- a/crates/typst/src/geom/em.rs
+++ b/crates/typst/src/geom/em.rs
@@ -3,7 +3,7 @@ use super::*;
/// A length that is relative to the font size.
///
/// `1em` is the same as the font size.
-#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Em(Scalar);
impl Em {
@@ -68,6 +68,12 @@ impl Numeric for Em {
}
}
+impl Debug for Em {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(f, "{:?}em", self.get())
+ }
+}
+
impl Repr for Em {
fn repr(&self) -> EcoString {
format_float(self.get(), None, "em")
diff --git a/crates/typst/src/geom/fr.rs b/crates/typst/src/geom/fr.rs
index f0cb4250..fe4fed49 100644
--- a/crates/typst/src/geom/fr.rs
+++ b/crates/typst/src/geom/fr.rs
@@ -13,7 +13,7 @@ use super::*;
/// Left #h(1fr) Left-ish #h(2fr) Right
/// ```
#[ty(name = "fraction")]
-#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Fr(Scalar);
impl Fr {
@@ -63,6 +63,12 @@ impl Numeric for Fr {
}
}
+impl Debug for Fr {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(f, "{:?}fr", self.get())
+ }
+}
+
impl Repr for Fr {
fn repr(&self) -> EcoString {
format_float(self.get(), Some(2), "fr")
diff --git a/crates/typst/src/geom/gradient.rs b/crates/typst/src/geom/gradient.rs
index 9f1ac30b..f4a0c7e8 100644
--- a/crates/typst/src/geom/gradient.rs
+++ b/crates/typst/src/geom/gradient.rs
@@ -159,7 +159,7 @@ use crate::syntax::{Span, Spanned};
/// Typst predefines color maps that you can use with your gradients. See the
/// [`color`]($color/#predefined-color-maps) documentation for more details.
#[ty(scope)]
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+#[derive(Clone, PartialEq, Eq, Hash)]
pub enum Gradient {
Linear(Arc<LinearGradient>),
Radial(Arc<RadialGradient>),
@@ -828,6 +828,16 @@ impl Gradient {
}
}
+impl Debug for Gradient {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ match self {
+ Self::Linear(v) => v.fmt(f),
+ Self::Radial(v) => v.fmt(f),
+ Self::Conic(v) => v.fmt(f),
+ }
+ }
+}
+
impl Repr for Gradient {
fn repr(&self) -> EcoString {
match self {
diff --git a/crates/typst/src/geom/length.rs b/crates/typst/src/geom/length.rs
index b8db6e50..3027fbea 100644
--- a/crates/typst/src/geom/length.rs
+++ b/crates/typst/src/geom/length.rs
@@ -31,7 +31,7 @@ use crate::syntax::Span;
/// (that is, excluding the `em` component).
/// - `em`: The amount of `em` units in this length, as a [float]($float).
#[ty(scope)]
-#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Hash)]
+#[derive(Default, Copy, Clone, Eq, PartialEq, Hash)]
pub struct Length {
/// The absolute part.
pub abs: Abs,
@@ -126,6 +126,16 @@ impl Length {
}
}
+impl Debug for Length {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ match (self.abs.is_zero(), self.em.is_zero()) {
+ (false, false) => write!(f, "{:?} + {:?}", self.abs, self.em),
+ (true, false) => self.em.fmt(f),
+ (_, true) => self.abs.fmt(f),
+ }
+ }
+}
+
impl Repr for Length {
fn repr(&self) -> EcoString {
match (self.abs.is_zero(), self.em.is_zero()) {
diff --git a/crates/typst/src/geom/paint.rs b/crates/typst/src/geom/paint.rs
index 1277107f..2bedfe13 100644
--- a/crates/typst/src/geom/paint.rs
+++ b/crates/typst/src/geom/paint.rs
@@ -1,7 +1,7 @@
use super::*;
/// How a fill or stroke should be painted.
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
+#[derive(Clone, Eq, PartialEq, Hash)]
pub enum Paint {
/// A solid color.
Solid(Color),
@@ -32,15 +32,12 @@ impl Paint {
}
}
-impl<T: Into<Color>> From<T> for Paint {
- fn from(t: T) -> Self {
- Self::Solid(t.into())
- }
-}
-
-impl From<Gradient> for Paint {
- fn from(gradient: Gradient) -> Self {
- Self::Gradient(gradient)
+impl Debug for Paint {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ match self {
+ Self::Solid(v) => v.fmt(f),
+ Self::Gradient(v) => v.fmt(f),
+ }
}
}
@@ -53,6 +50,18 @@ impl Repr for Paint {
}
}
+impl<T: Into<Color>> From<T> for Paint {
+ fn from(t: T) -> Self {
+ Self::Solid(t.into())
+ }
+}
+
+impl From<Gradient> for Paint {
+ fn from(gradient: Gradient) -> Self {
+ Self::Gradient(gradient)
+ }
+}
+
cast! {
Paint,
self => match self {
diff --git a/crates/typst/src/geom/ratio.rs b/crates/typst/src/geom/ratio.rs
index b0a092ba..670eeb75 100644
--- a/crates/typst/src/geom/ratio.rs
+++ b/crates/typst/src/geom/ratio.rs
@@ -12,7 +12,7 @@ use super::*;
/// ]
/// ```
#[ty]
-#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Ratio(Scalar);
impl Ratio {
@@ -62,6 +62,12 @@ impl Ratio {
}
}
+impl Debug for Ratio {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(f, "{:?}%", self.get())
+ }
+}
+
impl Repr for Ratio {
fn repr(&self) -> EcoString {
format_float(self.get() * 100.0, Some(2), "%")
diff --git a/crates/typst/src/geom/rel.rs b/crates/typst/src/geom/rel.rs
index 09a737e7..a2c8643e 100644
--- a/crates/typst/src/geom/rel.rs
+++ b/crates/typst/src/geom/rel.rs
@@ -18,7 +18,7 @@ use super::*;
/// - `length`: Its length component.
/// - `ratio`: Its ratio component.
#[ty(name = "relative", title = "Relative Length")]
-#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Hash)]
+#[derive(Default, Copy, Clone, Eq, PartialEq, Hash)]
pub struct Rel<T: Numeric = Length> {
/// The relative part.
pub rel: Ratio,
@@ -80,6 +80,16 @@ impl Rel<Length> {
}
}
+impl<T: Numeric + Debug> Debug for Rel<T> {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ match (self.rel.is_zero(), self.abs.is_zero()) {
+ (false, false) => write!(f, "{:?} + {:?}", self.rel, self.abs),
+ (false, true) => self.rel.fmt(f),
+ (true, _) => self.abs.fmt(f),
+ }
+ }
+}
+
impl<T: Numeric + Repr> Repr for Rel<T> {
fn repr(&self) -> EcoString {
match (self.rel.is_zero(), self.abs.is_zero()) {
diff --git a/crates/typst/src/geom/scalar.rs b/crates/typst/src/geom/scalar.rs
index 45e00f5c..a2b966da 100644
--- a/crates/typst/src/geom/scalar.rs
+++ b/crates/typst/src/geom/scalar.rs
@@ -3,7 +3,7 @@ use super::*;
/// A 64-bit float that implements `Eq`, `Ord` and `Hash`.
///
/// Panics if it's `NaN` during any of those operations.
-#[derive(Debug, Default, Copy, Clone)]
+#[derive(Default, Copy, Clone)]
pub struct Scalar(f64);
// We have to detect NaNs this way since `f64::is_nan` isn’t const
@@ -49,15 +49,9 @@ impl Numeric for Scalar {
}
}
-impl From<f64> for Scalar {
- fn from(float: f64) -> Self {
- Self::new(float)
- }
-}
-
-impl From<Scalar> for f64 {
- fn from(scalar: Scalar) -> Self {
- scalar.0
+impl Debug for Scalar {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ self.0.fmt(f)
}
}
@@ -101,6 +95,18 @@ impl Hash for Scalar {
}
}
+impl From<f64> for Scalar {
+ fn from(float: f64) -> Self {
+ Self::new(float)
+ }
+}
+
+impl From<Scalar> for f64 {
+ fn from(scalar: Scalar) -> Self {
+ scalar.0
+ }
+}
+
impl Neg for Scalar {
type Output = Self;
diff --git a/crates/typst/src/geom/sides.rs b/crates/typst/src/geom/sides.rs
index 38477f36..2ca7ca6a 100644
--- a/crates/typst/src/geom/sides.rs
+++ b/crates/typst/src/geom/sides.rs
@@ -1,8 +1,10 @@
+use std::fmt::{self, Debug, Formatter};
+
use super::*;
use crate::eval::{CastInfo, FromValue, IntoValue, Reflect};
/// A container with left, top, right and bottom components.
-#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Hash)]
+#[derive(Default, Copy, Clone, Eq, PartialEq, Hash)]
pub struct Sides<T> {
/// The value for the left side.
pub left: T,
@@ -121,86 +123,23 @@ impl<T> Get<Side> for Sides<T> {
}
}
-/// The four sides of objects.
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum Side {
- /// The left side.
- Left,
- /// The top side.
- Top,
- /// The right side.
- Right,
- /// The bottom side.
- Bottom,
-}
-
-impl Side {
- /// The opposite side.
- pub fn inv(self) -> Self {
- match self {
- Self::Left => Self::Right,
- Self::Top => Self::Bottom,
- Self::Right => Self::Left,
- Self::Bottom => Self::Top,
- }
- }
-
- /// The next side, clockwise.
- pub fn next_cw(self) -> Self {
- match self {
- Self::Left => Self::Top,
- Self::Top => Self::Right,
- Self::Right => Self::Bottom,
- Self::Bottom => Self::Left,
- }
- }
-
- /// The next side, counter-clockwise.
- pub fn next_ccw(self) -> Self {
- match self {
- Self::Left => Self::Bottom,
- Self::Top => Self::Left,
- Self::Right => Self::Top,
- Self::Bottom => Self::Right,
- }
- }
-
- /// The first corner of the side in clockwise order.
- pub fn start_corner(self) -> Corner {
- match self {
- Self::Left => Corner::BottomLeft,
- Self::Top => Corner::TopLeft,
- Self::Right => Corner::TopRight,
- Self::Bottom => Corner::BottomRight,
- }
- }
-
- /// The second corner of the side in clockwise order.
- pub fn end_corner(self) -> Corner {
- self.next_cw().start_corner()
- }
-
- /// Return the corresponding axis.
- pub fn axis(self) -> Axis {
- match self {
- Self::Left | Self::Right => Axis::Y,
- Self::Top | Self::Bottom => Axis::X,
+impl<T: Debug + PartialEq> Debug for Sides<T> {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ if self.is_uniform() {
+ f.write_str("Sides::splat(")?;
+ self.left.fmt(f)?;
+ f.write_str(")")
+ } else {
+ f.debug_struct("Sides")
+ .field("left", &self.left)
+ .field("top", &self.top)
+ .field("right", &self.right)
+ .field("bottom", &self.bottom)
+ .finish()
}
}
}
-cast! {
- Side,
- self => Align::from(self).into_value(),
- align: Align => match align {
- Align::LEFT => Self::Left,
- Align::RIGHT => Self::Right,
- Align::TOP => Self::Top,
- Align::BOTTOM => Self::Bottom,
- _ => bail!("cannot convert this alignment to a side"),
- },
-}
-
impl<T: Reflect> Reflect for Sides<Option<T>> {
fn input() -> CastInfo {
T::input() + Dict::input()
@@ -291,3 +230,83 @@ impl<T: Fold> Fold for Sides<Option<T>> {
})
}
}
+
+/// The four sides of objects.
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub enum Side {
+ /// The left side.
+ Left,
+ /// The top side.
+ Top,
+ /// The right side.
+ Right,
+ /// The bottom side.
+ Bottom,
+}
+
+impl Side {
+ /// The opposite side.
+ pub fn inv(self) -> Self {
+ match self {
+ Self::Left => Self::Right,
+ Self::Top => Self::Bottom,
+ Self::Right => Self::Left,
+ Self::Bottom => Self::Top,
+ }
+ }
+
+ /// The next side, clockwise.
+ pub fn next_cw(self) -> Self {
+ match self {
+ Self::Left => Self::Top,
+ Self::Top => Self::Right,
+ Self::Right => Self::Bottom,
+ Self::Bottom => Self::Left,
+ }
+ }
+
+ /// The next side, counter-clockwise.
+ pub fn next_ccw(self) -> Self {
+ match self {
+ Self::Left => Self::Bottom,
+ Self::Top => Self::Left,
+ Self::Right => Self::Top,
+ Self::Bottom => Self::Right,
+ }
+ }
+
+ /// The first corner of the side in clockwise order.
+ pub fn start_corner(self) -> Corner {
+ match self {
+ Self::Left => Corner::BottomLeft,
+ Self::Top => Corner::TopLeft,
+ Self::Right => Corner::TopRight,
+ Self::Bottom => Corner::BottomRight,
+ }
+ }
+
+ /// The second corner of the side in clockwise order.
+ pub fn end_corner(self) -> Corner {
+ self.next_cw().start_corner()
+ }
+
+ /// Return the corresponding axis.
+ pub fn axis(self) -> Axis {
+ match self {
+ Self::Left | Self::Right => Axis::Y,
+ Self::Top | Self::Bottom => Axis::X,
+ }
+ }
+}
+
+cast! {
+ Side,
+ self => Align::from(self).into_value(),
+ align: Align => match align {
+ Align::LEFT => Self::Left,
+ Align::RIGHT => Self::Right,
+ Align::TOP => Self::Top,
+ Align::BOTTOM => Self::Bottom,
+ _ => bail!("cannot convert this alignment to a side"),
+ },
+}
diff --git a/crates/typst/src/model/block.rs b/crates/typst/src/model/block.rs
index 92e2a18e..c1370c20 100644
--- a/crates/typst/src/model/block.rs
+++ b/crates/typst/src/model/block.rs
@@ -27,6 +27,12 @@ impl Block {
}
}
+impl Debug for Block {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ self.0.fmt(f)
+ }
+}
+
impl Hash for Block {
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.dyn_hash(state);
@@ -39,12 +45,6 @@ impl Clone for Block {
}
}
-impl Debug for Block {
- fn fmt(&self, f: &mut Formatter) -> fmt::Result {
- self.0.fmt(f)
- }
-}
-
/// A value that can be stored in a block.
///
/// Auto derived for all types that implement [`Any`], [`Clone`], [`Hash`],
diff --git a/crates/typst/src/model/content.rs b/crates/typst/src/model/content.rs
index 4b9f11de..48f84c35 100644
--- a/crates/typst/src/model/content.rs
+++ b/crates/typst/src/model/content.rs
@@ -1,5 +1,5 @@
use std::any::TypeId;
-use std::fmt::Debug;
+use std::fmt::{self, Debug, Formatter};
use std::iter::{self, Sum};
use std::ops::{Add, AddAssign};
use std::sync::Arc;
@@ -65,7 +65,7 @@ use crate::syntax::Span;
/// elements the content is composed of and what fields they have.
/// Alternatively, you can inspect the output of the [`repr`]($repr) function.
#[ty(scope)]
-#[derive(Debug, Clone)]
+#[derive(Clone)]
pub struct Content(Arc<dyn NativeElement>);
impl Content {
@@ -534,6 +534,12 @@ impl Default for Content {
}
}
+impl Debug for Content {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ self.0.fmt(f)
+ }
+}
+
impl<T: NativeElement> From<T> for Content {
fn from(value: T) -> Self {
Self::new(value)
diff --git a/crates/typst/src/model/element.rs b/crates/typst/src/model/element.rs
index 7551f83b..95e2befb 100644
--- a/crates/typst/src/model/element.rs
+++ b/crates/typst/src/model/element.rs
@@ -117,7 +117,7 @@ impl Element {
impl Debug for Element {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.pad(self.name())
+ write!(f, "Element({})", self.name())
}
}
diff --git a/crates/typst/src/model/label.rs b/crates/typst/src/model/label.rs
index 8886b370..ae2a15c7 100644
--- a/crates/typst/src/model/label.rs
+++ b/crates/typst/src/model/label.rs
@@ -66,7 +66,7 @@ impl Label {
impl Repr for Label {
fn repr(&self) -> EcoString {
- eco_format!("<{}>", self.0.resolve())
+ eco_format!("<{}>", self.as_str())
}
}
diff --git a/crates/typst/src/model/styles.rs b/crates/typst/src/model/styles.rs
index dc65f176..5566b839 100644
--- a/crates/typst/src/model/styles.rs
+++ b/crates/typst/src/model/styles.rs
@@ -1,5 +1,5 @@
use std::borrow::Cow;
-use std::fmt::{self, Debug, Formatter, Write};
+use std::fmt::{self, Debug, Formatter};
use std::iter;
use std::mem;
use std::ptr;
@@ -16,7 +16,7 @@ use crate::syntax::Span;
/// A list of style properties.
#[ty]
-#[derive(Debug, Default, PartialEq, Clone, Hash)]
+#[derive(Default, PartialEq, Clone, Hash)]
pub struct Styles(EcoVec<Prehashed<Style>>);
impl Styles {
@@ -89,6 +89,13 @@ impl From<Style> for Styles {
}
}
+impl Debug for Styles {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ f.write_str("Styles ")?;
+ f.debug_list().entries(&self.0).finish()
+ }
+}
+
impl Repr for Styles {
fn repr(&self) -> EcoString {
"..".into()
@@ -175,8 +182,14 @@ impl Property {
impl Debug for Property {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
- write!(f, "set {}({}: {:?})", self.elem.name(), self.id, self.value)?;
- Ok(())
+ write!(
+ f,
+ "Set({}.{}: ",
+ self.elem.name(),
+ self.elem.field_name(self.id).unwrap()
+ )?;
+ self.value.fmt(f)?;
+ write!(f, ")")
}
}
@@ -244,12 +257,11 @@ impl Recipe {
impl Debug for Recipe {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
- f.write_str("show")?;
+ f.write_str("Show(")?;
if let Some(selector) = &self.selector {
- f.write_char(' ')?;
selector.fmt(f)?;
+ f.write_str(", ")?;
}
- f.write_str(": ")?;
self.transform.fmt(f)
}
}
@@ -469,10 +481,10 @@ impl<'a> StyleChain<'a> {
impl Debug for StyleChain<'_> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
- for entry in self.entries().collect::<Vec<_>>().into_iter().rev() {
- writeln!(f, "{:?}", entry)?;
- }
- Ok(())
+ f.write_str("StyleChain ")?;
+ f.debug_list()
+ .entries(self.entries().collect::<Vec<_>>().into_iter().rev())
+ .finish()
}
}
diff --git a/crates/typst/src/util/deferred.rs b/crates/typst/src/util/deferred.rs
index 0803d236..5a902e23 100644
--- a/crates/typst/src/util/deferred.rs
+++ b/crates/typst/src/util/deferred.rs
@@ -35,7 +35,6 @@ impl<T: Send + Sync + 'static> Deferred<T> {
// Ensure that we yield to give the deferred value a chance to compute
// single-threaded platforms (for WASM compatibility).
while let Some(rayon::Yield::Executed) = rayon::yield_now() {}
-
self.0.wait()
}
}