1use crate::opts::Action;
2use crate::opts::Opts;
3use crate::templates::error_svelte;
4use crate::templates::error_svelte_js;
5use crate::templates::layout_client;
6use crate::templates::layout_client_js;
7use crate::templates::layout_server;
8use crate::templates::layout_server_js;
9use crate::templates::layout_svelte;
10use crate::templates::layout_svelte_js;
11use crate::templates::page_client;
12use crate::templates::page_client_js;
13use crate::templates::page_server;
14use crate::templates::page_server_js;
15use crate::templates::page_svelte;
16use crate::templates::page_svelte_js;
17use crate::templates::server;
18use crate::templates::server_js;
19use ::anyhow::Result;
20use anyhow::Context;
21use std::path::PathBuf;
22use std::str::FromStr;
23
24#[derive(Debug)]
25pub struct Setup {
26 pub action: Action,
27 pub operation: Operation,
28 pub pwd: PathBuf,
29}
30
31impl TryFrom<Opts> for Setup {
32 type Error = anyhow::Error;
33
34 fn try_from(value: Opts) -> Result<Self> {
35 let operation = Operation::try_from(&value.action)?;
36 let pwd = PathBuf::try_from(&value.action)?;
37
38 Ok(Setup {
39 action: value.action,
40 operation,
41 pwd,
42 })
43 }
44}
45
46#[derive(Debug)]
47pub enum Operation {
48 Print,
49 Pages(Vec<Page>),
50 ConfigTemplatesPath(PathBuf),
51 ConfigLanguage(String),
52}
53
54#[derive(Debug)]
55pub enum Page {
56 E,
57 L,
58 Lc,
59 Ls,
60 P,
61 Pc,
62 Ps,
63 S,
64}
65
66impl Page {
67 pub fn all() -> Vec<&'static str> {
68 vec!["e", "l", "lc", "ls", "p", "pc", "ps", "s"]
69 }
70
71 pub fn get_page(&self, lang: &String) -> &'static str {
72 if lang == "ts" {
73 match self {
74 Page::E => "+error.svelte",
75 Page::L => "+layout.svelte",
76 Page::Lc => "+layout.ts",
77 Page::Ls => "+layout.server.ts",
78 Page::P => "+page.svelte",
79 Page::Pc => "+page.ts",
80 Page::Ps => "+page.server.ts",
81 Page::S => "+server.ts",
82 }
83 } else if lang == "js" {
84 match self {
85 Page::E => "+error.svelte",
86 Page::L => "+layout.svelte",
87 Page::Lc => "+layout.js",
88 Page::Ls => "+layout.server.js",
89 Page::P => "+page.svelte",
90 Page::Pc => "+page.js",
91 Page::Ps => "+page.server.js",
92 Page::S => "+server.js",
93 }
94 } else {
95 Err(anyhow::anyhow!("Invalid language: {}", lang))
96 .context("Invalid language")
97 .unwrap()
98 }
99 }
100
101 pub fn get_content(&self, lang: &String) -> &'static str {
102 if lang == "ts" {
103 match self {
104 Page::E => error_svelte(),
105 Page::L => layout_svelte(),
106 Page::Lc => layout_client(),
107 Page::Ls => layout_server(),
108 Page::P => page_svelte(),
109 Page::Pc => page_client(),
110 Page::Ps => page_server(),
111 Page::S => server(),
112 }
113 } else if lang == "js" {
114 match self {
115 Page::E => error_svelte_js(),
116 Page::L => layout_svelte_js(),
117 Page::Lc => layout_client_js(),
118 Page::Ls => layout_server_js(),
119 Page::P => page_svelte_js(),
120 Page::Pc => page_client_js(),
121 Page::Ps => page_server_js(),
122 Page::S => server_js(),
123 }
124 } else {
125 Err(anyhow::anyhow!("Invalid language: {}", lang))
126 .context("Invalid language")
127 .unwrap()
128 }
129 }
130}
131
132impl FromStr for Page {
133 type Err = anyhow::Error;
134
135 fn from_str(s: &str) -> Result<Self> {
136 match s {
137 "e" => Ok(Page::E),
138 "l" => Ok(Page::L),
139 "lc" => Ok(Page::Lc),
140 "ls" => Ok(Page::Ls),
141 "p" => Ok(Page::P),
142 "pc" => Ok(Page::Pc),
143 "ps" => Ok(Page::Ps),
144 "s" => Ok(Page::S),
145 _ => Err(anyhow::anyhow!(
146 "Invalid value {}. Allowed values are: {:?}",
147 s,
148 Page::all()
149 )),
150 }
151 }
152}
153
154impl TryFrom<&Action> for Operation {
155 type Error = anyhow::Error;
156
157 fn try_from(value: &Action) -> Result<Self> {
158 match value {
159 Action::Print => Ok(Operation::Print),
160 Action::Add(values) => {
161 if values.args.is_empty() {
162 return Err(anyhow::anyhow!("no args"));
163 }
164 for arg in &values.args {
165 Page::from_str(arg)?;
166 }
167 Ok(Operation::Pages(
168 values
169 .args
170 .iter()
171 .map(|v| Page::from_str(v).unwrap())
172 .collect(),
173 ))
174 }
175 Action::Config(values) => {
176 if values.key == "temp" {
177 return Ok(Operation::ConfigTemplatesPath(PathBuf::from(&values.value)));
178 } else if values.key == "lang" {
179 if values.value != "ts" && values.value != "js" {
180 return Err(anyhow::anyhow!("Invalid value for lang"));
181 }
182 return Ok(Operation::ConfigLanguage(values.value.to_owned()));
183 }
184 return Err(anyhow::anyhow!("Invalid key"));
185 }
186 }
187 }
188}
189
190impl TryFrom<&Action> for PathBuf {
191 type Error = anyhow::Error;
192
193 fn try_from(value: &Action) -> Result<Self> {
194 match value {
195 Action::Add(values) => get_pwd(values.pwd.clone()),
196 Action::Config(_) => get_pwd(None),
197 Action::Print => get_pwd(None),
198 }
199 }
200}
201
202fn get_pwd(pwd: Option<PathBuf>) -> Result<PathBuf> {
203 if let Some(v) = pwd {
204 return Ok(v);
205 }
206 let loc = std::env::current_dir().context("pwd not set")?;
207 return Ok(loc);
208}