switch address.Kind {
case Descriptor:
- return eraseMessage(ParseDescriptor(topic, data, retained))
+ return eraseMessage(parsePayload[DescriptorPayload](address, data, retained))
case Availability:
- return eraseMessage(ParseAvailability(topic, data, retained))
+ return eraseMessage(parsePayload[AvailabilityPayload](address, data, retained))
case Reported:
- return eraseMessage(ParseReported(topic, data, retained))
+ return eraseMessage(parsePayload[ValuePayload](address, data, retained))
case Telemetry:
- return eraseMessage(ParseTelemetry(topic, data, retained))
+ return eraseMessage(parsePayload[ValuePayload](address, data, retained))
case Event:
- return eraseMessage(ParseEvent(topic, data, retained))
+ return eraseMessage(parsePayload[EventPayload](address, data, retained))
case Command:
- return eraseMessage(ParseCommand(topic, data, retained))
+ return eraseMessage(parsePayload[ValuePayload](address, data, retained))
case CommandBatch:
- return eraseMessage(ParseCommandBatch(topic, data, retained))
+ return eraseMessage(parsePayload[BatchPayload](address, data, retained))
case Result:
- return eraseMessage(ParseResult(topic, data, retained))
+ return eraseMessage(parsePayload[ResultPayload](address, data, retained))
case HubStatus:
- return eraseMessage(ParseHubStatus(topic, data, retained))
+ return eraseMessage(parsePayload[HubStatusPayload](address, data, retained))
default:
return Message[any]{}, fmt.Errorf("unsupported message kind")
}
}
-func eraseMessage[T any](message Message[T], err error) (Message[any], error) {
- if err != nil {
- return Message[any]{}, fmt.Errorf("parse message: %w", err)
- }
-
- return Message[any]{
- Address: message.Address,
- Metadata: message.Metadata,
- Payload: message.Payload,
- Retained: message.Retained,
- }, nil
-}
-
func buildMessage[T any](address Address, metadata Metadata, payload T) (Publication, error) {
topic, err := address.topic()
if err != nil {
return message, nil
}
+func eraseMessage[T any](message Message[T], err error) (Message[any], error) {
+ if err != nil {
+ return Message[any]{}, fmt.Errorf("parse message: %w", err)
+ }
+
+ return Message[any]{
+ Address: message.Address,
+ Metadata: message.Metadata,
+ Payload: message.Payload,
+ Retained: message.Retained,
+ }, nil
+}
+
func parsePayload[T any](address Address, data []byte, retained bool) (Message[T], error) {
kind := address.Kind
return nil
}
-func validateDescriptor(payload DescriptorPayload) error {
- if payload.Manufacturer == "" || payload.Model == "" || payload.Firmware == "" || len(string([]rune(payload.Attribution))) > 2000 || len(payload.Capabilities) == 0 {
- return fmt.Errorf("descriptor metadata or capabilities are invalid")
- }
-
- seen := make(map[string]bool, len(payload.Capabilities))
-
- for _, capability := range payload.Capabilities {
- if !ValidIdentifier(capability.ID) || !ValidIdentifier(capability.Type) || seen[capability.ID] {
- return fmt.Errorf("capability IDs and types must be valid and unique")
- }
-
- if !capability.ReportsState && !capability.AcceptsCommands {
- return fmt.Errorf("capability must have at least one access mode")
- }
-
- seen[capability.ID] = true
- }
-
- return nil
-}
-
func validateDescriptorFlags(raw json.RawMessage) error {
var fields struct {
Capabilities []map[string]json.RawMessage `json:"capabilities"`
return nil
}
+func validateDescriptor(payload DescriptorPayload) error {
+ if payload.Manufacturer == "" || payload.Model == "" || payload.Firmware == "" || len(string([]rune(payload.Attribution))) > 2000 || len(payload.Capabilities) == 0 {
+ return fmt.Errorf("descriptor metadata or capabilities are invalid")
+ }
+
+ seen := make(map[string]bool, len(payload.Capabilities))
+
+ for _, capability := range payload.Capabilities {
+ if !ValidIdentifier(capability.ID) || !ValidIdentifier(capability.Type) || seen[capability.ID] {
+ return fmt.Errorf("capability IDs and types must be valid and unique")
+ }
+
+ if !capability.ReportsState && !capability.AcceptsCommands {
+ return fmt.Errorf("capability must have at least one access mode")
+ }
+
+ seen[capability.ID] = true
+ }
+
+ return nil
+}
+
func validateAvailability(payload AvailabilityPayload) error {
if payload.Status != "online" && payload.Status != "offline" {
return fmt.Errorf("availability must be online or offline")