testing/
string_errors.rs

1use std::{
2    fmt,
3    io::{self, Write},
4    sync::{Arc, RwLock},
5};
6
7use swc_common::{
8    errors::{Emitter, Handler, HandlerFlags},
9    sync::Lrc,
10    SourceMap,
11};
12use swc_error_reporters::{GraphicalReportHandler, GraphicalTheme, ToPrettyDiagnostic};
13
14use super::StdErr;
15use crate::errors::{multi_emitter, stderr::stderr_emitter};
16
17/// Creates a new handler for testing.
18pub(crate) fn new_handler(cm: Lrc<SourceMap>, treat_err_as_bug: bool) -> (Handler, BufferedError) {
19    let buffer: BufferedError = Default::default();
20
21    let buffered_emitter = BufferedEmitter {
22        cm: cm.clone(),
23        report: GraphicalReportHandler::default().with_theme(GraphicalTheme::none()),
24        buffer: buffer.clone(),
25    };
26
27    let emitter = multi_emitter(Box::new(buffered_emitter), stderr_emitter(cm));
28    let handler = Handler::with_emitter_and_flags(
29        emitter,
30        HandlerFlags {
31            treat_err_as_bug,
32            ..Default::default()
33        },
34    );
35
36    (handler, buffer)
37}
38
39pub struct BufferedEmitter {
40    cm: Lrc<SourceMap>,
41    report: GraphicalReportHandler,
42    buffer: BufferedError,
43}
44
45impl Emitter for BufferedEmitter {
46    fn emit(&mut self, db: &mut swc_common::errors::DiagnosticBuilder<'_>) {
47        let d = &**db;
48        let pretty_string = d.to_pretty_string(&self.cm, false, &self.report);
49        let _ = self.buffer.write(pretty_string.as_bytes()).unwrap();
50    }
51}
52
53#[derive(Clone, Default)]
54pub(crate) struct BufferedError(Arc<RwLock<Vec<u8>>>);
55
56impl Write for BufferedError {
57    fn write(&mut self, d: &[u8]) -> io::Result<usize> {
58        self.0.write().unwrap().write(d)
59    }
60
61    fn flush(&mut self) -> io::Result<()> {
62        Ok(())
63    }
64}
65impl From<BufferedError> for StdErr {
66    fn from(buf: BufferedError) -> Self {
67        let s = buf.0.read().unwrap();
68        let s: String = String::from_utf8_lossy(&s).into();
69
70        s.into()
71    }
72}
73
74impl fmt::Write for BufferedError {
75    fn write_str(&mut self, s: &str) -> fmt::Result {
76        self.write(s.as_bytes()).map_err(|_| fmt::Error)?;
77        Ok(())
78    }
79}