Files
xiaomihome/xiaomi/specs/mapper.go
T
4566704 cdc459b5ff fix(xiaomihome): 模块路径改为 git.zeroonesoft.cn/golib/xiaomihome
- 改动:go.mod module 声明与全部内部导入路径补全为完整域名路径,README 同步
- 原因:裸模块名无法被 go get 解析,发版前必须修正为 GOPRIVATE 可拉取路径
2026-10-05 08:53:23 +08:00

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
}