storage/worktree/
lease.rs1use std::path::{Path, PathBuf};
9
10use kernel::event::record::WorktreeOpened;
11use kernel::{ByteLen, Payload};
12
13use crate::error::StorageError;
14
15use super::name::WorktreeName;
16
17#[derive(Debug, Clone, PartialEq, Eq)]
19pub struct WorktreeLease {
20 pub(crate) name: WorktreeName,
21 pub(crate) path: PathBuf,
22 pub(crate) disk: ByteLen,
23 pub(crate) work: FileWork,
24}
25
26#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
35pub struct FileWork {
36 pub created: u64,
38 pub rewritten: u64,
41 pub removed: u64,
44 pub walked: u64,
46}
47
48impl WorktreeLease {
49 #[must_use]
50 pub fn name(&self) -> &WorktreeName {
51 &self.name
52 }
53
54 #[must_use]
56 pub fn path(&self) -> &Path {
57 &self.path
58 }
59
60 #[must_use]
63 pub fn disk(&self) -> ByteLen {
64 self.disk
65 }
66
67 #[must_use]
69 pub fn work(&self) -> FileWork {
70 self.work
71 }
72
73 pub fn opened_payload(&self) -> Result<Payload, StorageError> {
80 Payload::of(&WorktreeOpened {
81 name: self.name.as_str().to_owned(),
82 disk_bytes: self.disk,
83 })
84 .map_err(|source| StorageError::Draft { source })
85 }
86}
87
88#[cfg(test)]
89#[allow(
90 clippy::unwrap_used,
91 clippy::expect_used,
92 clippy::panic,
93 clippy::indexing_slicing,
94 reason = "test code"
95)]
96mod tests {
97 use super::super::trees::Worktrees;
98 use serde_json::Value;
99
100 use super::*;
101 use crate::checkpoint::Checkpoint;
102 use kernel::TimeMs;
103 use kernel::consts_policy::WORKTREE_MAX_BYTES;
104 fn city(dir: &Path) -> Worktrees {
105 std::fs::create_dir_all(dir.join("lab")).unwrap();
106 std::fs::write(dir.join("lab").join("notes.md"), b"first\n").unwrap();
107 let mut checkpoint = Checkpoint::open(dir).unwrap();
108 checkpoint
109 .ensure_base(
110 &["lab".to_owned()],
111 TimeMs::new(1_000),
112 &super::super::trees::tests::owner(),
113 )
114 .unwrap();
115 Worktrees::open(dir).unwrap()
116 }
117 fn name(raw: &str) -> WorktreeName {
118 WorktreeName::parse(raw).unwrap()
119 }
120
121 #[test]
122 fn the_tree_is_measured_rather_than_estimated() {
123 let dir = tempfile::tempdir().unwrap();
124 let trees = city(dir.path());
125 let lease = trees.claim(&name("node-1"), &[]).unwrap();
126 assert!(
127 lease.disk().get() >= 6,
128 "the checked-out file has six bytes"
129 );
130 assert!(lease.disk().get() < WORKTREE_MAX_BYTES);
131
132 let payload = lease.opened_payload().unwrap();
133 let map = payload.as_map();
134 assert_eq!(map.get("name").and_then(Value::as_str), Some("node-1"));
135 assert!(map.contains_key("disk_bytes"));
136 assert!(
137 !map.contains_key("path"),
138 "an absolute path is a fact about this machine, not about the city"
139 );
140 }
141}