1use std::fmt;
2
3use crate::{
4 protocol::{
5 outbound_message::compile_response::CompileFailure, ProtocolError,
6 },
7 SourceSpan,
8};
9
10pub type Result<T> = std::result::Result<T, Box<Exception>>;
12
13#[derive(Debug)]
17pub struct Exception {
18 message: String,
19 sass_message: Option<String>,
20 sass_stack: Option<String>,
21 span: Option<SourceSpan>,
22 source: Option<Box<dyn std::error::Error + Send + Sync + 'static>>,
23}
24
25impl Exception {
26 pub fn message(&self) -> &str {
28 &self.message
29 }
30
31 pub fn sass_message(&self) -> Option<&str> {
33 self.sass_message.as_deref()
34 }
35
36 pub fn sass_stack(&self) -> Option<&str> {
38 self.sass_stack.as_deref()
39 }
40
41 pub fn span(&self) -> Option<&SourceSpan> {
43 self.span.as_ref()
44 }
45}
46
47impl std::error::Error for Exception {}
48
49impl fmt::Display for Exception {
50 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52 write!(f, "{}", self.message)
53 }
54}
55
56impl From<CompileFailure> for Exception {
57 fn from(failure: CompileFailure) -> Self {
58 Self {
59 message: failure.formatted,
60 sass_message: Some(failure.message),
61 sass_stack: Some(failure.stack_trace),
62 span: failure.span.map(|span| span.into()),
63 source: None,
64 }
65 }
66}
67
68impl From<ProtocolError> for Exception {
69 fn from(e: ProtocolError) -> Self {
70 Self::new(e.message)
71 }
72}
73
74impl Exception {
75 pub fn new(message: impl Into<String>) -> Self {
77 Self {
78 message: message.into(),
79 sass_message: None,
80 sass_stack: None,
81 span: None,
82 source: None,
83 }
84 }
85
86 pub fn set_source(
88 mut self,
89 source: impl std::error::Error + Send + Sync + 'static,
90 ) -> Self {
91 self.source = Some(Box::new(source));
92 self
93 }
94}