use std::path::PathBuf; use crate::{File, Marker}; mod error { use std::{ fmt, fmt::{Debug, Display}, }; /// The error returned by various [`commit(…)`][super::Marker::commit()] methods #[derive(Debug)] pub struct Error { /// The io error that prevented the attempt to succeed pub error: std::io::Error, /// The marker or file which was used in the attempt to persist it pub instance: T, } impl Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { Display::fmt(&self.error, f) } } impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { self.error.source() } } } pub use error::Error; impl Marker { /// Commit the changes written to the previously open file and overwrite the original file atomically, returning the resource path /// on success. /// /// This fails for markers which weren't created with [`File::close()`] pub fn commit(mut self) -> Result> { if !self.created_from_file { return Err(Error { error: std::io::Error::new( std::io::ErrorKind::Other, "refusing to commit marker that was never opened", ), instance: self, }); } let resource_path = self.resource_path(); match self.inner.persist(&resource_path) { Ok(_) => Ok(resource_path), Err(err) => Err(Error { error: err.error, instance: { self.inner = err.handle; self }, }), } } } impl File { /// Commit the changes written to this lock file and overwrite the original file atomically, returning the resource path /// and an open file handle on success. pub fn commit(mut self) -> Result<(PathBuf, Option), Error> { let resource_path = self.resource_path(); match self.inner.persist(&resource_path) { Ok(possibly_file) => Ok((resource_path, possibly_file)), Err(err) => Err(Error { error: err.error, instance: { self.inner = err.handle; self }, }), } } }