codebook_lsp/
file_cache.rs1use std::{
2 num::NonZero,
3 sync::{Arc, RwLock},
4};
5
6use lru::LruCache;
7use tower_lsp::lsp_types::{TextDocumentItem, Url};
8
9#[derive(Debug, Clone)]
10pub struct TextDocumentCacheItem {
11 pub text: String,
12 pub uri: Url,
13 pub version: Option<i32>,
14 pub language_id: Option<String>,
15}
16
17impl TextDocumentCacheItem {
18 pub fn new(
19 uri: &Url,
20 version: Option<i32>,
21 language_id: Option<&str>,
22 text: Option<&str>,
23 ) -> Self {
24 Self {
25 uri: uri.clone(),
26 version,
27 language_id: language_id.map(|id| id.to_string()),
28 text: match text {
29 Some(text) => text.to_string(),
30 None => String::new(),
31 },
32 }
33 }
34}
35
36#[derive(Debug)]
37pub struct TextDocumentCache {
38 documents: Arc<RwLock<LruCache<String, TextDocumentCacheItem>>>,
39}
40
41impl Default for TextDocumentCache {
42 fn default() -> Self {
43 Self {
44 documents: Arc::new(RwLock::new(LruCache::new(NonZero::new(1000).unwrap()))),
45 }
46 }
47}
48
49impl TextDocumentCache {
50 pub fn get(&self, uri: &str) -> Option<TextDocumentCacheItem> {
51 self.documents.write().unwrap().get(uri).cloned()
52 }
53
54 pub fn insert(&self, document: &TextDocumentItem) {
55 let document = TextDocumentCacheItem::new(
56 &document.uri,
57 Some(document.version),
58 Some(&document.language_id),
59 Some(&document.text),
60 );
61 self.documents
62 .write()
63 .unwrap()
64 .put(document.uri.to_string(), document);
65 }
66
67 pub fn update(&self, uri: &Url, text: &str) {
68 let key = uri.to_string();
69 let mut cache = self.documents.write().unwrap();
70 let item = cache.get(&key);
71 match item {
72 Some(item) => {
73 let new_item = TextDocumentCacheItem::new(
74 uri,
75 item.version,
76 item.language_id.as_deref(),
77 Some(text),
78 );
79 cache.put(key, new_item);
80 }
81 None => {
82 let item = TextDocumentCacheItem::new(uri, None, None, Some(text));
83 cache.put(key, item);
84 }
85 }
86 }
87
88 pub fn remove(&self, uri: &Url) {
89 self.documents.write().unwrap().pop(uri.as_str());
90 }
91
92 pub fn cached_urls(&self) -> Vec<Url> {
93 self.documents
94 .read()
95 .unwrap()
96 .iter()
97 .map(|(_, v)| v.uri.clone())
98 .collect()
99 }
100}