- 改动:go.mod module 声明与全部内部导入路径补全为完整域名路径,README 同步 - 原因:裸模块名无法被 go get 解析,发版前必须修正为 GOPRIVATE 可拉取路径
121 lines
3.0 KiB
Go
121 lines
3.0 KiB
Go
package specs
|
|
|
|
import "git.zeroonesoft.cn/golib/xiaomihome/miot"
|
|
|
|
// PropertyMapper provides bidirectional mapping between SPEC raw values (integers)
|
|
// and human-readable enum strings. For example, an air conditioner mode property
|
|
// might use raw value 0 for "cool", 1 for "heat", etc.
|
|
//
|
|
// The mapper is constructed from the SPEC value-list combined with an external
|
|
// lookup table that maps raw values to their semantic names.
|
|
type PropertyMapper struct {
|
|
rawToEnum map[interface{}]string
|
|
enumToRaw map[string]interface{}
|
|
}
|
|
|
|
// NewPropertyMapper creates a PropertyMapper from a SPEC value-list and
|
|
// a mapping of raw values → enum strings.
|
|
//
|
|
// Example:
|
|
//
|
|
// mapper := NewPropertyMapper(prop.ValueList, map[interface{}]string{
|
|
// 0: "cool",
|
|
// 1: "heat",
|
|
// 2: "fan",
|
|
// 3: "dry",
|
|
// 4: "auto",
|
|
// })
|
|
func NewPropertyMapper(vlist miot.MIoTSpecValueList, valueMap map[interface{}]string) *PropertyMapper {
|
|
m := &PropertyMapper{
|
|
rawToEnum: make(map[interface{}]string),
|
|
enumToRaw: make(map[string]interface{}),
|
|
}
|
|
|
|
// Build from the provided valueMap
|
|
for raw, enum := range valueMap {
|
|
m.rawToEnum[raw] = enum
|
|
m.enumToRaw[enum] = raw
|
|
}
|
|
|
|
// Also build from SPEC value-list descriptions (as a fallback)
|
|
for _, item := range vlist {
|
|
if item.Desc != "" {
|
|
name := item.Desc
|
|
if item.Name != "" {
|
|
name = item.Name
|
|
}
|
|
m.rawToEnum[item.Value] = name
|
|
m.enumToRaw[name] = item.Value
|
|
}
|
|
}
|
|
|
|
return m
|
|
}
|
|
|
|
// ToEnum converts a raw SPEC value to its enum string representation.
|
|
// Returns ("", false) if the raw value is not in the mapping.
|
|
func (m *PropertyMapper) ToEnum(raw interface{}) (string, bool) {
|
|
if m == nil {
|
|
return "", false
|
|
}
|
|
s, ok := m.rawToEnum[raw]
|
|
return s, ok
|
|
}
|
|
|
|
// ToRaw converts an enum string to its raw SPEC value.
|
|
// Returns (nil, false) if the enum string is not in the mapping.
|
|
func (m *PropertyMapper) ToRaw(enum string) (interface{}, bool) {
|
|
if m == nil {
|
|
return nil, false
|
|
}
|
|
v, ok := m.enumToRaw[enum]
|
|
return v, ok
|
|
}
|
|
|
|
// HasEnum checks whether the given enum string exists in the mapping.
|
|
func (m *PropertyMapper) HasEnum(enum string) bool {
|
|
if m == nil {
|
|
return false
|
|
}
|
|
_, ok := m.enumToRaw[enum]
|
|
return ok
|
|
}
|
|
|
|
// HasRaw checks whether the given raw value exists in the mapping.
|
|
func (m *PropertyMapper) HasRaw(raw interface{}) bool {
|
|
if m == nil {
|
|
return false
|
|
}
|
|
_, ok := m.rawToEnum[raw]
|
|
return ok
|
|
}
|
|
|
|
// FromValueList creates a PropertyMapper purely from the SPEC value list.
|
|
// Uses the ValueItem.Desc or ValueItem.Name as the enum string.
|
|
func FromValueList(vlist miot.MIoTSpecValueList) *PropertyMapper {
|
|
if len(vlist) == 0 {
|
|
return &PropertyMapper{
|
|
rawToEnum: make(map[interface{}]string),
|
|
enumToRaw: make(map[string]interface{}),
|
|
}
|
|
}
|
|
|
|
m := &PropertyMapper{
|
|
rawToEnum: make(map[interface{}]string),
|
|
enumToRaw: make(map[string]interface{}),
|
|
}
|
|
|
|
for _, item := range vlist {
|
|
name := item.Name
|
|
if name == "" {
|
|
name = item.Desc
|
|
}
|
|
if name != "" {
|
|
m.rawToEnum[item.Value] = name
|
|
m.enumToRaw[name] = item.Value
|
|
}
|
|
}
|
|
|
|
return m
|
|
}
|