aboutsummaryrefslogtreecommitdiff
path: root/crates/libanalysis/src/db.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-09-10 18:14:31 +0100
committerAleksey Kladov <[email protected]>2018-09-15 22:00:05 +0100
commit99d02fe583f4747f67debc1973a3eb3ca62e2005 (patch)
tree61af7d14bb5eafec446ee5b1bc9d07d13ef70006 /crates/libanalysis/src/db.rs
parent6ee4c287f9c95738f0482bf635ccc3801fc2fea2 (diff)
start query-based modules
Diffstat (limited to 'crates/libanalysis/src/db.rs')
-rw-r--r--crates/libanalysis/src/db.rs121
1 files changed, 121 insertions, 0 deletions
diff --git a/crates/libanalysis/src/db.rs b/crates/libanalysis/src/db.rs
new file mode 100644
index 000000000..335c79e76
--- /dev/null
+++ b/crates/libanalysis/src/db.rs
@@ -0,0 +1,121 @@
1use std::{
2 hash::Hash,
3 sync::Arc,
4};
5use libsyntax2::{File};
6use im;
7use {
8 FileId,
9 imp::{FileResolverImp},
10};
11
12#[derive(Clone)]
13pub(crate) struct Db {
14 file_resolver: FileResolverImp,
15 files: im::HashMap<FileId, Arc<String>>,
16}
17
18impl Db {
19 pub(crate) fn new() -> Db {
20 Db {
21 file_resolver: FileResolverImp::default(),
22 files: im::HashMap::new(),
23 }
24 }
25 pub(crate) fn change_file(&mut self, file_id: FileId, text: Option<String>) {
26 match text {
27 None => {
28 self.files.remove(&file_id);
29 }
30 Some(text) => {
31 self.files.insert(file_id, Arc::new(text));
32 }
33 }
34 }
35 pub(crate) fn set_file_resolver(&mut self, file_resolver: FileResolverImp) {
36 self.file_resolver = file_resolver
37 }
38 pub(crate) fn query_ctx(&self) -> QueryCtx {
39 QueryCtx { db: self.clone() }
40 }
41}
42
43pub(crate) struct QueryCtx {
44 db: Db
45}
46
47impl QueryCtx {
48 pub(crate) fn get<Q: Get>(&self, params: &Q::Params) -> Q::Output {
49 Q::get(self, params)
50 }
51}
52
53pub(crate) trait Query {
54 const ID: u32;
55 type Params: Hash;
56 type Output;
57}
58
59pub(crate) trait Get: Query {
60 fn get(ctx: &QueryCtx, params: &Self::Params) -> Self::Output;
61}
62
63impl<T: Eval> Get for T {
64 fn get(ctx: &QueryCtx, params: &Self::Params) -> Self::Output {
65 Self::eval(ctx, params)
66 }
67}
68
69pub(crate) trait Eval: Query {
70 fn eval(ctx: &QueryCtx, params: &Self::Params) -> Self::Output;
71}
72
73pub(crate) struct DbFiles {
74 db: Db,
75}
76
77impl DbFiles {
78 pub(crate) fn iter<'a>(&'a self) -> impl Iterator<Item=FileId> + 'a {
79 self.db.files.keys().cloned()
80 }
81 pub(crate) fn file_resolver(&self) -> FileResolverImp {
82 self.db.file_resolver.clone()
83 }
84}
85
86pub(crate) enum Files {}
87impl Query for Files {
88 const ID: u32 = 1;
89 type Params = ();
90 type Output = DbFiles;
91}
92impl Get for Files {
93 fn get(ctx: &QueryCtx, _params: &()) -> DbFiles {
94 DbFiles { db: ctx.db.clone() }
95 }
96}
97
98enum FileText {}
99impl Query for FileText {
100 const ID: u32 = 10;
101 type Params = FileId;
102 type Output = Arc<String>;
103}
104impl Get for FileText {
105 fn get(ctx: &QueryCtx, file_id: &FileId) -> Arc<String> {
106 ctx.db.files[file_id].clone()
107 }
108}
109
110pub(crate) enum FileSyntax {}
111impl Query for FileSyntax {
112 const ID: u32 = 20;
113 type Params = FileId;
114 type Output = File;
115}
116impl Eval for FileSyntax {
117 fn eval(ctx: &QueryCtx, file_id: &FileId) -> File {
118 let text = ctx.get::<FileText>(file_id);
119 File::parse(&text)
120 }
121}