reproto_core/
loc.rs

1use Span;
2use serde;
3use std::borrow;
4use std::cmp;
5use std::hash;
6use std::result;
7
8#[derive(Clone)]
9pub struct Loc<T> {
10    inner: T,
11    span: Span,
12}
13
14impl<T: serde::Serialize> serde::Serialize for Loc<T> {
15    fn serialize<S>(&self, serializer: S) -> result::Result<S::Ok, S::Error>
16    where
17        S: serde::Serializer,
18    {
19        self.inner.serialize(serializer)
20    }
21}
22
23impl<T> Loc<T> {
24    pub fn new<P: Into<Span>>(inner: T, span: P) -> Loc<T> {
25        Loc {
26            inner: inner,
27            span: span.into(),
28        }
29    }
30
31    pub fn span(loc: &Loc<T>) -> Span {
32        loc.span
33    }
34
35    pub fn take(loc: Loc<T>) -> T {
36        loc.inner
37    }
38
39    pub fn take_pair(loc: Loc<T>) -> (T, Span) {
40        (loc.inner, loc.span)
41    }
42
43    pub fn borrow(loc: &Loc<T>) -> &T {
44        &loc.inner
45    }
46
47    pub fn borrow_pair(loc: &Loc<T>) -> (&T, Span) {
48        (&loc.inner, loc.span)
49    }
50
51    pub fn map<U, O>(loc: Loc<T>, op: O) -> Loc<U>
52    where
53        O: FnOnce(T) -> U,
54    {
55        Loc::new(op(loc.inner), loc.span.clone())
56    }
57
58    pub fn as_ref(loc: &Loc<T>) -> Loc<&T> {
59        Loc::new(&loc.inner, loc.span.clone())
60    }
61
62    /// Apply the fallible operation over the given location.
63    pub fn and_then<U, O, E>(Loc { inner, span }: Loc<T>, op: O) -> result::Result<Loc<U>, E>
64    where
65        O: FnOnce(T) -> result::Result<U, E>,
66    {
67        op(inner).map(|value| Loc::new(value, span.clone()))
68    }
69}
70
71impl<T> cmp::PartialEq for Loc<T>
72where
73    T: cmp::PartialEq,
74{
75    fn eq(&self, other: &Self) -> bool {
76        self.inner.eq(other)
77    }
78}
79
80impl<T> cmp::Eq for Loc<T>
81where
82    T: cmp::Eq,
83{
84}
85
86impl<T> cmp::PartialOrd for Loc<T>
87where
88    T: cmp::PartialOrd,
89{
90    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
91        self.inner.partial_cmp(other)
92    }
93}
94
95impl<T> cmp::Ord for Loc<T>
96where
97    T: cmp::Ord,
98    Self: cmp::PartialOrd + cmp::Eq,
99{
100    fn cmp(&self, other: &Self) -> cmp::Ordering {
101        self.inner.cmp(other)
102    }
103}
104
105impl<T> hash::Hash for Loc<T>
106where
107    T: hash::Hash,
108{
109    fn hash<H>(&self, state: &mut H)
110    where
111        H: hash::Hasher,
112    {
113        self.inner.hash(state)
114    }
115}
116
117impl<T> ::std::ops::Deref for Loc<T> {
118    type Target = T;
119
120    fn deref(&self) -> &T {
121        &self.inner
122    }
123}
124
125impl<T> ::std::ops::DerefMut for Loc<T> {
126    fn deref_mut(&mut self) -> &mut T {
127        &mut self.inner
128    }
129}
130
131impl<T> ::std::convert::AsMut<T> for Loc<T> {
132    fn as_mut(&mut self) -> &mut T {
133        &mut self.inner
134    }
135}
136
137impl<T> borrow::Borrow<T> for Loc<T> {
138    fn borrow(&self) -> &T {
139        &**self
140    }
141}
142
143impl<T> ::std::fmt::Display for Loc<T>
144where
145    T: ::std::fmt::Display,
146{
147    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
148        write!(f, "{}", self.inner)
149    }
150}
151
152impl<T> ::std::fmt::Debug for Loc<T>
153where
154    T: ::std::fmt::Debug,
155{
156    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
157        write!(f, "<{:?}@{:?}>", self.inner, self.span)
158    }
159}
160
161impl<'a, T> From<&'a Loc<T>> for Span {
162    fn from(value: &'a Loc<T>) -> Self {
163        Loc::span(value).clone()
164    }
165}