74 lines
1.4 KiB
Go
74 lines
1.4 KiB
Go
package command
|
|
|
|
import (
|
|
"io"
|
|
"strconv"
|
|
"strings"
|
|
|
|
pk "git.konjactw.dev/falloutBot/go-mc/net/packet"
|
|
)
|
|
|
|
type Parser interface {
|
|
Parse(cmd string) (left string, value ParsedData, err error)
|
|
}
|
|
|
|
type StringParser int32
|
|
|
|
func (s StringParser) WriteTo(w io.Writer) (int64, error) {
|
|
return pk.Tuple{
|
|
pk.Identifier("brigadier:string"),
|
|
pk.VarInt(s),
|
|
}.WriteTo(w)
|
|
}
|
|
|
|
func (s StringParser) Parse(cmd string) (left string, value ParsedData, err error) {
|
|
switch s {
|
|
case 2: // Greedy Phrase
|
|
return "", cmd, nil
|
|
case 1: // Quotable Phrase
|
|
if len(cmd) > 0 && cmd[0] == '"' {
|
|
var sb strings.Builder
|
|
var isEscaping bool
|
|
for i, v := range cmd[1:] {
|
|
if isEscaping {
|
|
isEscaping = false
|
|
switch v {
|
|
case '\\':
|
|
sb.WriteRune('\\')
|
|
case '"':
|
|
sb.WriteRune('"')
|
|
}
|
|
} else if v == '\\' {
|
|
isEscaping = true
|
|
} else if v == '"' {
|
|
return cmd[:i], sb.String(), nil
|
|
} else {
|
|
sb.WriteRune(v)
|
|
}
|
|
}
|
|
return cmd, nil, ParseErr{
|
|
Pos: len(cmd) - 1,
|
|
Err: "expected '\"'",
|
|
}
|
|
}
|
|
fallthrough
|
|
case 0: // Single Word
|
|
i := strings.IndexAny(cmd, "\t\n\v\f\r ")
|
|
if i == -1 {
|
|
return "", cmd, nil
|
|
}
|
|
return cmd[i:], cmd[:i], nil
|
|
default:
|
|
panic("StringParser: unknown format 0x" + strconv.FormatInt(int64(s), 16))
|
|
}
|
|
}
|
|
|
|
type ParseErr struct {
|
|
Pos int
|
|
Err string
|
|
}
|
|
|
|
func (p ParseErr) Error() string {
|
|
return p.Err
|
|
}
|