prql_ast/
span.rs

1use serde::de::Visitor;
2use serde::{Deserialize, Serialize};
3use std::fmt::{self, Debug, Formatter};
4use std::ops::Range;
5
6#[derive(Clone, PartialEq, Eq, Copy)]
7pub struct Span {
8    pub start: usize,
9    pub end: usize,
10
11    pub source_id: u16,
12}
13
14impl From<Span> for Range<usize> {
15    fn from(a: Span) -> Self {
16        a.start..a.end
17    }
18}
19
20impl Debug for Span {
21    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
22        write!(f, "{}:{}-{}", self.source_id, self.start, self.end)
23    }
24}
25
26impl Serialize for Span {
27    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
28    where
29        S: serde::Serializer,
30    {
31        let str = format!("{self:?}");
32        serializer.serialize_str(&str)
33    }
34}
35
36impl<'de> Deserialize<'de> for Span {
37    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
38    where
39        D: serde::Deserializer<'de>,
40    {
41        struct SpanVisitor {}
42
43        impl<'de> Visitor<'de> for SpanVisitor {
44            type Value = Span;
45
46            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
47                write!(f, "A span string of form `file_id:x-y`")
48            }
49
50            fn visit_str<E>(self, v: &str) -> std::result::Result<Self::Value, E>
51            where
52                E: serde::de::Error,
53            {
54                use serde::de;
55
56                if let Some((file_id, char_span)) = v.split_once(':') {
57                    let file_id = file_id
58                        .parse::<u16>()
59                        .map_err(|e| de::Error::custom(e.to_string()))?;
60
61                    if let Some((start, end)) = char_span.split_once('-') {
62                        let start = start
63                            .parse::<usize>()
64                            .map_err(|e| de::Error::custom(e.to_string()))?;
65                        let end = end
66                            .parse::<usize>()
67                            .map_err(|e| de::Error::custom(e.to_string()))?;
68
69                        return Ok(Span {
70                            start,
71                            end,
72                            source_id: file_id,
73                        });
74                    }
75                }
76
77                Err(de::Error::custom("malformed span"))
78            }
79
80            fn visit_string<E>(self, v: String) -> std::result::Result<Self::Value, E>
81            where
82                E: serde::de::Error,
83            {
84                self.visit_str(&v)
85            }
86        }
87
88        deserializer.deserialize_string(SpanVisitor {})
89    }
90}