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 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}