1use std::{borrow::Cow, fmt};
4
5pub type LanguageError = crate::ll::error::LanguageError;
7pub type LanguageErrorKind = crate::ll::error::LanguageErrorKind;
9
10#[derive(Debug)]
12pub enum Error {
13 Compile(LanguageError),
15 Runtime(LanguageError),
17 TooManyGlobals,
19 TooManyFunctions,
21 TooManyMethods,
23 TooManyArguments,
25 TooManyTraits,
27 TooManyParametersInTraitMethod,
29 TypeMismatch {
31 expected: Cow<'static, str>,
33 got: Cow<'static, str>,
35 },
36 ArgumentCount {
38 expected: usize,
40 got: usize,
42 },
43 ArgumentTypeMismatch {
45 index: usize,
47 expected: Cow<'static, str>,
49 got: Cow<'static, str>,
51 },
52 ReentrantMutableBorrow,
54 User(Box<dyn std::error::Error>),
56}
57
58impl From<LanguageError> for Error {
59 fn from(error: LanguageError) -> Self {
60 match &error {
61 LanguageError::Compile { .. } => Self::Compile(error),
62 LanguageError::Runtime { .. } => Self::Runtime(error),
63 }
64 }
65}
66
67impl fmt::Display for Error {
68 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69 match self {
70 Self::Compile(error) | Self::Runtime(error) => error.fmt(f),
71 Self::TooManyGlobals => f.write_str("too many globals"),
72 Self::TooManyFunctions => f.write_str("too many functions"),
73 Self::TooManyMethods => f.write_str("too many methods with different signatures"),
74 Self::TooManyArguments => f.write_str("too many arguments passed to a function"),
75 Self::TooManyTraits => f.write_str("too many traits"),
76 Self::TooManyParametersInTraitMethod => {
77 f.write_str("trait method with too many parameters")
78 }
79 Self::TypeMismatch { expected, got } => {
80 write!(f, "type mismatch, expected {expected} but got {got}")
81 }
82 Self::ArgumentCount { expected, got } => {
83 write!(f, "{expected} arguments expected but got {got}")
84 }
85 Self::ArgumentTypeMismatch { index, expected, got } => {
86 write!(
87 f,
88 "type mismatch at argument {}, expected {expected} but got {got}",
89 index + 1
90 )
91 }
92 Self::ReentrantMutableBorrow => write!(f, "method receiver is in use already"),
93 Self::User(error) => write!(f, "{error}"),
94 }
95 }
96}
97
98impl std::error::Error for Error {}
99
100pub trait MicaResultExt<T, E> {
102 fn mica(self) -> Result<T, Error>;
104}
105
106#[repr(transparent)]
108struct UserError<T>(T);
109
110impl<T> fmt::Debug for UserError<T>
111where
112 T: fmt::Debug,
113{
114 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115 fmt::Debug::fmt(&self.0, f)
116 }
117}
118
119impl<T> fmt::Display for UserError<T>
120where
121 T: fmt::Display,
122{
123 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
124 fmt::Display::fmt(&self.0, f)
125 }
126}
127
128impl<T> std::error::Error for UserError<T> where T: fmt::Debug + fmt::Display {}
129
130impl<T, E> MicaResultExt<T, E> for Result<T, E>
131where
132 E: fmt::Debug + fmt::Display + 'static,
133{
134 fn mica(self) -> Result<T, Error> {
135 self.map_err(|error| Error::User(Box::new(UserError(error))))
136 }
137}
138
139pub(crate) fn wrap_in_language_error<T, E>(r: Result<T, E>) -> Result<T, LanguageErrorKind>
140where
141 E: std::error::Error + 'static,
142{
143 r.map_err(|error| LanguageErrorKind::User(Box::new(error)))
144}
145
146pub trait MicaLanguageResultExt<T> {
148 fn to_language_error(self) -> Result<T, LanguageErrorKind>;
150}
151
152impl<T> MicaLanguageResultExt<T> for Result<T, Error> {
153 fn to_language_error(self) -> Result<T, LanguageErrorKind> {
154 wrap_in_language_error(self)
155 }
156}