More useful Debug
impls
This commit is contained in:
parent
2da619e17c
commit
c97a01616a
@ -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);
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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())))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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() {
|
||||
|
@ -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())
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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())
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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::*;
|
||||
|
@ -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")
|
||||
|
@ -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")
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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")
|
||||
|
@ -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")
|
||||
|
@ -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 {
|
||||
|
@ -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()) {
|
||||
|
@ -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 {
|
||||
|
@ -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), "%")
|
||||
|
@ -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()) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,84 +123,21 @@ 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,
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
/// 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"),
|
||||
},
|
||||
}
|
||||
|
||||
impl<T: Reflect> Reflect for Sides<Option<T>> {
|
||||
@ -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"),
|
||||
},
|
||||
}
|
||||
|
@ -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`],
|
||||
|
@ -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)
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ impl Label {
|
||||
|
||||
impl Repr for Label {
|
||||
fn repr(&self) -> EcoString {
|
||||
eco_format!("<{}>", self.0.resolve())
|
||||
eco_format!("<{}>", self.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user