use serde::{Deserialize, Serialize};
use std::{
borrow::Cow,
fmt::{self, Display},
};
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
pub struct Location {
file: Cow<'static, str>,
line: u32,
column: u32,
}
impl Location {
#[track_caller]
pub const fn caller() -> Self {
let location = std::panic::Location::caller();
Self {
file: Cow::Borrowed(location.file()),
line: location.line(),
column: location.column(),
}
}
pub const fn file(&self) -> &str {
match &self.file {
Cow::Borrowed(s) => s,
Cow::Owned(s) => s.as_str(),
}
}
pub const fn column(&self) -> u32 {
self.column
}
pub const fn line(&self) -> u32 {
self.line
}
}
impl From<&'static std::panic::Location<'static>> for Location {
fn from(location: &'static std::panic::Location<'static>) -> Self {
Self {
file: Cow::Borrowed(location.file()),
line: location.line(),
column: location.column(),
}
}
}
impl Display for Location {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}:{}:{}", self.file, self.line, self.column)
}
}