Repository: swc-project/swc
File: crates/swc_error_reporters/src/diagnostic.rs (Rust)

Code before:

// For readable diagnostic, then render by miette
impl ToPrettyDiagnostic for Diagnostic {
    /// Returns a pretty-printed of the diagnostic.
    fn to_pretty_diagnostic<'a>(
        &'a self,
        cm: &'a SourceMap,
        skip_filename: bool,
    ) -> PrettyDiagnostic<'a> {
        PrettyDiagnostic::new(self, cm, skip_filename)
    }

    /// Converts the diagnostic into a pretty-printed string, suitable for
    /// display.
    ///
    /// This method is used to generate a human-readable string representation
    /// of the diagnostic. It utilizes the `PrettyDiagnostic` struct to
    /// format the diagnostic information.
    ///
    /// # Parameters
    ///
    /// - `cm`: A reference to the `SourceMap` used for mapping source code
    ///   locations.
    /// - `skip_filename`: A boolean indicating whether to skip including
    ///   filenames in the output.
    /// - `handler`: A reference to the `GraphicalReportHandler` used for
    ///   handling graphical reports.
    ///
    /// # Returns
    ///
    /// A `String` containing the pretty-printed diagnostic information.
    fn to_pretty_string<'a>(
        &self,
        cm: &'a SourceMap,
        skip_filename: bool,
        handler: &'a GraphicalReportHandler,
    ) -> String {
        let pretty_diagnostic = PrettyDiagnostic::new(self, cm, skip_filename);
        pretty_diagnostic.to_pretty_string(handler)
    }
}


Review comment (bug):
Using saturating_sub could mask a logic error when end < start (invalid span). Instead of silently producing a zero-length span, consider validating that end >= start and returning an error or using a more explicit handling strategy.
```suggestion
    debug_assert!(end >= start, "Span has hi < lo: {:?}", span);
    let len = if end >= start { end - start } else { 0 };

    SourceSpan::new(SourceOffset::from(start), len)
```

Code after:

    fn line_count(&self) -> usize {
        self.line_count
    }

    fn name(&self) -> Option<&str> {
        self.name.as_deref()
    }
}

fn level_to_severity(level: Level) -> Option<Severity> {
    match level {
        Level::FailureNote | Level::Bug | Level::Fatal | Level::PhaseFatal | Level::Error => {
            Some(Severity::Error)
        }
        Level::Warning => Some(Severity::Warning),
        Level::Note | Level::Help => Some(Severity::Advice),
        Level::Cancelled => None,
    }
}

pub fn convert_span(span: Span) -> SourceSpan {
    let start = span.lo.0 as usize;
    let end = span.hi.0 as usize;

    SourceSpan::new(SourceOffset::from(start), end.saturating_sub(start))
}

pub trait ToPrettyDiagnostic {
    fn to_pretty_diagnostic<'a>(
        &'a self,
        cm: &'a SourceMap,
        skip_filename: bool,
    ) -> PrettyDiagnostic<'a>;

    fn to_pretty_string<'a>(
        &self,
        cm: &'a SourceMap,
        skip_filename: bool,
        handler: &'a GraphicalReportHandler,
    ) -> String;
}

// For readable diagnostic, then render by miette
impl ToPrettyDiagnostic for Diagnostic {
    /// Returns a pretty-printed of the diagnostic.
    fn to_pretty_diagnostic<'a>(
        &'a self,
        cm: &'a SourceMap,
        skip_filename: bool,
    ) -> PrettyDiagnostic<'a> {