1use crate::{write, File, Version};
2
3#[derive(Debug, thiserror::Error)]
5#[allow(missing_docs)]
6pub enum Error {
7 #[error(transparent)]
8 Io(#[from] gix_hash::io::Error),
9 #[error("Could not acquire lock for index file")]
10 AcquireLock(#[from] gix_lock::acquire::Error),
11 #[error("Could not commit lock for index file")]
12 CommitLock(#[from] gix_lock::commit::Error<gix_lock::File>),
13}
14
15impl File {
16 pub fn write_to(
19 &self,
20 mut out: impl std::io::Write,
21 options: write::Options,
22 ) -> Result<(Version, gix_hash::ObjectId), gix_hash::io::Error> {
23 let _span = gix_features::trace::detail!("gix_index::File::write_to()", skip_hash = options.skip_hash);
24 let (version, hash) = if options.skip_hash {
25 let out: &mut dyn std::io::Write = &mut out;
26 let version = self.state.write_to(out, options)?;
27 (version, self.state.object_hash.null())
28 } else {
29 let mut hasher = gix_hash::io::Write::new(&mut out, self.state.object_hash);
30 let out: &mut dyn std::io::Write = &mut hasher;
31 let version = self.state.write_to(out, options)?;
32 (version, hasher.hash.try_finalize()?)
33 };
34 out.write_all(hash.as_slice())?;
35 Ok((version, hash))
36 }
37
38 pub fn write(&mut self, options: write::Options) -> Result<(), Error> {
42 let _span = gix_features::trace::detail!("gix_index::File::write()", path = ?self.path);
43 let mut lock = std::io::BufWriter::with_capacity(
44 64 * 1024,
45 gix_lock::File::acquire_to_update_resource(&self.path, gix_lock::acquire::Fail::Immediately, None)?,
46 );
47 let (version, digest) = self.write_to(&mut lock, options)?;
48 match lock.into_inner() {
49 Ok(lock) => lock.commit()?,
50 Err(err) => return Err(Error::Io(err.into_error().into())),
51 };
52 self.state.version = version;
53 self.checksum = Some(digest);
54 Ok(())
55 }
56}