diff --git a/CLI/cli.go b/CLI/cli.go new file mode 100644 index 0000000..9771b32 --- /dev/null +++ b/CLI/cli.go @@ -0,0 +1,103 @@ +package CLI + +import ( + "fmt" + "regexp" + "strconv" + "strings" +) + +type Option struct { + ID string + Help string + ArgsRegex string + Required bool + IsInt bool + Disabled bool +} + +type OptionGot struct { + ID string + Value any +} + +type CLI struct { + Options []*Option +} + +func (o *Option) GetRegex() *regexp.Regexp { + if o.ArgsRegex != "" { + return regexp.MustCompile(fmt.Sprintf("-%s %s", o.ID, o.ArgsRegex)) + } + return regexp.MustCompile(fmt.Sprintf("-%s", o.ID)) +} + +func (o *Option) parse(cli string) (*OptionGot, error) { + regex := o.GetRegex() + un := regex.FindString(cli) + if un == "" && o.Required { + return nil, fmt.Errorf("option %s is required", o.ID) + } + if un == "" { + return nil, nil + } + str := strings.Replace(un, fmt.Sprintf("-%s ", o.ID), "", 1) + if !o.IsInt { + return &OptionGot{ID: o.ID, Value: str}, nil + } + f, err := strconv.Atoi(str) + if err != nil { + return nil, err + } + return &OptionGot{ID: o.ID, Value: f}, nil +} + +func (c *CLI) AddOption(o *Option) *CLI { + c.Options = append(c.Options, o) + return c +} + +func (c *CLI) Parse(cli string) ([]*OptionGot, error) { + var got []*OptionGot + for _, o := range c.Options { + if o.Disabled { + continue + } + g, err := o.parse(cli) + if err != nil { + return nil, err + } + if g != nil { + got = append(got, g) + } + } + return got, nil +} + +func (c *CLI) Help() { + println("------------------------------") + println("HELP OF THE MAZE GENERATOR CLI") + println("------------------------------") + println("Required arguments:") + for _, o := range c.Options { + if !o.Required || o.Disabled { + continue + } + if o.IsInt { + println(fmt.Sprintf(" -%s uint -> %s", o.ID, o.Help)) + continue + } + println(fmt.Sprintf(" -%s string -> %s", o.ID, o.Help)) + } + println("Optional arguments:") + for _, o := range c.Options { + if o.Required || o.Disabled { + continue + } + if o.IsInt { + println(fmt.Sprintf(" -%s uint -> %s", o.ID, o.Help)) + continue + } + println(fmt.Sprintf(" -%s string -> %s", o.ID, o.Help)) + } +} diff --git a/main.go b/main.go index 030ac01..371fa15 100644 --- a/main.go +++ b/main.go @@ -2,18 +2,12 @@ package main import ( "fmt" + "github.com/msmp-core/maze-generator-cli/CLI" "github.com/msmp-core/maze-generator-cli/Generators" "os" - "regexp" - "strconv" - "strings" ) func main() { - if len(os.Args) == 1 { - help() - return - } cli := "" for i, a := range os.Args { if i == 0 { @@ -21,79 +15,64 @@ func main() { } cli += a + " " } - //widthO := regexp.MustCompile(`-w [0-9]+`) - //height0 := regexp.MustCompile(`-h [0-9]+`) - size0 := regexp.MustCompile(`-s [0-9]+`) - output0 := regexp.MustCompile(`-o [0-9a-zA-Z/.\-_]+`) - difficulty0 := regexp.MustCompile(`-d [0-9]+`) - help0 := regexp.MustCompile(`-help`) - //unWidth := widthO.FindString(cli) - //unHeight := height0.FindString(cli) - unSize := size0.FindString(cli) - unOutput := output0.FindString(cli) - unDifficulty := difficulty0.FindString(cli) - t := help0.FindString(cli) - if t != "" { - help() - return + options := []*CLI.Option{ + { + ID: "s", Help: "Size of one side of the maze", ArgsRegex: `[0-9]+`, Required: true, IsInt: true, Disabled: false, + }, + { + ID: "w", Help: "Width of the maze", ArgsRegex: `[0-9]+`, Required: true, IsInt: true, Disabled: true, + }, + { + ID: "h", Help: "Height of the maze", ArgsRegex: `[0-9]+`, Required: true, IsInt: true, Disabled: true, + }, + { + ID: "o", Help: "Output file", ArgsRegex: `[0-9a-zA-Z/.\-_]+`, Required: false, IsInt: false, Disabled: false, + }, + { + ID: "d", Help: "Difficulty of the maze", ArgsRegex: `[0-9]+`, Required: false, IsInt: true, Disabled: false, + }, + { + ID: "help", Help: "Show this help", ArgsRegex: ``, Required: false, IsInt: false, Disabled: false, + }, } - //if unHeight == "" || unWidth == "" { - // help() - // return - //} - if unSize == "" { - help() + app := CLI.CLI{Options: options} + if len(os.Args) == 1 { + app.Help() return } - //strWidth := strings.ReplaceAll(unWidth, "-w ", "") - //strHeight := strings.ReplaceAll(unHeight, "-h ", "") - strSize := strings.ReplaceAll(unSize, "-s ", "") - - //w, err := strconv.Atoi(strWidth) - //if err != nil { - // panic(err) - //} - //h, err := strconv.Atoi(strHeight) - //if err != nil { - // panic(err) - //} - s, err := strconv.Atoi(strSize) + got, err := app.Parse(cli) if err != nil { - panic(err) + println(err.Error()) + app.Help() + return } + var s int + var out string d := 0 - if unDifficulty != "" { - strDifficulty := strings.ReplaceAll(unDifficulty, "-d ", "") - d, err = strconv.Atoi(strDifficulty) - if err != nil { - panic(err) + for _, g := range got { + switch g.ID { + case "s": + s = g.Value.(int) + case "d": + d = g.Value.(int) + case "o": + out = g.Value.(string) + case "help": + app.Help() + return } } + m, err := Generators.GenerateNewMaze(uint(s), uint(s), uint(d), Generators.NewRandomisedKruskal) if err != nil { panic(err) } m.RenderWalls() - if unOutput != "" { - output := strings.ReplaceAll(unOutput, "-o ", "") - err = m.Output(output) + if out != "" { + err = m.Output(out) if err != nil { panic(err) } - fmt.Printf("Successfully outputted at %s\n", output) + fmt.Printf("Successfully outputted at %s\n", out) } } - -func help() { - println("------------------------------") - println("HELP OF THE MAZE GENERATOR CLI") - println("------------------------------") - println("Required arguments:") - //println(" -w uint -> Width of the maze") - //println(" -h uint -> Height of the maze\n") - println(" -s uint -> Size of one side of the maze\n") - println("Optional arguments:") - println(" -d uint -> Difficulty of the maze") - println(" -o string -> Output file of the new maze") - -}