sveltecli/
setup.rs

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}