1#![allow(clippy::arc_with_non_send_sync)]
2use crate::files::{File, SourceFileId, Utf8Path};
3use codespan_reporting as cs;
4use salsa;
5use smol_str::SmolStr;
6use std::rc::Rc;
7
8pub trait Upcast<T: ?Sized> {
9 fn upcast(&self) -> &T;
10}
11
12pub trait UpcastMut<T: ?Sized> {
13 fn upcast_mut(&mut self) -> &mut T;
14}
15
16#[salsa::query_group(SourceDbStorage)]
17pub trait SourceDb {
18 #[salsa::interned]
19 fn intern_file(&self, file: File) -> SourceFileId;
20
21 #[salsa::input]
23 fn file_content(&self, file: SourceFileId) -> Rc<str>;
24
25 #[salsa::invoke(file_line_starts_query)]
26 fn file_line_starts(&self, file: SourceFileId) -> Rc<[usize]>;
27
28 #[salsa::invoke(file_name_query)]
29 fn file_name(&self, file: SourceFileId) -> SmolStr;
30}
31
32fn file_line_starts_query(db: &dyn SourceDb, file: SourceFileId) -> Rc<[usize]> {
33 cs::files::line_starts(&file.content(db)).collect()
34}
35
36fn file_name_query(db: &dyn SourceDb, file: SourceFileId) -> SmolStr {
37 let path = db.lookup_intern_file(file).path;
38 Utf8Path::new(path.as_str())
39 .file_name()
40 .expect("path lacks file name")
41 .into()
42}
43
44#[salsa::database(SourceDbStorage)]
45#[derive(Default)]
46pub struct TestDb {
47 storage: salsa::Storage<TestDb>,
48}
49impl salsa::Database for TestDb {}