gix_lock/
commit.rs

1use std::path::PathBuf;
2
3use crate::{File, Marker};
4
5mod error {
6    use std::{
7        fmt,
8        fmt::{Debug, Display},
9    };
10
11    /// The error returned by various [`commit(…)`][super::Marker::commit()] methods
12    #[derive(Debug)]
13    pub struct Error<T: Debug> {
14        /// The io error that prevented the attempt to succeed
15        pub error: std::io::Error,
16        /// The marker or file which was used in the attempt to persist it
17        pub instance: T,
18    }
19
20    impl<T: Debug> Display for Error<T> {
21        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22            Display::fmt(&self.error, f)
23        }
24    }
25
26    impl<T: Debug> std::error::Error for Error<T> {
27        fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
28            self.error.source()
29        }
30    }
31}
32pub use error::Error;
33
34impl Marker {
35    /// Commit the changes written to the previously open file and overwrite the original file atomically, returning the resource path
36    /// on success.
37    ///
38    /// This fails for markers which weren't created with [`File::close()`]
39    pub fn commit(mut self) -> Result<PathBuf, Error<Self>> {
40        if !self.created_from_file {
41            return Err(Error {
42                error: std::io::Error::other("refusing to commit marker that was never opened"),
43                instance: self,
44            });
45        }
46        let resource_path = self.resource_path();
47        match self.inner.persist(&resource_path) {
48            Ok(_) => Ok(resource_path),
49            Err(err) => Err(Error {
50                error: err.error,
51                instance: {
52                    self.inner = err.handle;
53                    self
54                },
55            }),
56        }
57    }
58}
59
60impl File {
61    /// Commit the changes written to this lock file and overwrite the original file atomically, returning the resource path
62    /// and an open file handle on success.
63    pub fn commit(mut self) -> Result<(PathBuf, Option<std::fs::File>), Error<Self>> {
64        let resource_path = self.resource_path();
65        match self.inner.persist(&resource_path) {
66            Ok(possibly_file) => Ok((resource_path, possibly_file)),
67            Err(err) => Err(Error {
68                error: err.error,
69                instance: {
70                    self.inner = err.handle;
71                    self
72                },
73            }),
74        }
75    }
76}