lockserver/zwavejs/json_helpers.go
2024-11-22 19:50:54 -08:00

148 lines
3.1 KiB
Go

package zwavejs
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"github.com/sirupsen/logrus"
)
type AnyTypeType int
const (
AnyTypeString AnyTypeType = iota
AnyTypeInt
AnyTypeBool
AnyTypeList
)
type AnyType struct {
Type AnyTypeType
String string
Int int
Bool bool
List []AnyType
}
func (n *AnyType) UnmarshalJSON(data []byte) error {
if bytes.HasPrefix(data, []byte("\"")) {
n.Type = AnyTypeString
return json.Unmarshal(data, &n.String)
}
if bytes.Equal(data, []byte("true")) || bytes.Equal(data, []byte("false")) {
n.Type = AnyTypeBool
return json.Unmarshal(data, &n.Bool)
}
if bytes.HasPrefix(data, []byte("[")) {
n.Type = AnyTypeList
return json.Unmarshal(data, &n.List)
}
n.Type = AnyTypeInt
if err := json.Unmarshal(data, &n.Int); err != nil {
logrus.WithField("value", string(data)).Debug("error while parsing node property value of ambiguous type")
return err
}
return nil
}
func (n AnyType) MarshalJSON() ([]byte, error) {
switch n.Type {
case AnyTypeString:
return json.Marshal(n.String)
case AnyTypeBool:
return json.Marshal(n.Bool)
case AnyTypeList:
return json.Marshal(n.List)
case AnyTypeInt:
return json.Marshal(n.Int)
default:
return nil, errors.New("anytype of unknown type")
}
}
type NodeValueTypeType int
const (
NodeValueTypeString NodeValueTypeType = iota
NodeValueTypeInt
NodeValueTypeBool
NodeValueTypeList
NodeValueTypeIntWithUnit
)
type NodeValueType struct {
Type NodeValueTypeType
String string
Int int
Bool bool
List []NodeValueType
}
func (n *NodeValueType) UnmarshalJSON(data []byte) error {
if bytes.HasPrefix(data, []byte("\"")) {
n.Type = NodeValueTypeString
return json.Unmarshal(data, &n.String)
}
if bytes.Equal(data, []byte("true")) || bytes.Equal(data, []byte("false")) {
n.Type = NodeValueTypeBool
return json.Unmarshal(data, &n.Bool)
}
if bytes.HasPrefix(data, []byte("[")) {
n.Type = NodeValueTypeList
return json.Unmarshal(data, &n.List)
}
if bytes.HasPrefix(data, []byte("{")) {
var value map[string]interface{}
if err := json.Unmarshal(data, &value); err != nil {
return fmt.Errorf("error unmarshalling NodeValueType object %s: %v", string(data), err)
}
if intval, ok := value["value"].(int); ok {
n.Int = intval
}
if unit, ok := value["unit"].(string); ok {
n.String = unit
}
n.Type = NodeValueTypeIntWithUnit
return nil
}
n.Type = NodeValueTypeInt
if err := json.Unmarshal(data, &n.Int); err != nil {
logrus.WithField("value", string(data)).Debug("error while parsing node property value of ambiguous type")
return err
}
return nil
}
func (n NodeValueType) MarshalJSON() ([]byte, error) {
switch n.Type {
case NodeValueTypeString:
return json.Marshal(n.String)
case NodeValueTypeBool:
return json.Marshal(n.Bool)
case NodeValueTypeList:
return json.Marshal(n.List)
case NodeValueTypeInt:
return json.Marshal(n.Int)
case NodeValueTypeIntWithUnit:
return json.Marshal(map[string]interface{}{
"value": n.Int,
"unit": n.String,
})
default:
return nil, errors.New("NodeValueType of unknown type")
}
}