use std::path::Path;
use std::path::PathBuf;
use inquire::validator::ValueRequiredValidator;
use super::validators;
use super::PromptError;
use super::SEP;
pub struct PromptPath
{
message: String,
default: Option<PathBuf>,
existing: bool,
creating: bool,
dir: bool,
file: bool,
}
impl PromptPath
{
pub fn new<S>(message: S) -> Self
where
S: AsRef<str>,
{
let inner = |message: &str| {
let message = format!("{message}{SEP}");
Self {
message,
default: None,
existing: false,
creating: false,
dir: false,
file: false,
}
};
inner(message.as_ref())
}
pub fn with_default<P>(
mut self,
value: P,
) -> Self
where
P: AsRef<Path>,
{
let inner = |value: &Path| {
self.default = Some(value.to_path_buf());
self
};
inner(value.as_ref())
}
pub fn existing(mut self) -> Self
{
self.existing = true;
self
}
pub fn creating_file(mut self) -> Self
{
self.creating = true;
self.file = true;
self
}
pub fn creating_dir(mut self) -> Self
{
self.creating = true;
self.dir = true;
self
}
pub fn is_dir(mut self) -> Self
{
self.dir = true;
self
}
pub fn is_file(mut self) -> Self
{
self.file = true;
self
}
pub fn prompt(self) -> Result<PathBuf, PromptError>
{
let Self {
message,
default,
existing,
creating,
dir,
file,
} = self;
let mut prompt = inquire::Text::new(&message);
if let Some(default) = default.as_ref()
{
prompt = prompt.with_default(
default
.to_str()
.unwrap(),
);
}
prompt = prompt.with_validator(ValueRequiredValidator::default());
if existing && dir
{
prompt = prompt.with_validator(validators::path_existing_dir);
}
else if existing && file
{
prompt = prompt.with_validator(validators::path_existing_file);
}
else if existing
{
prompt = prompt.with_validator(validators::path_existing);
}
else
{
prompt = prompt.with_validator(validators::path);
}
if creating && dir
{
prompt = prompt.with_validator(validators::path_creating_dir);
}
else if creating && file
{
prompt = prompt.with_validator(validators::path_creating_file);
}
let response = prompt.prompt()?;
let path = PathBuf::new().join(response);
Ok(path)
}
}