use std::fmt;
use std::hash::{Hash, Hasher};
#[derive(Clone, Copy)]
pub struct Transparent<T> {
inner: Result<T, &'static str>,
}
impl<T> fmt::Debug for Transparent<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "_")
}
}
impl<T> Transparent<T> {
pub fn unwrap(self) -> T {
match self.inner {
Ok(x) => x,
Err(l) => crate::abort!(
"Attempted to read a forged transparent value. Forged at {}",
l
),
}
}
#[must_use]
pub fn forge(loc: &'static str) -> Self {
Self { inner: Err(loc) }
}
}
impl<T> Transparent<Option<T>> {
pub fn try_override_inner(&mut self, t: T) {
match &mut self.inner {
Ok(s) => {
if s.is_none() {
*s = Some(t);
}
}
Err(_) => self.inner = Ok(Some(t)),
}
}
}
impl<T> Transparent<Transparent<T>> {
pub fn flatten(self) -> Transparent<T> {
match self.inner {
Ok(x1) => match x1.inner {
Ok(x2) => Transparent { inner: Ok(x2) },
Err(loc) => Transparent { inner: Err(loc) },
},
Err(loc) => Transparent { inner: Err(loc) },
}
}
}
impl<T> Transparent<Option<T>> {
pub fn flatten(self) -> Option<Transparent<T>> {
match self.inner {
Ok(x1) => Some(Transparent { inner: Ok(x1?) }),
Err(loc) => Some(Transparent { inner: Err(loc) }),
}
}
}
impl<T> Transparent<T> {
pub fn from(inner: T) -> Self {
Self { inner: Ok(inner) }
}
}
impl<T> PartialEq for Transparent<T> {
fn eq(&self, _: &Self) -> bool {
true
}
}
impl<T> Eq for Transparent<T> {}
impl<T> Hash for Transparent<T> {
fn hash<H: Hasher>(&self, _: &mut H) {}
}
impl<T: fmt::Display> fmt::Display for Transparent<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.inner {
Ok(v) => write!(f, "{v}"),
Err(_) => write!(f, "<undef>"),
}
}
}
impl Transparent<proc_macro2::Span> {
#[must_use]
pub fn join(self, other: Self) -> Option<Self> {
let Ok(v1) = self.inner else {
return Some(self);
};
let Ok(v2) = other.inner else {
return Some(self);
};
Some(Self {
inner: Ok(v1.join(v2)?),
})
}
}
impl<T: crate::TrySpan> crate::TrySpan for Transparent<T> {
fn try_span(&self) -> Option<crate::Span> {
self.inner.try_span()
}
}