2024-12-10 03:34:41 -05:00
|
|
|
use std::panic;
|
2024-12-10 01:34:53 -05:00
|
|
|
|
|
|
|
use annotate_snippets::{Level, Renderer, Snippet};
|
|
|
|
use smallvec::SmallVec;
|
|
|
|
|
2024-12-14 08:49:02 -05:00
|
|
|
use crate::{DustString, NativeFunctionError, Value, Vm};
|
2024-12-10 01:34:53 -05:00
|
|
|
|
|
|
|
pub fn panic(
|
|
|
|
vm: &Vm,
|
2024-12-14 08:49:02 -05:00
|
|
|
arguments: SmallVec<[&Value; 4]>,
|
2024-12-10 01:34:53 -05:00
|
|
|
) -> Result<Option<Value>, NativeFunctionError> {
|
2024-12-10 03:34:41 -05:00
|
|
|
let mut message: Option<DustString> = None;
|
2024-12-10 01:34:53 -05:00
|
|
|
|
|
|
|
for value_ref in arguments {
|
|
|
|
let string = match value_ref.display(vm) {
|
|
|
|
Ok(string) => string,
|
|
|
|
Err(error) => return Err(NativeFunctionError::Vm(Box::new(error))),
|
|
|
|
};
|
|
|
|
|
2024-12-10 03:34:41 -05:00
|
|
|
match message {
|
|
|
|
Some(ref mut message) => message.push_str(&string),
|
|
|
|
None => message = Some(string),
|
|
|
|
}
|
2024-12-10 01:34:53 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
let position = vm.current_position();
|
|
|
|
let error_output = Level::Error.title("Explicit Panic").snippet(
|
|
|
|
Snippet::source(vm.source()).fold(false).annotation(
|
|
|
|
Level::Error
|
|
|
|
.span(position.0..position.1)
|
|
|
|
.label("Explicit panic occured here"),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
let renderer = Renderer::plain();
|
|
|
|
let report = renderer.render(error_output).to_string();
|
|
|
|
|
|
|
|
panic::set_hook(Box::new(move |_| {
|
|
|
|
println!("{}", report);
|
2024-12-10 03:34:41 -05:00
|
|
|
|
|
|
|
if let Some(message) = &message {
|
|
|
|
println!("{}", message);
|
|
|
|
}
|
2024-12-10 01:34:53 -05:00
|
|
|
}));
|
|
|
|
|
|
|
|
panic!();
|
|
|
|
}
|