1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use super::RapidCommand;use crate::{
	cli::{current_directory, logo, rapid_logo, Config},
	constants::BOLT_EMOJI,
};
use clap::{arg, value_parser, ArgAction, ArgMatches, Command};
use colorful::{Color, Colorful};
use std::{
	path::PathBuf,
	thread, time,
};
use include_dir::{include_dir, Dir};
use rust_embed::RustEmbed;


// We need to get the project directory to extract the template files (this is because include_dir!() is yoinked inside of a workspace)
const PROJECT_DIR: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/src/templates/server");

pub struct New {}

impl RapidCommand for New {
	fn cmd() -> clap::Command {
		Command::new("new")
			.about("Creates a new rapid project at the current working directory!")
			.arg(
				arg!(
					-full --fullstack "Scaffolds a fullstack rapid project!"
				)
				.required(false)
				.action(ArgAction::SetTrue)
				.value_parser(value_parser!(PathBuf)),
			)
			.arg(
				arg!(
					-server --server "Scaffolds a server-side only rapid project!"
				)
				.required(false)
				.action(ArgAction::SetTrue)
				.value_parser(value_parser!(PathBuf)),
			)
	}

	fn execute(_: &Config, args: &ArgMatches) -> Result<(), crate::cli::CliError<'static>> {
		println!("{}", logo());
		parse_new_args(args);
		Ok(())
	}
}


pub fn parse_new_args(args: &ArgMatches) {
	/// NOTE: We can add more args for templates here (ideally we add nextjs asap)
	const NEW_ARGS: [&str; 2] = ["fullstack", "server"];
	// Get the current working directory of the user
	let current_working_directory = current_directory();

	for arg in NEW_ARGS {
		match args.get_one::<PathBuf>(arg) {
			Some(val) => {
				if val == &PathBuf::from("true") {
					match arg {
						"fullstack" => {
							init_fullstack_template(current_working_directory, arg);
							break;
						}
						"server" => {
							init_server_template(current_working_directory, arg);
							break;
						}
						_ => {
							println!("> Invalid argument passed to new command!");
							break;
						}
					}
				}
			}
			None => {
				println!("> No argument passed to new command!");
				break;
			}
		}
	}
}

pub fn init_fullstack_template(current_working_directory: PathBuf, arg: &str) {
	println!("Coming soon...");
}

pub fn init_server_template(current_working_directory: PathBuf, arg: &str) {
	PROJECT_DIR.extract(current_working_directory).unwrap();
	println!("{} {:?}...", "Initializing a new rapid-web server application".color(Color::Green), arg);

	// Sleep a little to show loading animation, etc (there is a nice one we could use from the "tui" crate)
	let timeout = time::Duration::from_millis(500);
	thread::sleep(timeout);

	println!(
		"{} {} {} {}",
		format!("{}", rapid_logo()).bold(),
		"Success".bg_blue().color(Color::White).bold(),
		BOLT_EMOJI,
		"Welcome to your new rapid-web server application!"
	);
}