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") } }