backbone_bucket/domain/entity/
content_hash.ext.rs1#[allow(unused_imports)]
4use super::*;
5
6impl ContentHash {
7
8 pub fn increment_reference(&mut self) -> Result<(), DedupError> {
14 self.reference_count += 1;
15 self.last_referenced_at = Utc::now();
16 self.metadata.touch();
17 Ok(())
18 }
19
20 pub fn decrement_reference(&mut self) -> Result<bool, DedupError> {
22 self.reference_count = (self.reference_count - 1).max(0);
23 self.metadata.touch();
24 Ok(self.reference_count == 0)
25 }
26
27 pub fn can_delete(&self) -> bool {
29 self.reference_count == 0
30 }
31
32 pub fn is_unused(&self) -> bool {
34 self.reference_count == 0
35 }
36
37 pub fn storage_saved(&self) -> i64 {
39 self.size_bytes * (self.reference_count - 1).max(0) as i64
40 }
41
42 pub fn age_days(&self) -> i32 {
44 (Utc::now() - self.first_uploaded_at).num_days() as i32
45 }
46
47 pub fn days_since_last_reference(&self) -> i32 {
49 (Utc::now() - self.last_referenced_at).num_days() as i32
50 }
51
52 pub fn check_invariants(&self) -> Result<(), Vec<&'static str>> {
54 let mut errors = Vec::new();
55 if self.reference_count < 0 {
56 errors.push("reference_count must be >= 0");
57 }
58 if self.hash.is_empty() || self.hash.contains("..") {
59 errors.push("hash must not be empty and must not contain '..'");
60 }
61 if self.size_bytes <= 0 {
62 errors.push("size_bytes must be > 0");
63 }
64 if errors.is_empty() { Ok(()) } else { Err(errors) }
65 }
66}