diff options
Diffstat (limited to 'parser.go')
| -rw-r--r-- | parser.go | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/parser.go b/parser.go new file mode 100644 index 0000000..054e906 --- /dev/null +++ b/parser.go @@ -0,0 +1,63 @@ +package main + +import ( + "bufio" + "fmt" + "io" + "strconv" + "strings" +) + +func parseRESP(reader *bufio.Reader) ([]string, error) { + line, err := reader.ReadString('\n') + if err != nil { + return nil, err + } + + if len(line) == 0 { + return nil, fmt.Errorf("empty line") + } + + switch line[0] { + case '*': + var args []string + argC, _ := strconv.Atoi(strings.TrimSpace(line[1:])) + + for i := 0; i < argC; i++ { + nestedArgs, err := parseRESP(reader) + if err != nil { + return nil, err + } + + args = append(args, nestedArgs...) + } + return args, nil + case '$': + strLen, _ := strconv.Atoi(strings.TrimSpace(line[1:])) + + if strLen == -1 { + return []string{""}, nil + } + + buf := make([]byte, strLen) + + _, err = io.ReadFull(reader, buf) + if err != nil { + return nil, err + } + + _, err = reader.Discard(2) + if err != nil { + return nil, err + } + + return []string{string(buf)}, nil + case '+': + cleanStr := strings.TrimSpace(line[1:]) + return []string{cleanStr}, nil + case ':': + return []string{strings.TrimSpace(line[1:])}, nil + default: + return nil, fmt.Errorf("unknown command type: %c", line[0]) + } +}
\ No newline at end of file |
