49 lines
1.0 KiB
Go
49 lines
1.0 KiB
Go
package usecase
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
"unicode/utf8"
|
|
)
|
|
|
|
// boundedDiagnosticJSON returns a JSON string prefix and whether it represents
|
|
// the complete normalized input. It retains at most the useful prefix.
|
|
func boundedDiagnosticJSON(value string, maxBytes int) ([]byte, bool) {
|
|
if maxBytes < 2 {
|
|
return nil, false
|
|
}
|
|
limit := maxBytes - 2
|
|
var prefix strings.Builder
|
|
used := 0
|
|
more := false
|
|
for i := 0; i < len(value); {
|
|
r, size := utf8.DecodeRuneInString(value[i:])
|
|
piece := value[i : i+size]
|
|
if r == utf8.RuneError && size == 1 {
|
|
piece = "\uFFFD"
|
|
i++
|
|
for i < len(value) {
|
|
r, size = utf8.DecodeRuneInString(value[i:])
|
|
if r != utf8.RuneError || size != 1 {
|
|
break
|
|
}
|
|
i++
|
|
}
|
|
} else {
|
|
i += size
|
|
}
|
|
if used+len(piece) > limit {
|
|
more = true
|
|
break
|
|
}
|
|
prefix.WriteString(piece)
|
|
used += len(piece)
|
|
}
|
|
normalized := prefix.String()
|
|
encoded, _ := json.Marshal(normalized)
|
|
if len(encoded) > maxBytes {
|
|
return truncateDiagnosticJSONValue(normalized, maxBytes), false
|
|
}
|
|
return encoded, !more
|
|
}
|