mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-21 16:38:23 +01:00
Fix number parsing for MetaSettingsType (#806)
json.Unmarshal parses all numbers to float64, which breaks any integer settings values. This PR changes MetaSettingsType.UnmarshalJSON to use json.Decoder, which is capable of parsing into a meta-type json.Number, which can be interpreted as a float or an integer. It also properly handles pointer types.
This commit is contained in:
parent
96ad70ffdd
commit
4907552379
@ -46,6 +46,10 @@ func parseMetaSets(metaSets []string) (map[string]interface{}, error) {
|
|||||||
return nil, fmt.Errorf("invalid json value: %v", err)
|
return nil, fmt.Errorf("invalid json value: %v", err)
|
||||||
}
|
}
|
||||||
meta[fields[0]] = val
|
meta[fields[0]] = val
|
||||||
|
} else {
|
||||||
|
ival, err := strconv.ParseInt(setVal, 0, 64)
|
||||||
|
if err == nil {
|
||||||
|
meta[fields[0]] = ival
|
||||||
} else {
|
} else {
|
||||||
fval, err := strconv.ParseFloat(setVal, 64)
|
fval, err := strconv.ParseFloat(setVal, 64)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -55,6 +59,7 @@ func parseMetaSets(metaSets []string) (map[string]interface{}, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return meta, nil
|
return meta, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,9 @@ type MetaSettingsType struct {
|
|||||||
|
|
||||||
func (m *MetaSettingsType) UnmarshalJSON(data []byte) error {
|
func (m *MetaSettingsType) UnmarshalJSON(data []byte) error {
|
||||||
var metaMap waveobj.MetaMapType
|
var metaMap waveobj.MetaMapType
|
||||||
if err := json.Unmarshal(data, &metaMap); err != nil {
|
decoder := json.NewDecoder(bytes.NewReader(data))
|
||||||
|
decoder.UseNumber()
|
||||||
|
if err := decoder.Decode(&metaMap); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
*m = MetaSettingsType{MetaMapType: metaMap}
|
*m = MetaSettingsType{MetaMapType: metaMap}
|
||||||
@ -77,7 +79,7 @@ type SettingsType struct {
|
|||||||
WindowOpacity *float64 `json:"window:opacity,omitempty"`
|
WindowOpacity *float64 `json:"window:opacity,omitempty"`
|
||||||
WindowBgColor string `json:"window:bgcolor,omitempty"`
|
WindowBgColor string `json:"window:bgcolor,omitempty"`
|
||||||
WindowReducedMotion bool `json:"window:reducedmotion,omitempty"`
|
WindowReducedMotion bool `json:"window:reducedmotion,omitempty"`
|
||||||
WindowTileGapSize *int8 `json:"window:tilegapsize,omitempty"`
|
WindowTileGapSize *int64 `json:"window:tilegapsize,omitempty"`
|
||||||
|
|
||||||
TelemetryClear bool `json:"telemetry:*,omitempty"`
|
TelemetryClear bool `json:"telemetry:*,omitempty"`
|
||||||
TelemetryEnabled bool `json:"telemetry:enabled,omitempty"`
|
TelemetryEnabled bool `json:"telemetry:enabled,omitempty"`
|
||||||
@ -98,8 +100,6 @@ type FullConfigType struct {
|
|||||||
ConfigErrors []ConfigError `json:"configerrors" configfile:"-"`
|
ConfigErrors []ConfigError `json:"configerrors" configfile:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var settingsAbsPath = filepath.Join(configDirAbsPath, SettingsFile)
|
|
||||||
|
|
||||||
func readConfigHelper(fileName string, barr []byte, readErr error) (waveobj.MetaMapType, []ConfigError) {
|
func readConfigHelper(fileName string, barr []byte, readErr error) (waveobj.MetaMapType, []ConfigError) {
|
||||||
var cerrs []ConfigError
|
var cerrs []ConfigError
|
||||||
if readErr != nil && !os.IsNotExist(readErr) {
|
if readErr != nil && !os.IsNotExist(readErr) {
|
||||||
@ -242,7 +242,7 @@ func reindentJson(barr []byte, indentStr string) []byte {
|
|||||||
if barr[0] != '{' && barr[0] != '[' {
|
if barr[0] != '{' && barr[0] != '[' {
|
||||||
return barr
|
return barr
|
||||||
}
|
}
|
||||||
if bytes.Index(barr, []byte("\n")) == -1 {
|
if bytes.Contains(barr, []byte("\n")) {
|
||||||
return barr
|
return barr
|
||||||
}
|
}
|
||||||
outputLines := bytes.Split(barr, []byte("\n"))
|
outputLines := bytes.Split(barr, []byte("\n"))
|
||||||
@ -286,6 +286,32 @@ func jsonMarshalConfigInOrder(m waveobj.MetaMapType) ([]byte, error) {
|
|||||||
return buf.Bytes(), nil
|
return buf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var dummyNumber json.Number
|
||||||
|
|
||||||
|
func convertJsonNumber(num json.Number, ctype reflect.Type) (interface{}, error) {
|
||||||
|
// ctype might be int64, float64, string, *int64, *float64, *string
|
||||||
|
// switch on ctype first
|
||||||
|
if ctype.Kind() == reflect.Pointer {
|
||||||
|
ctype = ctype.Elem()
|
||||||
|
}
|
||||||
|
if reflect.Int64 == ctype.Kind() {
|
||||||
|
if ival, err := num.Int64(); err == nil {
|
||||||
|
return ival, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("invalid number for int64: %s", num)
|
||||||
|
}
|
||||||
|
if reflect.Float64 == ctype.Kind() {
|
||||||
|
if fval, err := num.Float64(); err == nil {
|
||||||
|
return fval, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("invalid number for float64: %s", num)
|
||||||
|
}
|
||||||
|
if reflect.String == ctype.Kind() {
|
||||||
|
return num.String(), nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("cannot convert number to %s", ctype)
|
||||||
|
}
|
||||||
|
|
||||||
func SetBaseConfigValue(toMerge waveobj.MetaMapType) error {
|
func SetBaseConfigValue(toMerge waveobj.MetaMapType) error {
|
||||||
m, cerrs := ReadWaveHomeConfigFile(SettingsFile)
|
m, cerrs := ReadWaveHomeConfigFile(SettingsFile)
|
||||||
if len(cerrs) > 0 {
|
if len(cerrs) > 0 {
|
||||||
@ -302,9 +328,22 @@ func SetBaseConfigValue(toMerge waveobj.MetaMapType) error {
|
|||||||
if val == nil {
|
if val == nil {
|
||||||
delete(m, configKey)
|
delete(m, configKey)
|
||||||
} else {
|
} else {
|
||||||
if reflect.TypeOf(val) != ctype {
|
rtype := reflect.TypeOf(val)
|
||||||
|
if rtype == reflect.TypeOf(dummyNumber) {
|
||||||
|
convertedVal, err := convertJsonNumber(val.(json.Number), ctype)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot convert %s: %v", configKey, err)
|
||||||
|
}
|
||||||
|
val = convertedVal
|
||||||
|
rtype = reflect.TypeOf(val)
|
||||||
|
}
|
||||||
|
if rtype != ctype {
|
||||||
|
if ctype == reflect.PointerTo(rtype) {
|
||||||
|
m[configKey] = &val
|
||||||
|
} else {
|
||||||
return fmt.Errorf("invalid value type for %s: %T", configKey, val)
|
return fmt.Errorf("invalid value type for %s: %T", configKey, val)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
m[configKey] = val
|
m[configKey] = val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user