use crate::commands::errors::{InvocationError, NonZeroExitCode, SignalTermination};
use std::{path::PathBuf, process::Command, str::FromStr};
#[derive(Clone, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum TemplateName {
Api,
Quickstart,
}
impl TemplateName {
pub fn as_str(&self) -> &str {
match self {
TemplateName::Api => "api",
TemplateName::Quickstart => "quickstart",
}
}
}
impl FromStr for TemplateName {
type Err = InvalidTemplateName;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"api" => Ok(TemplateName::Api),
"quickstart" => Ok(TemplateName::Quickstart),
s => Err(InvalidTemplateName {
name: s.to_string(),
}),
}
}
}
#[derive(Debug, thiserror::Error)]
#[error("`{name}` is not a valid template name. Use either `api` or `quickstart`.")]
pub struct InvalidTemplateName {
pub(crate) name: String,
}
pub struct NewBuilder {
cmd: Command,
path: PathBuf,
template: TemplateName,
}
static NEW_DEBUG_COMMAND: &str = "pavex [...] new [...]";
impl NewBuilder {
pub(crate) fn new(cmd: Command, path: PathBuf) -> Self {
Self {
cmd,
path,
template: TemplateName::Api,
}
}
pub fn template(mut self, template: TemplateName) -> Self {
self.template = template;
self
}
pub fn execute(self) -> Result<(), NewError> {
let mut cmd = self.command();
let status = cmd
.status()
.map_err(|e| InvocationError {
source: e,
command: NEW_DEBUG_COMMAND,
})
.map_err(NewError::InvocationError)?;
if !status.success() {
if let Some(code) = status.code() {
return Err(NewError::NonZeroExitCode(NonZeroExitCode {
code,
command: NEW_DEBUG_COMMAND,
}));
} else {
return Err(NewError::SignalTermination(SignalTermination {
command: NEW_DEBUG_COMMAND,
}));
}
}
Ok(())
}
pub fn command(mut self) -> Command {
self.cmd
.arg("new")
.arg(self.path)
.arg("--template")
.arg(self.template.as_str())
.stdout(std::process::Stdio::inherit())
.stderr(std::process::Stdio::inherit());
self.cmd
}
}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum NewError {
#[error(transparent)]
InvocationError(InvocationError),
#[error(transparent)]
SignalTermination(SignalTermination),
#[error(transparent)]
NonZeroExitCode(NonZeroExitCode),
}