diff --git a/source/chapter-3-word-counter.rst b/source/chapter-3-word-counter.rst index 02b0d20..60f7cb8 100644 --- a/source/chapter-3-word-counter.rst +++ b/source/chapter-3-word-counter.rst @@ -70,3 +70,12 @@ is present on the system with |os_file_exists|_. There is one catch with the |os_read_file|_ function, it returns an ``Option`` :doc:`type `. This kind of type has to be handled in your code with an ``or`` block that allows only specific set of :doc:`keywords `. + +Once we handle the failing function and remove unnecessary printing to the +console the program is ready and complete. + +Here is a challenge for you as a reader: Currently it handles only a single +file. Try to make it handle multiple files! + +.. include:: vsource/word-counter-complete.v + :code: v diff --git a/source/vsource/word-counter-complete.v b/source/vsource/word-counter-complete.v new file mode 100644 index 0000000..b0b411c --- /dev/null +++ b/source/vsource/word-counter-complete.v @@ -0,0 +1,53 @@ +import os + +struct Mode { + name string + cli_args []string + sep []string +} + + +const ( + words = Mode{name: "words", cli_args: ["-w", "--words"], sep: [" ", "\n"]} + lines = Mode{cli_args: ["-l", "--lines"], name: "lines", sep: ["\n"]} + chars = Mode{name: "chars", cli_args: ["-c", "--chars"], sep: [""]} +) + + +fn parse_mode(args []string) Mode { + mut mode := Mode{} + + if args[1] in words.cli_args { + mode = words + } else if args[1] in lines.cli_args { + mode = lines + } else if args[1] in chars.cli_args { + mode = chars + } + return mode +} + + +fn count(mode Mode, path string) int { + mut result := 0 + + if !os.file_exists(path) { + result = -1 + return result + } + + content := os.read_file(path) or {return result} + for item in content { + if "" in mode.sep || item.str() in mode.sep { + result++ + } + } + return result +} + + +fn main() { + mode := parse_mode(os.args) + file := os.args[2] + println(count(mode, file)) +}