diff --git a/codespan-reporting/CHANGELOG.md b/codespan-reporting/CHANGELOG.md index 14c47660..63ba2a91 100644 --- a/codespan-reporting/CHANGELOG.md +++ b/codespan-reporting/CHANGELOG.md @@ -64,6 +64,8 @@ This is because some testing dependencies now require this Rust version. ``` +- `Label`s can now be created without specifying a file id and instead later setting + the file id on a `Label` or all labels in a `Diagnostic`. ## [0.11.1] - 2021-01-18 diff --git a/codespan-reporting/src/diagnostic.rs b/codespan-reporting/src/diagnostic.rs index 8e3abf4f..871039cf 100644 --- a/codespan-reporting/src/diagnostic.rs +++ b/codespan-reporting/src/diagnostic.rs @@ -85,11 +85,58 @@ impl Label { Label::new(LabelStyle::Secondary, file_id, range) } - /// Add a message to the diagnostic. + /// Set the message for the diagnostic. The old message (if any) is discarded. pub fn with_message(mut self, message: impl ToString) -> Label { self.message = message.to_string(); self } + + /// Set the file id. The old file id (if any) is discarded. + pub fn with_file(self, file_id: NewFileId) -> Label { + Label { + style: self.style, + file_id, + range: self.range, + message: self.message, + } + } +} + +// use a separate impl so we do not have to specify the type like this in e.g. +// `primary_anon`: +// ``` +// Label::<()>::new_anon(..) +// ``` +impl Label<()> { + /// Create a new label without specifying a [`file_id`]. + /// + /// [`file_id`]: Label::file_id + pub fn new_anon(style: LabelStyle, range: impl Into>) -> Label<()> { + Label { + style, + file_id: (), + range: range.into(), + message: String::new(), + } + } + + /// Create a new label with a style of [`LabelStyle::Primary`] and without + /// specifying a [`file_id`]. + /// + /// [`LabelStyle::Primary`]: LabelStyle::Primary + /// [`file_id`]: Label::file_id + pub fn primary_anon(range: impl Into>) -> Label<()> { + Label::new_anon(LabelStyle::Primary, range) + } + + /// Create a new label with a style of [`LabelStyle::Secondary`] and without + /// specifying a [`file_id`]. + /// + /// [`LabelStyle::Secondary`]: LabelStyle::Secondary + /// [`file_id`]: Label::file_id + pub fn secondary_anon(range: impl Into>) -> Label<()> { + Label::new_anon(LabelStyle::Secondary, range) + } } /// Represents a diagnostic message that can provide information like errors and @@ -188,4 +235,20 @@ impl Diagnostic { self.notes.append(&mut notes); self } + + /// Set the file id for all labels in this Diagnostic by calling + /// [`Label::with_file`] on each label. + pub fn with_file(mut self, file_id: NewFileId) -> Diagnostic { + Diagnostic { + severity: self.severity, + code: self.code, + message: self.message, + labels: self + .labels + .drain(..) + .map(|label| label.with_file(file_id.clone())) + .collect(), + notes: self.notes, + } + } }