pavex_cli_client/commands/
new.rs1use crate::commands::errors::{InvocationError, NonZeroExitCode, SignalTermination};
2use std::{path::PathBuf, process::Command, str::FromStr};
3
4#[derive(Clone, Debug, PartialEq, Eq)]
6#[non_exhaustive]
7pub enum TemplateName {
8 Api,
10 Quickstart,
12}
13
14impl TemplateName {
15 pub fn as_str(&self) -> &str {
16 match self {
17 TemplateName::Api => "api",
18 TemplateName::Quickstart => "quickstart",
19 }
20 }
21}
22
23impl FromStr for TemplateName {
24 type Err = InvalidTemplateName;
25
26 fn from_str(s: &str) -> Result<Self, Self::Err> {
27 match s {
28 "api" => Ok(TemplateName::Api),
29 "quickstart" => Ok(TemplateName::Quickstart),
30 s => Err(InvalidTemplateName {
31 name: s.to_string(),
32 }),
33 }
34 }
35}
36
37#[derive(Debug, thiserror::Error)]
38#[error("`{name}` is not a valid template name. Use either `api` or `quickstart`.")]
39pub struct InvalidTemplateName {
40 pub(crate) name: String,
41}
42
43pub struct NewBuilder {
49 cmd: Command,
50 path: PathBuf,
51 template: TemplateName,
52}
53
54impl NewBuilder {
55 pub(crate) fn new(cmd: Command, path: PathBuf) -> Self {
56 Self {
57 cmd,
58 path,
59 template: TemplateName::Api,
60 }
61 }
62
63 pub fn template(mut self, template: TemplateName) -> Self {
65 self.template = template;
66 self
67 }
68
69 pub fn execute(self) -> Result<(), NewError> {
76 let mut cmd = self.command();
77 let cmd_debug = format!("{cmd:?}");
78 let status = cmd
79 .status()
80 .map_err(|e| InvocationError {
81 source: e,
82 command: cmd_debug.clone(),
83 })
84 .map_err(NewError::InvocationError)?;
85 if !status.success() {
86 if let Some(code) = status.code() {
87 return Err(NewError::NonZeroExitCode(NonZeroExitCode {
88 code,
89 command: cmd_debug,
90 }));
91 } else {
92 return Err(NewError::SignalTermination(SignalTermination {
93 command: cmd_debug,
94 }));
95 }
96 }
97 Ok(())
98 }
99
100 pub fn command(mut self) -> Command {
106 self.cmd
107 .arg("new")
108 .arg(self.path)
109 .arg("--template")
110 .arg(self.template.as_str())
111 .stdout(std::process::Stdio::inherit())
112 .stderr(std::process::Stdio::inherit());
113 self.cmd
114 }
115}
116
117#[derive(Debug, thiserror::Error)]
118#[non_exhaustive]
119pub enum NewError {
120 #[error(transparent)]
121 InvocationError(InvocationError),
122 #[error(transparent)]
123 SignalTermination(SignalTermination),
124 #[error(transparent)]
125 NonZeroExitCode(NonZeroExitCode),
126}