plotnik_compiler/query/
source_map.rs1#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default)]
8pub struct SourceId(pub(crate) u32);
9
10#[derive(Clone, PartialEq, Eq, Debug)]
12pub enum SourceKind {
13 OneLiner,
15 Stdin,
17 File(String),
19}
20
21impl SourceKind {
22 pub fn display_name(&self) -> &str {
24 match self {
25 SourceKind::OneLiner => "<query>",
26 SourceKind::Stdin => "<stdin>",
27 SourceKind::File(path) => path,
28 }
29 }
30}
31
32#[derive(Clone, Debug)]
34pub struct Source<'q> {
35 pub id: SourceId,
36 pub kind: &'q SourceKind,
37 pub content: &'q str,
38}
39
40impl<'q> Source<'q> {
41 pub fn as_str(&self) -> &'q str {
43 self.content
44 }
45}
46
47#[derive(Clone, Debug)]
49struct SourceEntry {
50 kind: SourceKind,
51 content: String,
52}
53
54#[derive(Clone, Debug, Default)]
56pub struct SourceMap {
57 entries: Vec<SourceEntry>,
58}
59
60impl SourceMap {
61 pub fn new() -> Self {
62 Self::default()
63 }
64
65 pub fn add_one_liner(&mut self, content: &str) -> SourceId {
67 self.push_entry(SourceKind::OneLiner, content)
68 }
69
70 pub fn add_stdin(&mut self, content: &str) -> SourceId {
72 self.push_entry(SourceKind::Stdin, content)
73 }
74
75 pub fn add_file(&mut self, path: &str, content: &str) -> SourceId {
77 self.push_entry(SourceKind::File(path.to_owned()), content)
78 }
79
80 pub fn one_liner(content: &str) -> Self {
83 let mut map = Self::new();
84 map.add_one_liner(content);
85 map
86 }
87
88 pub fn content(&self, id: SourceId) -> &str {
90 self.entries
91 .get(id.0 as usize)
92 .map(|e| e.content.as_str())
93 .expect("invalid SourceId")
94 }
95
96 pub fn kind(&self, id: SourceId) -> &SourceKind {
98 self.entries
99 .get(id.0 as usize)
100 .map(|e| &e.kind)
101 .expect("invalid SourceId")
102 }
103
104 pub fn path(&self, id: SourceId) -> Option<&str> {
106 let entry = self.entries.get(id.0 as usize).expect("invalid SourceId");
107 match &entry.kind {
108 SourceKind::File(path) => Some(path),
109 _ => None,
110 }
111 }
112
113 pub fn len(&self) -> usize {
115 self.entries.len()
116 }
117
118 pub fn is_empty(&self) -> bool {
120 self.entries.is_empty()
121 }
122
123 pub fn get(&self, id: SourceId) -> Source<'_> {
125 let entry = self.entries.get(id.0 as usize).expect("invalid SourceId");
126 Source {
127 id,
128 kind: &entry.kind,
129 content: &entry.content,
130 }
131 }
132
133 pub fn iter(&self) -> impl Iterator<Item = Source<'_>> {
135 self.entries.iter().enumerate().map(|(idx, entry)| Source {
136 id: SourceId(idx as u32),
137 kind: &entry.kind,
138 content: &entry.content,
139 })
140 }
141
142 fn push_entry(&mut self, kind: SourceKind, content: &str) -> SourceId {
143 let id = SourceId(self.entries.len() as u32);
144 self.entries.push(SourceEntry {
145 kind,
146 content: content.to_owned(),
147 });
148 id
149 }
150}