@@ -3,45 +3,63 @@ use std::{
33 path:: { Path , PathBuf } ,
44} ;
55
6+ use colored:: Colorize ;
67use mod_project:: { ModProject , ModProjectAuthor } ;
78
8- use crate :: utils:: validate_mod_name;
9+ use crate :: utils:: { is_valid_mod_name, validate_mod_name} ;
10+ use inquire:: { validator:: Validation , Text } ;
911
1012#[ derive( Debug , Clone ) ]
1113pub struct InitModProjectArgs {
12- pub name : String ,
14+ pub name : Option < String > ,
1315 pub display_name : Option < String > ,
1416
1517 pub output_dir : Option < String > ,
1618}
1719
1820pub fn init_mod_project ( args : InitModProjectArgs ) -> eyre:: Result < ( ) > {
19- validate_mod_name ( & args. name ) ?;
21+ let display_name = match args. display_name {
22+ Some ( ref display_name) => display_name. clone ( ) ,
23+ None => prompt_mod_display_name ( ) ?,
24+ } ;
25+
26+ let name = match args. name {
27+ Some ( name) => {
28+ validate_mod_name ( & name) ?;
29+ name
30+ }
31+ None => prompt_mod_name ( & display_name) ?,
32+ } ;
2033
21- println ! ( "Initializing new project: {}" , args . name) ;
34+ println ! ( "Initializing new project: {}" , name. bold ( ) . bright_cyan ( ) ) ;
2235
2336 let mod_project_dir_path = match args. output_dir {
24- Some ( ref output_dir) => PathBuf :: from ( output_dir) . join ( & args . name ) ,
25- None => create_mod_project_dir_path ( & args . name ) ?,
37+ Some ( ref output_dir) => PathBuf :: from ( output_dir) . join ( & name) ,
38+ None => create_mod_project_dir_path ( & name) ?,
2639 } ;
2740
2841 println ! (
2942 "Creating mod project directory at: {}" ,
30- mod_project_dir_path. display( )
43+ mod_project_dir_path
44+ . display( )
45+ . to_string( )
46+ . bold( )
47+ . bright_cyan( )
3148 ) ;
3249 std:: fs:: create_dir_all ( & mod_project_dir_path) ?;
3350
34- create_mod_project_file ( & mod_project_dir_path, & args ) ?;
51+ create_mod_project_file ( & mod_project_dir_path, & name , & display_name ) ?;
3552
3653 Ok ( ( ) )
3754}
3855
3956fn create_mod_project_file (
4057 mod_project_dir_path : impl AsRef < Path > ,
41- args : & InitModProjectArgs ,
58+ name : & str ,
59+ display_name : & str ,
4260) -> eyre:: Result < ( ) > {
4361 let mod_project =
44- create_default_mod_project ( Some ( args . name . clone ( ) ) , args . display_name . clone ( ) ) ;
62+ create_default_mod_project ( Some ( name. to_string ( ) ) , Some ( display_name. to_string ( ) ) ) ;
4563
4664 let mod_project_file_content = serde_json:: to_string ( & mod_project) ?;
4765 std:: fs:: write (
@@ -67,3 +85,31 @@ fn create_default_mod_project(name: Option<String>, display_name: Option<String>
6785fn create_mod_project_dir_path ( name : impl AsRef < Path > ) -> io:: Result < PathBuf > {
6886 Ok ( std:: path:: Path :: new ( & std:: env:: current_dir ( ) ?) . join ( name) )
6987}
88+
89+ pub fn prompt_mod_name ( suggested_name : impl AsRef < str > ) -> eyre:: Result < String > {
90+ let validator = |input : & str | {
91+ if is_valid_mod_name ( input) {
92+ Ok ( Validation :: Valid )
93+ } else {
94+ Ok ( Validation :: Invalid (
95+ "Mod name must be alphanumeric and can only contain hyphens (no spaces or special characters)" . into ( )
96+ ) )
97+ }
98+ } ;
99+
100+ let slugified = slug:: slugify ( suggested_name. as_ref ( ) ) ;
101+
102+ let name = Text :: new ( "Enter mod folder name (no spaces or special characters):" )
103+ . with_validator ( validator)
104+ . with_default ( & slugified)
105+ . with_placeholder ( & slugified)
106+ . prompt ( ) ?;
107+
108+ Ok ( name)
109+ }
110+
111+ fn prompt_mod_display_name ( ) -> eyre:: Result < String > {
112+ let name = Text :: new ( "Enter mod display name:" ) . prompt ( ) ?;
113+
114+ Ok ( name)
115+ }
0 commit comments