package api import ( "encoding/json" "fmt" ) type Capability interface { ID() string } type CapabilityJSON struct { Capability } type BasicCapability struct { Id string `json:"id"` } func (c BasicCapability) ID() string { return c.Id } const CapabilityBasic string = "basic" type DBusCapability struct { Id string `json:"id"` Own []string `json:"own,omitempty"` } func (c DBusCapability) ID() string { return c.Id } const CapabilityDBus = "dbus" type capabilityType struct { Type string `json:"type"` } func (c *CapabilityJSON) MarshalJSON() ([]byte, error) { if c == nil || c.Capability == nil { return nil, fmt.Errorf("invalid capability") } var v any switch cv := c.Capability.(type) { case *BasicCapability: v = &struct { capabilityType *BasicCapability }{capabilityType{CapabilityBasic}, cv} case *DBusCapability: v = &struct { capabilityType *DBusCapability }{capabilityType{CapabilityDBus}, cv} default: return nil, fmt.Errorf("invalid capability") } return json.Marshal(v) } func (c *CapabilityJSON) UnmarshalJSON(data []byte) error { t := new(capabilityType) if err := json.Unmarshal(data, &t); err != nil { return err } switch t.Type { case CapabilityBasic: *c = CapabilityJSON{new(BasicCapability)} case CapabilityDBus: *c = CapabilityJSON{new(DBusCapability)} default: return fmt.Errorf("invalid capability") } return json.Unmarshal(data, c.Capability) }