use crate::{Display, FmtResult, Formatter, Slice};
#[doc = crate::_tags!(code)]
#[doc = crate::_doc_location!("code")]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct CodeLocation {
pub module: &'static str,
pub file: &'static str,
pub line: u32,
pub column: u32,
}
impl Display for CodeLocation {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult<()> {
write!(f, "{} ({}:{}:{})", self.module, self.file, self.line, self.column)
}
}
impl CodeLocation {
#[inline(always)]
pub const fn here() -> Self {
CodeLocation {
module: crate::code_module!(),
file: crate::code_file!(),
line: crate::code_line!(),
column: crate::code_column!(),
}
}
pub const fn file_line(&self) -> (&'static str, u32) {
(self.file, self.line)
}
pub const fn file_line_column(&self) -> (&'static str, u32, u32) {
(self.file, self.line, self.column)
}
pub const fn eq(&self, other: &Self) -> bool {
self.line == other.line
&& self.column == other.column
&& Slice::<&str>::eq(self.file, other.file)
&& Slice::<&str>::eq(self.module, other.module)
}
pub fn fmt_short(&self, f: &mut Formatter<'_>) -> FmtResult<()> {
write!(f, "{}:{}:{}", self.file, self.line, self.column)
}
}
#[doc = crate::_tags!(code)]
#[doc = crate::_doc_location!("code")]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct CodeSpan {
pub start: CodeLocation,
pub end: CodeLocation,
}
impl CodeSpan {
pub const fn new(start: CodeLocation, end: CodeLocation) -> Self {
Self { start, end }
}
pub const fn here() -> Self {
let loc = CodeLocation::here();
Self { start: loc, end: loc }
}
pub const fn is_point(&self) -> bool {
self.start.eq(&self.end)
}
}
impl Display for CodeSpan {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult<()> {
if self.is_point() {
write!(f, "{}", self.start)
} else {
write!(
f,
"{}:{}:{} – {}:{}:{}",
self.start.file,
self.start.line,
self.start.column,
self.end.line,
self.end.column,
self.end.module
)
}
}
}