#![feature(lint_reasons)]
#![warn(
missing_docs,
unused_crate_dependencies,
unused_macro_rules,
variant_size_differences,
clippy::allow_attributes,
clippy::allow_attributes_without_reason,
clippy::expect_used,
clippy::indexing_slicing,
clippy::missing_docs_in_private_items,
clippy::multiple_inherent_impl,
clippy::panic,
clippy::pedantic,
clippy::str_to_string,
clippy::unreachable,
clippy::unwrap_used,
clippy::use_debug
)]
pub mod transparent;
pub use transparent::Transparent;
pub mod error;
pub use error::*;
pub type Span = Transparent<proc_macro2::Span>;
#[macro_export]
macro_rules! repo {
() => {
"https://github.com/Vanille-N/chandeliers"
};
}
#[macro_export]
macro_rules! here {
() => {
concat!(file!(), ":", line!(), ":", column!())
};
}
#[macro_export]
macro_rules! abort {
($($err:tt)*) => {{
std::panic!("
Chandeliers panicked: \x1b[1;31m{}.\x1b[0m
This error occured in \x1b[1;35m{}\x1b[0m
If you are not a developper of Chandeliers and you see this message then this is a bug.
I'd be grateful if you could report this error at \x1b[33m{}\x1b[0m
with the code that produced it and the version of Chandeliers you are using.
",
format!($($err)*),
$crate::here!(),
$crate::repo!(),
);
}};
}
#[macro_export]
macro_rules! malformed {
() => {{
::chandeliers_err::abort!("Entered unreachable code");
}};
}
#[macro_export]
macro_rules! consistency {
($cond:expr, $($msg:tt)*) => {{
if !$cond {
::chandeliers_err::abort!($($msg)*);
}
}};
}
#[derive(Default)]
pub struct EAccum {
err: Vec<Error>,
warn: Vec<Error>,
}
pub struct EAccumScope<'a> {
acc: &'a mut EAccum,
fatal: bool,
}
impl EAccum {
pub fn error<T, E: IntoError>(&mut self, e: E) -> Option<T> {
self.err.push(e.into_err());
None
}
pub fn warning<E: IntoError>(&mut self, e: E) {
self.warn.push(e.into_err());
}
#[must_use]
pub fn is_fatal(&self) -> bool {
!self.err.is_empty()
}
#[must_use]
pub fn fetch(self) -> (Vec<Error>, Vec<Error>) {
(self.err, self.warn)
}
pub fn scope(&mut self) -> EAccumScope {
EAccumScope {
acc: self,
fatal: false,
}
}
}
impl<'a> EAccumScope<'a> {
pub fn compute<F>(&mut self, f: F)
where
F: FnOnce(&mut EAccum) -> Option<()>,
{
let e = f(&mut *self.acc);
if e.is_none() {
self.fatal = true;
}
}
#[must_use]
pub fn close(self) -> Option<()> {
if self.fatal {
None
} else {
Some(())
}
}
pub fn error<E: IntoError>(&mut self, e: E) {
self.compute(|acc| acc.error(e));
}
pub fn warning<E: IntoError>(&mut self, e: E) {
self.compute(|acc| {
acc.warning(e);
Some(())
});
}
}