Skip to main content

pkl_lsp_core/
archive.rs

1use rkyv::{Archive, Deserialize, Serialize};
2
3use crate::WorkspaceIndex;
4
5pub const ARCHIVE_SCHEMA_VERSION: u32 = 1;
6
7#[derive(Debug, Clone, PartialEq, Eq, Archive, Serialize, Deserialize)]
8#[rkyv(compare(PartialEq), derive(Debug))]
9pub struct ArchivedWorkspace {
10    pub schema_version: u32,
11    pub index: WorkspaceIndex,
12}
13
14#[derive(Debug, thiserror::Error)]
15pub enum ArchiveError {
16    #[error("workspace archive schema {found} is not supported; expected {expected}")]
17    UnsupportedSchema { found: u32, expected: u32 },
18}
19
20impl ArchivedWorkspace {
21    pub fn new(index: WorkspaceIndex) -> Self {
22        Self {
23            schema_version: ARCHIVE_SCHEMA_VERSION,
24            index,
25        }
26    }
27
28    pub fn validate_schema(&self) -> Result<(), ArchiveError> {
29        if self.schema_version == ARCHIVE_SCHEMA_VERSION {
30            Ok(())
31        } else {
32            Err(ArchiveError::UnsupportedSchema {
33                found: self.schema_version,
34                expected: ARCHIVE_SCHEMA_VERSION,
35            })
36        }
37    }
38}
39
40#[cfg(test)]
41mod tests {
42    use super::{ARCHIVE_SCHEMA_VERSION, ArchivedWorkspace};
43    use crate::WorkspaceIndex;
44
45    #[test]
46    fn rejects_stale_schema() {
47        let archive = ArchivedWorkspace {
48            schema_version: ARCHIVE_SCHEMA_VERSION + 1,
49            index: WorkspaceIndex {
50                diagnostics: Vec::new(),
51                imports: Vec::new(),
52                symbols: Vec::new(),
53            },
54        };
55
56        assert!(archive.validate_schema().is_err());
57    }
58
59    #[test]
60    fn rkyv_round_trip_workspace_archive() {
61        let archive = ArchivedWorkspace::new(WorkspaceIndex {
62            diagnostics: Vec::new(),
63            imports: Vec::new(),
64            symbols: Vec::new(),
65        });
66        let bytes = rkyv::to_bytes::<rkyv::rancor::Error>(&archive).unwrap();
67        let archived =
68            rkyv::access::<super::ArchivedArchivedWorkspace, rkyv::rancor::Error>(&bytes).unwrap();
69        assert_eq!(archived.schema_version, ARCHIVE_SCHEMA_VERSION);
70    }
71}