mirror of
https://mau.dev/mautrix/go.git
synced 2026-03-14 22:35:52 +01:00
122 lines
2.7 KiB
Go
122 lines
2.7 KiB
Go
// Copyright (c) 2026 Tulir Asokan
|
|
//
|
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
package cmdschema
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
var quoteEscaper = strings.NewReplacer(
|
|
`"`, `\"`,
|
|
`\`, `\\`,
|
|
)
|
|
|
|
const charsToQuote = ` \` + botArrayOpener + botArrayCloser
|
|
|
|
func quoteString(val string) string {
|
|
if val == "" {
|
|
return `""`
|
|
}
|
|
val = quoteEscaper.Replace(val)
|
|
if strings.ContainsAny(val, charsToQuote) {
|
|
return `"` + val + `"`
|
|
}
|
|
return val
|
|
}
|
|
|
|
func (ec *EventContent) StringifyArgs(args any) string {
|
|
var argMap map[string]any
|
|
switch typedArgs := args.(type) {
|
|
case json.RawMessage:
|
|
err := json.Unmarshal(typedArgs, &argMap)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
case map[string]any:
|
|
argMap = typedArgs
|
|
default:
|
|
if b, err := json.Marshal(args); err != nil {
|
|
return ""
|
|
} else if err = json.Unmarshal(b, &argMap); err != nil {
|
|
return ""
|
|
}
|
|
}
|
|
parts := make([]string, 0, len(ec.Parameters))
|
|
for i, param := range ec.Parameters {
|
|
isLast := i == len(ec.Parameters)-1
|
|
val := argMap[param.Key]
|
|
if val == nil {
|
|
val = param.DefaultValue
|
|
if val == nil && !param.Optional {
|
|
val = param.Schema.GetDefaultValue()
|
|
}
|
|
}
|
|
if val == nil {
|
|
continue
|
|
}
|
|
var stringified string
|
|
if param.Schema.SchemaType == SchemaTypeArray {
|
|
stringified = arrayArgumentToString(val, isLast)
|
|
} else {
|
|
stringified = singleArgumentToString(val)
|
|
}
|
|
if stringified != "" {
|
|
parts = append(parts, stringified)
|
|
}
|
|
}
|
|
return strings.Join(parts, " ")
|
|
}
|
|
|
|
func arrayArgumentToString(val any, isLast bool) string {
|
|
valArr, ok := val.([]any)
|
|
if !ok {
|
|
return ""
|
|
}
|
|
parts := make([]string, 0, len(valArr))
|
|
for _, elem := range valArr {
|
|
stringified := singleArgumentToString(elem)
|
|
if stringified != "" {
|
|
parts = append(parts, stringified)
|
|
}
|
|
}
|
|
joinedParts := strings.Join(parts, " ")
|
|
if isLast && len(parts) > 0 {
|
|
return joinedParts
|
|
}
|
|
return botArrayOpener + joinedParts + botArrayCloser
|
|
}
|
|
|
|
func singleArgumentToString(val any) string {
|
|
switch typedVal := val.(type) {
|
|
case string:
|
|
return quoteString(typedVal)
|
|
case json.Number:
|
|
return typedVal.String()
|
|
case bool:
|
|
return strconv.FormatBool(typedVal)
|
|
case int:
|
|
return strconv.Itoa(typedVal)
|
|
case int64:
|
|
return strconv.FormatInt(typedVal, 10)
|
|
case float64:
|
|
return strconv.FormatInt(int64(typedVal), 10)
|
|
case map[string]any, json.RawMessage, RoomIDValue, *RoomIDValue:
|
|
normalized, err := NormalizeRoomIDValue(typedVal)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
uri := normalized.URI()
|
|
if uri == nil {
|
|
return ""
|
|
}
|
|
return quoteString(uri.String())
|
|
default:
|
|
return ""
|
|
}
|
|
}
|