Skip to main content

gix_object/
find.rs

1use gix_error::{ExnResult, ResultExt};
2
3/// An implementation of object access traits that stores nothing and finds nothing.
4/// Use [`Never::panic_on_access()`] to panic on object access instead.
5#[derive(Debug, Copy, Clone)]
6pub struct Never;
7
8impl Never {
9    /// Return an implementation that panics whenever an object access trait method is called.
10    /// Useful for asserting that an operation does not access the object database.
11    pub const fn panic_on_access() -> PanicAlways {
12        PanicAlways
13    }
14}
15
16/// An implementation of object access traits that panics on every call.
17/// Obtain it with [`Never::panic_on_access()`].
18#[derive(Debug, Copy, Clone)]
19pub struct PanicAlways;
20
21impl super::FindHeader for PanicAlways {
22    fn try_header(&self, _id: &gix_hash::oid) -> ExnResult<Option<crate::Header>> {
23        panic!("object header lookups are forbidden");
24    }
25}
26
27impl super::Find for PanicAlways {
28    fn try_find<'a>(&self, _id: &gix_hash::oid, _buffer: &'a mut Vec<u8>) -> ExnResult<Option<crate::Data<'a>>> {
29        panic!("object lookups are forbidden");
30    }
31}
32
33impl super::Exists for PanicAlways {
34    fn exists(&self, _id: &gix_hash::oid) -> bool {
35        panic!("object existence checks are forbidden");
36    }
37}
38
39impl super::Write for PanicAlways {
40    fn write(&self, _object: &dyn crate::WriteTo) -> ExnResult<gix_hash::ObjectId> {
41        panic!("object writes are forbidden");
42    }
43
44    fn write_buf_with_known_id(
45        &self,
46        _object: crate::Kind,
47        _from: &[u8],
48        _id: gix_hash::ObjectId,
49    ) -> ExnResult<gix_hash::ObjectId> {
50        panic!("object writes are forbidden");
51    }
52
53    fn write_stream(
54        &self,
55        _kind: crate::Kind,
56        _size: u64,
57        _from: &mut dyn std::io::Read,
58    ) -> ExnResult<gix_hash::ObjectId> {
59        panic!("object writes are forbidden");
60    }
61
62    fn write_stream_with_known_id(
63        &self,
64        _kind: crate::Kind,
65        _size: u64,
66        _from: &mut dyn std::io::Read,
67        _id: gix_hash::ObjectId,
68    ) -> ExnResult<gix_hash::ObjectId> {
69        panic!("object writes are forbidden");
70    }
71}
72
73impl super::FindHeader for Never {
74    fn try_header(&self, _id: &gix_hash::oid) -> ExnResult<Option<crate::Header>> {
75        Ok(None)
76    }
77}
78
79impl super::Find for Never {
80    fn try_find<'a>(&self, _id: &gix_hash::oid, _buffer: &'a mut Vec<u8>) -> ExnResult<Option<crate::Data<'a>>> {
81        Ok(None)
82    }
83}
84
85impl super::Exists for Never {
86    fn exists(&self, _id: &gix_hash::oid) -> bool {
87        false
88    }
89}
90
91impl super::Write for Never {
92    fn write_buf(&self, object: crate::Kind, from: &[u8]) -> ExnResult<gix_hash::ObjectId> {
93        crate::compute_hash(gix_hash::Kind::default(), object, from).or_erased()
94    }
95
96    fn write_buf_with_known_id(
97        &self,
98        _object: crate::Kind,
99        _from: &[u8],
100        id: gix_hash::ObjectId,
101    ) -> ExnResult<gix_hash::ObjectId> {
102        Ok(id)
103    }
104
105    fn write_stream(
106        &self,
107        kind: crate::Kind,
108        size: u64,
109        from: &mut dyn std::io::Read,
110    ) -> ExnResult<gix_hash::ObjectId> {
111        crate::compute_stream_hash(
112            gix_hash::Kind::default(),
113            kind,
114            from,
115            size,
116            &mut gix_features::progress::Discard,
117            &std::sync::atomic::AtomicBool::new(false),
118        )
119        .or_erased()
120    }
121
122    fn write_stream_with_known_id(
123        &self,
124        _kind: crate::Kind,
125        mut size: u64,
126        from: &mut dyn std::io::Read,
127        id: gix_hash::ObjectId,
128    ) -> ExnResult<gix_hash::ObjectId> {
129        let mut buf = [0u8; u16::MAX as usize];
130        while size != 0 {
131            let bytes = (size as usize).min(buf.len());
132            from.read_exact(&mut buf[..bytes]).or_erased()?;
133            size -= bytes as u64;
134        }
135        Ok(id)
136    }
137}