use std::convert::{
AsRef,
AsMut
};
use std::ops::{
Deref,
DerefMut
};
use std::hash::{
Hash,
Hasher
};
use std::cmp::{
Ord,
PartialOrd,
Ordering
};
use std::convert::TryInto;
use std::fmt;
use crate::Span;
pub struct Loc<T: ?Sized> {
span: Span,
value: T
}
impl<T: ?Sized> Loc<T> {
pub fn new(t: T, span: Span) -> Loc<T> where T: Sized {
Self {
span: span,
value: t
}
}
pub fn span(&self) -> Span {
self.span
}
pub fn map<U, F>(self, f: F) -> Loc<U> where F: FnOnce(T) -> U, T: Sized {
Loc {
span: self.span,
value: f(self.value)
}
}
pub fn inner_into<U>(self) -> Loc<U> where T: Into<U> {
Loc {
span: self.span,
value: self.value.into()
}
}
pub fn try_map<U, F, E>(self, f: F) -> Result<Loc<U>, E> where F: FnOnce(T) -> Result<U, E>, T: Sized {
Ok(Loc {
span: self.span,
value: f(self.value)?
})
}
pub fn inner_try_into<U>(self) -> Result<Loc<U>, <T as TryInto<U>>::Error> where T: TryInto<U> {
Ok(Loc {
span: self.span,
value: self.value.try_into()?
})
}
pub fn into_inner(self) -> T where T: Sized {
self.value
}
pub fn into_raw_parts(self) -> (T, Span) where T: Sized {
(self.value, self.span)
}
}
impl<T> Loc<Option<T>> {
pub fn transposed(t: Option<Loc<T>>, span: Span) -> Self {
match t {
Some(t) => t.map(|t| Some(t)),
None => Self::new(None, span)
}
}
}
impl<T: Clone> Clone for Loc<T> {
fn clone(&self) -> Loc<T> {
Loc {
span: self.span,
value: self.value.clone()
}
}
}
impl<T> AsRef<T> for Loc<T> {
fn as_ref(&self) -> &T {
&self.value
}
}
impl<T> AsMut<T> for Loc<T> {
fn as_mut(&mut self) -> &mut T {
&mut self.value
}
}
impl<T: fmt::Display> fmt::Display for Loc<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.value.fmt(f)
}
}
impl<T: fmt::Debug> fmt::Debug for Loc<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}:{}", self.value, self.span)
}
}
impl<T: Hash> Hash for Loc<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.span.hash(state);
self.value.hash(state);
}
}
impl<T: PartialEq> PartialEq for Loc<T> {
fn eq(&self, other: &Loc<T>) -> bool {
self.span == other.span && self.value == other.value
}
}
impl<T: Eq> Eq for Loc<T> {}
impl<T: PartialOrd> PartialOrd for Loc<T> {
fn partial_cmp(&self, other: &Loc<T>) -> Option<Ordering> {
self.value.partial_cmp(&other.value)
}
}
impl<T: Ord> Ord for Loc<T> {
fn cmp(&self, other: &Loc<T>) -> Ordering {
self.value.cmp(&other.value)
}
}
impl<T> Deref for Loc<T> {
type Target = T;
fn deref(&self) -> &T {
&self.value
}
}
impl<T> DerefMut for Loc<T> {
fn deref_mut(&mut self) -> &mut T {
&mut self.value
}
}