Skip to main content

clankerdiff_protocol/server/
sent_document.rs

1use crate::{
2    server::{ServerEvent, ServerMessage},
3    shared::{DiffSnapshot, DocumentUpdate, FileEntry},
4};
5use clankerdiff_core::{FileDiff, RepoPath};
6use std::{collections::BTreeMap, sync::Arc};
7
8#[derive(Debug, Default)]
9pub struct SentDocument {
10    files: BTreeMap<RepoPath, Arc<FileDiff>>,
11}
12
13impl SentDocument {
14    pub fn encode_event(&mut self, event: ServerEvent) -> ServerMessage {
15        event.map(|snapshot| self.encode(&snapshot))
16    }
17
18    pub fn encode(&mut self, snapshot: &DiffSnapshot) -> DocumentUpdate {
19        let mut files = Vec::with_capacity(snapshot.document.files.len());
20        let mut sent = BTreeMap::new();
21        for file in &snapshot.document.files {
22            let entry = match self.files.get(&file.path) {
23                Some(held) if held.as_ref() == file => {
24                    sent.insert(file.path.clone(), Arc::clone(held));
25                    FileEntry::Unchanged(file.path.clone())
26                }
27                _ => {
28                    let file = Arc::new(file.clone());
29                    sent.insert(file.path.clone(), Arc::clone(&file));
30                    FileEntry::Changed(file)
31                }
32            };
33            files.push(entry);
34        }
35        self.files = sent;
36        DocumentUpdate {
37            scope: snapshot.scope,
38            repo_root: snapshot.document.repo_root.clone(),
39            files,
40        }
41    }
42}