1use std::collections::BTreeMap;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4pub struct Document {
5 pub uri: String,
6 pub text: String,
7 pub version: i32,
8}
9
10#[derive(Debug, Clone, Default)]
11pub struct DocumentStore {
12 documents: BTreeMap<String, Document>,
13}
14
15impl DocumentStore {
16 pub fn open(&mut self, uri: impl Into<String>, text: impl Into<String>, version: i32) {
17 let uri = uri.into();
18 self.documents.insert(
19 uri.clone(),
20 Document {
21 uri,
22 text: text.into(),
23 version,
24 },
25 );
26 }
27
28 pub fn change(&mut self, uri: impl Into<String>, text: impl Into<String>, version: i32) {
29 self.open(uri, text, version);
30 }
31
32 pub fn close(&mut self, uri: &str) -> Option<Document> {
33 self.documents.remove(uri)
34 }
35
36 pub fn get(&self, uri: &str) -> Option<&Document> {
37 self.documents.get(uri)
38 }
39
40 pub fn iter(&self) -> impl Iterator<Item = &Document> {
41 self.documents.values()
42 }
43}
44
45#[cfg(test)]
46mod tests {
47 use super::DocumentStore;
48
49 #[test]
50 fn open_change_close_document() {
51 let mut store = DocumentStore::default();
52 store.open("file:///a.pkl", "name = \"a\"", 1);
53 assert_eq!(store.get("file:///a.pkl").unwrap().version, 1);
54
55 store.change("file:///a.pkl", "name = \"b\"", 2);
56 assert_eq!(store.get("file:///a.pkl").unwrap().text, "name = \"b\"");
57
58 assert!(store.close("file:///a.pkl").is_some());
59 assert!(store.get("file:///a.pkl").is_none());
60 }
61}