summaryrefslogtreecommitdiff
path: root/crates/typst-library/src
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2024-11-29 16:03:08 +0100
committerGitHub <noreply@github.com>2024-11-29 15:03:08 +0000
commitd40c8ab6ab4f7051a12e5ce9433439f3a5afb99f (patch)
tree8e5b2972b1c5ede14a05ae5525c4a07fb3dda300 /crates/typst-library/src
parent055263ee9f2253de9f176970df9d47d3b2bd2467 (diff)
Compile-time `PicoStr` interning (#5491)
Diffstat (limited to 'crates/typst-library/src')
-rw-r--r--crates/typst-library/src/foundations/label.rs20
-rw-r--r--crates/typst-library/src/foundations/str.rs9
-rw-r--r--crates/typst-library/src/model/bibliography.rs23
3 files changed, 22 insertions, 30 deletions
diff --git a/crates/typst-library/src/foundations/label.rs b/crates/typst-library/src/foundations/label.rs
index 726958df..2f5520b1 100644
--- a/crates/typst-library/src/foundations/label.rs
+++ b/crates/typst-library/src/foundations/label.rs
@@ -1,7 +1,7 @@
use ecow::{eco_format, EcoString};
-use typst_utils::PicoStr;
+use typst_utils::{PicoStr, ResolvedPicoStr};
-use crate::foundations::{func, scope, ty, Repr};
+use crate::foundations::{func, scope, ty, Repr, Str};
/// A label for an element.
///
@@ -45,17 +45,17 @@ use crate::foundations::{func, scope, ty, Repr};
/// Currently, labels can only be attached to elements in markup mode, not in
/// code mode. This might change in the future.
#[ty(scope, cast)]
-#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct Label(PicoStr);
impl Label {
- /// Creates a label from a string, interning it.
- pub fn new(name: impl Into<PicoStr>) -> Self {
- Self(name.into())
+ /// Creates a label from an interned string.
+ pub fn new(name: PicoStr) -> Self {
+ Self(name)
}
/// Resolves the label to a string.
- pub fn as_str(&self) -> &'static str {
+ pub fn resolve(self) -> ResolvedPicoStr {
self.0.resolve()
}
@@ -71,15 +71,15 @@ impl Label {
#[func(constructor)]
pub fn construct(
/// The name of the label.
- name: PicoStr,
+ name: Str,
) -> Label {
- Self(name)
+ Self(PicoStr::intern(name.as_str()))
}
}
impl Repr for Label {
fn repr(&self) -> EcoString {
- eco_format!("<{}>", self.as_str())
+ eco_format!("<{}>", self.resolve())
}
}
diff --git a/crates/typst-library/src/foundations/str.rs b/crates/typst-library/src/foundations/str.rs
index 1431e9f9..72fdcc53 100644
--- a/crates/typst-library/src/foundations/str.rs
+++ b/crates/typst-library/src/foundations/str.rs
@@ -7,7 +7,6 @@ use comemo::Tracked;
use ecow::EcoString;
use serde::{Deserialize, Serialize};
use typst_syntax::{Span, Spanned};
-use typst_utils::PicoStr;
use unicode_segmentation::UnicodeSegmentation;
use crate::diag::{bail, At, SourceResult, StrResult};
@@ -754,12 +753,6 @@ cast! {
}
cast! {
- PicoStr,
- self => Value::Str(self.resolve().into()),
- v: Str => v.as_str().into(),
-}
-
-cast! {
String,
self => Value::Str(self.into()),
v: Str => v.into(),
@@ -784,7 +777,7 @@ cast! {
.map_err(|_| "bytes are not valid utf-8")?
.into()
),
- v: Label => Self::Str(v.as_str().into()),
+ v: Label => Self::Str(v.resolve().as_str().into()),
v: Type => Self::Str(v.long_name().into()),
v: Str => Self::Str(v),
}
diff --git a/crates/typst-library/src/model/bibliography.rs b/crates/typst-library/src/model/bibliography.rs
index 56916731..280ac4a4 100644
--- a/crates/typst-library/src/model/bibliography.rs
+++ b/crates/typst-library/src/model/bibliography.rs
@@ -179,16 +179,13 @@ impl BibliographyElem {
}
/// Find all bibliography keys.
- pub fn keys(
- introspector: Tracked<Introspector>,
- ) -> Vec<(EcoString, Option<EcoString>)> {
+ pub fn keys(introspector: Tracked<Introspector>) -> Vec<(Label, Option<EcoString>)> {
let mut vec = vec![];
for elem in introspector.query(&Self::elem().select()).iter() {
let this = elem.to_packed::<Self>().unwrap();
- for entry in this.bibliography().entries() {
- let key = entry.key().into();
+ for (key, entry) in this.bibliography().iter() {
let detail = entry.title().map(|title| title.value.to_str().into());
- vec.push((key, detail))
+ vec.push((Label::new(key), detail))
}
}
vec
@@ -341,7 +338,7 @@ impl Bibliography {
};
for entry in library {
- match map.entry(entry.key().into()) {
+ match map.entry(PicoStr::intern(entry.key())) {
indexmap::map::Entry::Vacant(vacant) => {
vacant.insert(entry);
}
@@ -366,8 +363,8 @@ impl Bibliography {
self.map.contains_key(&key.into())
}
- fn entries(&self) -> impl Iterator<Item = &hayagriva::Entry> {
- self.map.values()
+ fn iter(&self) -> impl Iterator<Item = (PicoStr, &hayagriva::Entry)> {
+ self.map.iter().map(|(&k, v)| (k, v))
}
}
@@ -661,7 +658,7 @@ impl<'a> Generator<'a> {
errors.push(error!(
child.span(),
"key `{}` does not exist in the bibliography",
- key.as_str()
+ key.resolve()
));
continue;
};
@@ -775,7 +772,9 @@ impl<'a> Generator<'a> {
let mut output = std::mem::take(&mut self.failures);
for (info, citation) in self.infos.iter().zip(&rendered.citations) {
let supplement = |i: usize| info.subinfos.get(i)?.supplement.clone();
- let link = |i: usize| links.get(info.subinfos.get(i)?.key.as_str()).copied();
+ let link = |i: usize| {
+ links.get(info.subinfos.get(i)?.key.resolve().as_str()).copied()
+ };
let renderer = ElemRenderer {
routines: self.routines,
@@ -820,7 +819,7 @@ impl<'a> Generator<'a> {
let mut first_occurrences = HashMap::new();
for info in &self.infos {
for subinfo in &info.subinfos {
- let key = subinfo.key.as_str();
+ let key = subinfo.key.resolve();
first_occurrences.entry(key).or_insert(info.location);
}
}