### PROBLEM + `main.go` (api client) does a lot of things: + read the log input + parse line by line + updates the results + display the results + inflexible: + filter by extension (can change) + group by domain (can change) — group by page? ## SOLUTION + hide the parsing api from the client + move `main.go/scanner` -> `parser.go/parse()` + add `main.go`: err handling from `parse()` + `parser.go/parse()` -> return err directly + remove: `if p.lerr != nil { return }` from parse() and update() + remove: `dumpErrs` + remove: `parser.go/err()` + remove `parser.go/lerr` + return `in.Err()` from `parse()` + remove: `p.lines++` + `return r, fmt.Errorf("line %d: %v", p.lines, err)` + remove: `lines int` + `parse()` and `parse()` becomes: ```golang func parse(p *parser, line string) (result, error) { return parseFields(line) } func parse(p *parser) { // ... r, err := parse(p, in.Text()) if err != nil { return fmt.Errorf("line %d: %v", p.lines, err) } // ... } ``` + remove `parse()` + call `parseFields` directly in `parse()`: ```go var ( l = 1 in = bufio.NewScanner(os.Stdin) ) for in.Scan() { r, err := parseFields(in.Text()) if err != nil { return fmt.Errorf("line %d: %v", l, err) } update(p, r) l++ } ```