mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-08-02 14:07:46 +00:00
backup_control: Implement custom error type
Implements an error type based on `UError` that replaces the previously used error strings. The errors are currently returned when determining the backup mode, but extensions for future uses are already in place as comments.
This commit is contained in:
parent
2c6410f4d8
commit
54086ef4c5
2 changed files with 143 additions and 0 deletions
|
@ -16,6 +16,7 @@ edition = "2018"
|
||||||
path="src/lib/lib.rs"
|
path="src/lib/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
clap = "2.33.3"
|
||||||
dns-lookup = { version="1.0.5", optional=true }
|
dns-lookup = { version="1.0.5", optional=true }
|
||||||
dunce = "1.0.0"
|
dunce = "1.0.0"
|
||||||
getopts = "<= 0.2.21"
|
getopts = "<= 0.2.21"
|
||||||
|
|
|
@ -1,5 +1,89 @@
|
||||||
|
//! Implement GNU-style backup functionality.
|
||||||
|
//!
|
||||||
|
//! This module implements the backup functionality as described in the [GNU
|
||||||
|
//! manual][1]. It provides
|
||||||
|
//!
|
||||||
|
//! - pre-defined [`clap`-Arguments][2] for inclusion in utilities that
|
||||||
|
//! implement backups
|
||||||
|
//! - determination of the [backup mode][3]
|
||||||
|
//! - determination of the [backup suffix][4]
|
||||||
|
//! - [backup target path construction][5]
|
||||||
|
//! - [Error types][6] for backup-related errors
|
||||||
|
//! - GNU-compliant [help texts][7] for backup-related errors
|
||||||
|
//!
|
||||||
|
//! Backup-functionality is implemented by the following utilities:
|
||||||
|
//!
|
||||||
|
//! - `cp`
|
||||||
|
//! - `install`
|
||||||
|
//! - `ln`
|
||||||
|
//! - `mv`
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
//! [1]: https://www.gnu.org/software/coreutils/manual/html_node/Backup-options.html
|
||||||
|
//! [2]: arguments
|
||||||
|
//! [3]: `determine_backup_mode()`
|
||||||
|
//! [4]: `determine_backup_suffix()`
|
||||||
|
//! [5]: `get_backup_path()`
|
||||||
|
//! [6]: `BackupError`
|
||||||
|
//! [7]: `BACKUP_CONTROL_LONG_HELP`
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
//! # Usage example
|
||||||
|
//!
|
||||||
|
//! ```
|
||||||
|
//! #[macro_use]
|
||||||
|
//! extern crate uucore;
|
||||||
|
//!
|
||||||
|
//! use clap::{App, Arg, ArgMatches};
|
||||||
|
//! use std::path::{Path, PathBuf};
|
||||||
|
//! use uucore::backup_control::{self, BackupMode};
|
||||||
|
//! use uucore::error::{UError, UResult};
|
||||||
|
//!
|
||||||
|
//! fn main() {
|
||||||
|
//! let usage = String::from("app [OPTION]... ARG");
|
||||||
|
//! let long_usage = String::from("And here's a detailed explanation");
|
||||||
|
//!
|
||||||
|
//! let matches = App::new("app")
|
||||||
|
//! .arg(backup_control::arguments::backup())
|
||||||
|
//! .arg(backup_control::arguments::backup_no_args())
|
||||||
|
//! .arg(backup_control::arguments::suffix())
|
||||||
|
//! .usage(&usage[..])
|
||||||
|
//! .after_help(&*format!(
|
||||||
|
//! "{}\n{}",
|
||||||
|
//! long_usage,
|
||||||
|
//! backup_control::BACKUP_CONTROL_LONG_HELP
|
||||||
|
//! ))
|
||||||
|
//! .get_matches_from(vec![
|
||||||
|
//! "app", "--backup=t", "--suffix=bak~"
|
||||||
|
//! ]);
|
||||||
|
//!
|
||||||
|
//! let backup_mode = match backup_control::determine_backup_mode(&matches) {
|
||||||
|
//! Err(e) => {
|
||||||
|
//! show!(e);
|
||||||
|
//! return;
|
||||||
|
//! },
|
||||||
|
//! Ok(mode) => mode,
|
||||||
|
//! };
|
||||||
|
//! let backup_suffix = backup_control::determine_backup_suffix(&matches);
|
||||||
|
//! let target_path = Path::new("/tmp/example");
|
||||||
|
//!
|
||||||
|
//! let backup_path = backup_control::get_backup_path(
|
||||||
|
//! backup_mode, target_path, &backup_suffix
|
||||||
|
//! );
|
||||||
|
//!
|
||||||
|
//! // Perform your backups here.
|
||||||
|
//!
|
||||||
|
//! }
|
||||||
|
//! ```
|
||||||
|
|
||||||
|
// spell-checker:ignore backupopt
|
||||||
|
|
||||||
|
use crate::error::{UError, UResult};
|
||||||
|
use clap::ArgMatches;
|
||||||
use std::{
|
use std::{
|
||||||
env,
|
env,
|
||||||
|
error::Error,
|
||||||
|
fmt::{Debug, Display},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,6 +101,12 @@ the VERSION_CONTROL environment variable. Here are the values:
|
||||||
existing, nil numbered if numbered backups exist, simple otherwise
|
existing, nil numbered if numbered backups exist, simple otherwise
|
||||||
simple, never always make simple backups";
|
simple, never always make simple backups";
|
||||||
|
|
||||||
|
static VALID_ARGS_HELP: &str = "Valid arguments are:
|
||||||
|
- ‘none’, ‘off’
|
||||||
|
- ‘simple’, ‘never’
|
||||||
|
- ‘existing’, ‘nil’
|
||||||
|
- ‘numbered’, ‘t’";
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||||
pub enum BackupMode {
|
pub enum BackupMode {
|
||||||
NoBackup,
|
NoBackup,
|
||||||
|
@ -25,6 +115,58 @@ pub enum BackupMode {
|
||||||
ExistingBackup,
|
ExistingBackup,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
|
pub enum BackupError {
|
||||||
|
InvalidArgument(String, String),
|
||||||
|
AmbiguousArgument(String, String),
|
||||||
|
BackupImpossible(),
|
||||||
|
// BackupFailed(PathBuf, PathBuf, std::io::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UError for BackupError {
|
||||||
|
fn code(&self) -> i32 {
|
||||||
|
match self {
|
||||||
|
BackupError::BackupImpossible() => 2,
|
||||||
|
_ => 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn usage(&self) -> bool {
|
||||||
|
// Suggested by clippy.
|
||||||
|
matches!(
|
||||||
|
self,
|
||||||
|
BackupError::InvalidArgument(_, _) | BackupError::AmbiguousArgument(_, _)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error for BackupError {}
|
||||||
|
|
||||||
|
impl Display for BackupError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
use BackupError as BE;
|
||||||
|
match self {
|
||||||
|
BE::InvalidArgument(arg, origin) => write!(
|
||||||
|
f,
|
||||||
|
"invalid argument ‘{}’ for ‘{}’\n{}",
|
||||||
|
arg, origin, VALID_ARGS_HELP
|
||||||
|
),
|
||||||
|
BE::AmbiguousArgument(arg, origin) => write!(
|
||||||
|
f,
|
||||||
|
"ambiguous argument ‘{}’ for ‘{}’\n{}",
|
||||||
|
arg, origin, VALID_ARGS_HELP
|
||||||
|
),
|
||||||
|
BE::BackupImpossible() => write!(f, "cannot create backup"),
|
||||||
|
// Placeholder for later
|
||||||
|
// BE::BackupFailed(from, to, e) => Display::fmt(
|
||||||
|
// &uio_error!(e, "failed to backup '{}' to '{}'", from.display(), to.display()),
|
||||||
|
// f
|
||||||
|
// ),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Arguments for backup-related functionality
|
||||||
pub mod arguments {
|
pub mod arguments {
|
||||||
extern crate clap;
|
extern crate clap;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue