// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. use miette::Diagnostic; pub use qsc_data_structures::error::WithSource; use qsc_frontend::compile::PackageStore; use std::fmt::{self, Debug, Display, Formatter}; use thiserror::Error; #[derive(Clone, Debug, Error)] pub struct WithStack { error: E, stack_trace: Option, } impl WithStack { pub(super) fn new(error: E, stack_trace: Option) -> Self { WithStack { error, stack_trace } } pub(super) fn stack_trace(&self) -> Option<&String> { self.stack_trace.as_ref() } pub fn error(&self) -> &E { &self.error } } impl Display for WithStack { fn fmt(&self, f: &mut Formatter) -> fmt::Result { std::fmt::Display::fmt(&self.error, f) } } // #[diagnostic(transparent)] does not seem to work with generics impl Diagnostic for WithStack { fn code<'a>(&'a self) -> Option> { self.error.code() } fn severity(&self) -> Option { self.error.severity() } fn help<'a>(&'a self) -> Option> { self.error.help() } fn url<'a>(&'a self) -> Option> { self.error.url() } fn source_code(&self) -> Option<&dyn miette::SourceCode> { self.error.source_code() } fn labels(&self) -> Option + '_>> { self.error.labels() } fn related<'a>(&'a self) -> Option + 'a>> { self.error.related() } fn diagnostic_source(&self) -> Option<&dyn Diagnostic> { self.error.diagnostic_source() } } pub(super) fn from_eval( error: qsc_eval::Error, store: &PackageStore, stack_trace: Option, ) -> WithStack> { let span = error.span(); let sources = &store .get(span.package) .expect("expected to find package id in store") .sources; WithStack::new(WithSource::from_map(sources, error), stack_trace) }