1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
use std::ops::{Deref, DerefMut};

use lang_util::TextRange;

use super::TokenText;

// A token somewhere in a source file
#[derive(Debug, Clone, Copy)]
pub struct TextToken<T> {
    pub token: T,
    pub range: TextRange,
}

impl<T> TextToken<T> {
    pub fn new(token: T, range: TextRange) -> Self {
        Self { token, range }
    }

    pub fn raw<'s>(&self, input: &'s str) -> &'s str {
        &input[self.range]
    }

    pub fn text<'s>(&self, input: &'s str) -> TokenText<'s> {
        TokenText::raw(&input[self.range])
    }

    pub fn map<U>(self, f: impl FnOnce(T) -> U) -> TextToken<U> {
        TextToken {
            token: f(self.token),
            range: self.range,
        }
    }

    pub fn transmute<U: From<T>>(self) -> TextToken<U> {
        TextToken {
            token: self.token.into(),
            range: self.range,
        }
    }
}

impl<T> Deref for TextToken<T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.token
    }
}

impl<T> DerefMut for TextToken<T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.token
    }
}