From 3cb06baa98e88e8f3fb1479027a174af601d1743 Mon Sep 17 00:00:00 2001 From: tinger Date: Wed, 16 Jul 2025 11:53:46 +0200 Subject: [PATCH] Add version to `Binding` deprecation warnings This allows displaying a hint in which the version a binding may be removed in. It helps to signal how urgent a package update may be to package authors. --- crates/typst-library/src/diag.rs | 15 ++++++++++----- crates/typst-library/src/foundations/scope.rs | 15 ++++++++++++++- crates/typst-library/src/foundations/symbol.rs | 2 +- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/crates/typst-library/src/diag.rs b/crates/typst-library/src/diag.rs index 41b92ed65..3f2c5a6cc 100644 --- a/crates/typst-library/src/diag.rs +++ b/crates/typst-library/src/diag.rs @@ -234,18 +234,23 @@ impl From for SourceDiagnostic { /// Destination for a deprecation message when accessing a deprecated value. pub trait DeprecationSink { - /// Emits the given deprecation message into this sink. - fn emit(self, message: &str); + /// Emits the given deprecation message into this sink alongside a version + /// in which the deprecated item is planned to be removed. + fn emit(self, message: &str, until: Option<&str>); } impl DeprecationSink for () { - fn emit(self, _: &str) {} + fn emit(self, _: &str, _: Option<&str>) {} } impl DeprecationSink for (&mut Engine<'_>, Span) { /// Emits the deprecation message as a warning. - fn emit(self, message: &str) { - self.0.sink.warn(SourceDiagnostic::warning(self.1, message)); + fn emit(self, message: &str, version: Option<&str>) { + self.0.sink.warn( + SourceDiagnostic::warning(self.1, message).with_hints( + version.map(|v| eco_format!("this will be removed in {}", v)), + ), + ); } } diff --git a/crates/typst-library/src/foundations/scope.rs b/crates/typst-library/src/foundations/scope.rs index 838584ccd..efed73bc1 100644 --- a/crates/typst-library/src/foundations/scope.rs +++ b/crates/typst-library/src/foundations/scope.rs @@ -255,6 +255,10 @@ pub struct Binding { category: Option, /// A deprecation message for the definition. deprecation: Option<&'static str>, + /// A version in which the deprecated binding is planned to be removed. + /// + /// This is ignored if `deprecation` is `None`. + until: Option<&'static str>, } /// The different kinds of slots. @@ -275,6 +279,7 @@ impl Binding { kind: BindingKind::Normal, category: None, deprecation: None, + until: None, } } @@ -289,6 +294,14 @@ impl Binding { self } + /// Set the version in which the binding is planned to be removed. + /// + /// This is ignored if [`Binding::deprecated`] isn't also set. + pub fn until(&mut self, version: &'static str) -> &mut Self { + self.until = Some(version); + self + } + /// Read the value. pub fn read(&self) -> &Value { &self.value @@ -301,7 +314,7 @@ impl Binding { /// - pass `(&mut engine, span)` to emit a warning into the engine. pub fn read_checked(&self, sink: impl DeprecationSink) -> &Value { if let Some(message) = self.deprecation { - sink.emit(message); + sink.emit(message, self.until); } &self.value } diff --git a/crates/typst-library/src/foundations/symbol.rs b/crates/typst-library/src/foundations/symbol.rs index f57bb0c2a..953135c2d 100644 --- a/crates/typst-library/src/foundations/symbol.rs +++ b/crates/typst-library/src/foundations/symbol.rs @@ -151,7 +151,7 @@ impl Symbol { modifiers.best_match_in(list.variants().map(|(m, _, d)| (m, d))) { if let Some(message) = deprecation { - sink.emit(message) + sink.emit(message, None) } return Ok(self); }