Skip to main content

shardline_cache/
disabled.rs

1use crate::{AsyncReconstructionCache, ReconstructionCacheFuture, ReconstructionCacheKey};
2
3/// No-op reconstruction cache adapter.
4#[derive(Debug, Clone, Default)]
5pub struct DisabledReconstructionCache;
6
7impl DisabledReconstructionCache {
8    /// Creates a disabled reconstruction cache adapter.
9    #[must_use]
10    pub const fn new() -> Self {
11        Self
12    }
13}
14
15impl AsyncReconstructionCache for DisabledReconstructionCache {
16    fn ready(&self) -> ReconstructionCacheFuture<'_, ()> {
17        Box::pin(async { Ok(()) })
18    }
19
20    fn get<'operation>(
21        &'operation self,
22        _key: &'operation ReconstructionCacheKey,
23    ) -> ReconstructionCacheFuture<'operation, Option<Vec<u8>>> {
24        Box::pin(async { Ok(None) })
25    }
26
27    fn put<'operation>(
28        &'operation self,
29        _key: &'operation ReconstructionCacheKey,
30        _payload: &'operation [u8],
31    ) -> ReconstructionCacheFuture<'operation, ()> {
32        Box::pin(async { Ok(()) })
33    }
34
35    fn delete<'operation>(
36        &'operation self,
37        _key: &'operation ReconstructionCacheKey,
38    ) -> ReconstructionCacheFuture<'operation, bool> {
39        Box::pin(async { Ok(false) })
40    }
41}
42
43#[cfg(test)]
44mod tests {
45    use crate::{AsyncReconstructionCache, ReconstructionCacheKey};
46
47    use super::*;
48
49    #[test]
50    fn new_constructs_without_panic() {
51        let _cache = DisabledReconstructionCache::new();
52    }
53
54    #[test]
55    fn default_constructs_without_panic() {
56        let _cache = DisabledReconstructionCache;
57    }
58
59    #[tokio::test]
60    async fn ready_returns_ok() {
61        let cache = DisabledReconstructionCache::new();
62        let result = cache.ready().await;
63        assert!(result.is_ok());
64    }
65
66    #[allow(clippy::unwrap_used)]
67    #[tokio::test]
68    async fn get_returns_none() {
69        let cache = DisabledReconstructionCache::new();
70        let key = ReconstructionCacheKey::latest("test", None);
71        let result = cache.get(&key).await;
72        assert!(result.is_ok());
73        assert_eq!(result.unwrap(), None);
74    }
75
76    #[tokio::test]
77    async fn put_returns_ok() {
78        let cache = DisabledReconstructionCache::new();
79        let key = ReconstructionCacheKey::latest("test", None);
80        let result = cache.put(&key, b"payload").await;
81        assert!(result.is_ok());
82    }
83
84    #[allow(clippy::unwrap_used)]
85    #[tokio::test]
86    async fn delete_returns_false() {
87        let cache = DisabledReconstructionCache::new();
88        let key = ReconstructionCacheKey::latest("test", None);
89        let result = cache.delete(&key).await;
90        assert!(result.is_ok());
91        assert!(!result.unwrap());
92    }
93
94    #[test]
95    fn new_is_const_fn() {
96        const _CACHE: DisabledReconstructionCache = DisabledReconstructionCache::new();
97    }
98
99    #[test]
100    fn default_trait_produces_same_as_new() {
101        let a = DisabledReconstructionCache::new();
102        // Both are unit structs — both impl AsyncReconstructionCache
103        let _: &dyn crate::AsyncReconstructionCache = &a;
104    }
105
106    #[allow(clippy::unwrap_used)]
107    #[tokio::test]
108    async fn get_with_scope_returns_none() {
109        use shardline_protocol::{RepositoryProvider, RepositoryScope};
110        let cache = DisabledReconstructionCache::new();
111        let scope =
112            RepositoryScope::new(RepositoryProvider::GitHub, "org", "repo", Some("main")).unwrap();
113        let key = ReconstructionCacheKey::latest("scoped-file", Some(&scope));
114        let result = cache.get(&key).await;
115        assert!(result.is_ok());
116        assert_eq!(result.unwrap(), None);
117    }
118
119    #[allow(clippy::unwrap_used)]
120    #[tokio::test]
121    async fn get_with_version_key_returns_none() {
122        let cache = DisabledReconstructionCache::new();
123        let key = ReconstructionCacheKey::version("file.bin", "hash123", None);
124        let result = cache.get(&key).await;
125        assert!(result.is_ok());
126        assert_eq!(result.unwrap(), None);
127    }
128
129    #[tokio::test]
130    async fn put_with_empty_payload_returns_ok() {
131        let cache = DisabledReconstructionCache::new();
132        let key = ReconstructionCacheKey::latest("empty", None);
133        let result = cache.put(&key, b"").await;
134        assert!(result.is_ok());
135    }
136
137    #[allow(clippy::unwrap_used)]
138    #[tokio::test]
139    async fn delete_with_scoped_key_returns_false() {
140        use shardline_protocol::{RepositoryProvider, RepositoryScope};
141        let cache = DisabledReconstructionCache::new();
142        let scope =
143            RepositoryScope::new(RepositoryProvider::GitLab, "group", "proj", None).unwrap();
144        let key = ReconstructionCacheKey::latest("scoped", Some(&scope));
145        let result = cache.delete(&key).await;
146        assert!(result.is_ok());
147        assert!(!result.unwrap());
148    }
149}