summaryrefslogtreecommitdiffstats
path: root/vendor/gix-tempfile/src/fs/create_dir.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gix-tempfile/src/fs/create_dir.rs')
-rw-r--r--vendor/gix-tempfile/src/fs/create_dir.rs202
1 files changed, 0 insertions, 202 deletions
diff --git a/vendor/gix-tempfile/src/fs/create_dir.rs b/vendor/gix-tempfile/src/fs/create_dir.rs
deleted file mode 100644
index 65efdb2b8..000000000
--- a/vendor/gix-tempfile/src/fs/create_dir.rs
+++ /dev/null
@@ -1,202 +0,0 @@
-//!
-use std::path::Path;
-
-/// The amount of retries to do during various aspects of the directory creation.
-#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq)]
-pub struct Retries {
- /// How many times the whole directory can be created in the light of racy interference.
- /// This count combats racy situations where another process is trying to remove a directory that we want to create,
- /// and is deliberately higher than those who do deletion. That way, creation usually wins.
- pub to_create_entire_directory: usize,
- /// The amount of times we can try to create a directory because we couldn't as the parent didn't exist.
- /// This amounts to the maximum subdirectory depth we allow to be created. Counts once per attempt to create the entire directory.
- pub on_create_directory_failure: usize,
- /// How often to retry to create a single directory if an interrupt happens, as caused by signals.
- pub on_interrupt: usize,
-}
-
-impl Default for Retries {
- fn default() -> Self {
- Retries {
- on_interrupt: 10,
- to_create_entire_directory: 5,
- on_create_directory_failure: 25,
- }
- }
-}
-
-mod error {
- use std::{fmt, path::Path};
-
- use crate::fs::create_dir::Retries;
-
- /// The error returned by [all()][super::all()].
- #[allow(missing_docs)]
- #[derive(Debug)]
- pub enum Error<'a> {
- /// A failure we will probably recover from by trying again.
- Intermediate { dir: &'a Path, kind: std::io::ErrorKind },
- /// A failure that ends the operation.
- Permanent {
- dir: &'a Path,
- err: std::io::Error,
- /// The retries left after running the operation
- retries_left: Retries,
- /// The original amount of retries to allow determining how many were actually used
- retries: Retries,
- },
- }
-
- impl<'a> fmt::Display for Error<'a> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- Error::Intermediate { dir, kind } => write!(
- f,
- "Intermediae failure creating {:?} with error: {:?}",
- dir.display(),
- kind
- ),
- Error::Permanent {
- err: _,
- dir,
- retries_left,
- retries,
- } => write!(
- f,
- "Permanently failing to create directory {dir:?} ({retries_left:?} of {retries:?})",
- ),
- }
- }
- }
-
- impl<'a> std::error::Error for Error<'a> {
- fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
- match self {
- Error::Permanent { err, .. } => Some(err),
- _ => None,
- }
- }
- }
-}
-pub use error::Error;
-
-enum State {
- CurrentlyCreatingDirectories,
- SearchingUpwardsForExistingDirectory,
-}
-
-/// A special iterator which communicates its operation through results where…
-///
-/// * `Some(Ok(created_directory))` is yielded once or more success, followed by `None`
-/// * `Some(Err(Error::Intermediate))` is yielded zero or more times while trying to create the directory.
-/// * `Some(Err(Error::Permanent))` is yielded exactly once on failure.
-pub struct Iter<'a> {
- cursors: Vec<&'a Path>,
- retries: Retries,
- original_retries: Retries,
- state: State,
-}
-
-/// Construction
-impl<'a> Iter<'a> {
- /// Create a new instance that creates `target` when iterated with the default amount of [`Retries`].
- pub fn new(target: &'a Path) -> Self {
- Self::new_with_retries(target, Default::default())
- }
-
- /// Create a new instance that creates `target` when iterated with the specified amount of `retries`.
- pub fn new_with_retries(target: &'a Path, retries: Retries) -> Self {
- Iter {
- cursors: vec![target],
- original_retries: retries,
- retries,
- state: State::SearchingUpwardsForExistingDirectory,
- }
- }
-}
-
-impl<'a> Iter<'a> {
- fn pernanent_failure(
- &mut self,
- dir: &'a Path,
- err: impl Into<std::io::Error>,
- ) -> Option<Result<&'a Path, Error<'a>>> {
- self.cursors.clear();
- Some(Err(Error::Permanent {
- err: err.into(),
- dir,
- retries_left: self.retries,
- retries: self.original_retries,
- }))
- }
-
- fn intermediate_failure(&self, dir: &'a Path, err: std::io::Error) -> Option<Result<&'a Path, Error<'a>>> {
- Some(Err(Error::Intermediate { dir, kind: err.kind() }))
- }
-}
-
-impl<'a> Iterator for Iter<'a> {
- type Item = Result<&'a Path, Error<'a>>;
-
- fn next(&mut self) -> Option<Self::Item> {
- use std::io::ErrorKind::*;
- match self.cursors.pop() {
- Some(dir) => match std::fs::create_dir(dir) {
- Ok(()) => {
- self.state = State::CurrentlyCreatingDirectories;
- Some(Ok(dir))
- }
- Err(err) => match err.kind() {
- AlreadyExists if dir.is_dir() => {
- self.state = State::CurrentlyCreatingDirectories;
- Some(Ok(dir))
- }
- AlreadyExists => self.pernanent_failure(dir, err), // is non-directory
- NotFound => {
- self.retries.on_create_directory_failure -= 1;
- if let State::CurrentlyCreatingDirectories = self.state {
- self.state = State::SearchingUpwardsForExistingDirectory;
- self.retries.to_create_entire_directory -= 1;
- if self.retries.to_create_entire_directory < 1 {
- return self.pernanent_failure(dir, NotFound);
- }
- self.retries.on_create_directory_failure =
- self.original_retries.on_create_directory_failure;
- }
- if self.retries.on_create_directory_failure < 1 {
- return self.pernanent_failure(dir, NotFound);
- };
- self.cursors.push(dir);
- self.cursors.push(match dir.parent() {
- None => return self.pernanent_failure(dir, InvalidInput),
- Some(parent) => parent,
- });
- self.intermediate_failure(dir, err)
- }
- Interrupted => {
- self.retries.on_interrupt -= 1;
- if self.retries.on_interrupt <= 1 {
- return self.pernanent_failure(dir, Interrupted);
- };
- self.cursors.push(dir);
- self.intermediate_failure(dir, err)
- }
- _unexpected_kind => self.pernanent_failure(dir, err),
- },
- },
- None => None,
- }
- }
-}
-
-/// Create all directories leading to `dir` including `dir` itself with the specified amount of `retries`.
-/// Returns the input `dir` on success that make it useful in expressions.
-pub fn all(dir: &Path, retries: Retries) -> std::io::Result<&Path> {
- for res in Iter::new_with_retries(dir, retries) {
- match res {
- Err(Error::Permanent { err, .. }) => return Err(err),
- Err(Error::Intermediate { .. }) | Ok(_) => continue,
- }
- }
- Ok(dir)
-}