// parse.go — Shared key=value payload parsing. package protocol import "strings" // ParsePayload parses newline-separated key=value pairs into a map. // Values are unescaped: \n → newline, \\ → backslash. func ParsePayload(payload string) map[string]string { args := make(map[string]string) for _, line := range strings.Split(payload, "\n") { line = strings.TrimSpace(line) if line == "" { continue } idx := strings.Index(line, "=") if idx < 0 { continue } key := line[:idx] value := line[idx+1:] value = UnescapeValue(value) args[key] = value } return args } // UnescapeValue reverses wire-format escape sequences: \n → newline, \\ → backslash. func UnescapeValue(s string) string { if !strings.ContainsRune(s, '\\') { return s } result := make([]byte, 0, len(s)) for i := 0; i < len(s); i++ { if s[i] == '\\' && i+1 < len(s) { switch s[i+1] { case 'n': result = append(result, '\n') i++ continue case '\\': result = append(result, '\\') i++ continue } } result = append(result, s[i]) } return string(result) }