at main 3.1 kB view raw
1package plc 2 3import ( 4 "encoding/json" 5 "fmt" 6) 7 8type OperationType string 9 10const ( 11 OperationTypePLC OperationType = "plc_operation" 12 OperationTypeTombstone OperationType = "plc_tombstone" 13 OperationTypeCreate OperationType = "create" 14) 15 16type ServiceEndpoint struct { 17 Type string `json:"type"` 18 Endpoint string `json:"endpoint"` 19} 20 21type Operation struct { 22 Type OperationType `json:"type"` 23 RotationKeys []string `json:"rotationKeys"` 24 VerificationMethods map[string]string `json:"verificationMethods"` 25 AlsoKnownAs []string `json:"alsoKnownAs"` 26 Services map[string]ServiceEndpoint `json:"services"` 27 Prev *string `json:"prev"` 28 Sig string `json:"sig"` 29} 30 31type TombstoneOperation struct { 32 Type OperationType `json:"type"` 33 Prev string `json:"prev"` 34 Sig string `json:"sig"` 35} 36 37type DeprecatedOperation struct { 38 Type OperationType `json:"type"` 39 SigningKey string `json:"signingKey"` 40 RecoveryKey string `json:"recoveryKey"` 41 Handle string `json:"handle"` 42 Service string `json:"service"` 43 Prev *string `json:"prev"` 44 Sig string `json:"sig"` 45} 46 47type PLCOperation struct { 48 *Operation 49 *TombstoneOperation 50 *DeprecatedOperation 51} 52 53func (op *PLCOperation) UnmarshalJSON(data []byte) error { 54 var typeOnly struct { 55 Type OperationType `json:"type"` 56 } 57 58 if err := json.Unmarshal(data, &typeOnly); err != nil { 59 return fmt.Errorf("failed to unmarshal operation type: %w", err) 60 } 61 62 switch typeOnly.Type { 63 case OperationTypePLC: 64 var regular Operation 65 if err := json.Unmarshal(data, &regular); err != nil { 66 return fmt.Errorf("failed to unmarshal plc_operation: %w", err) 67 } 68 op.Operation = &regular 69 70 case OperationTypeTombstone: 71 var tombstone TombstoneOperation 72 if err := json.Unmarshal(data, &tombstone); err != nil { 73 return fmt.Errorf("failed to unmarshal plc_tombstone: %w", err) 74 } 75 op.TombstoneOperation = &tombstone 76 77 case OperationTypeCreate: 78 var deprecated DeprecatedOperation 79 if err := json.Unmarshal(data, &deprecated); err != nil { 80 return fmt.Errorf("failed to unmarshal deprecated create operation: %w", err) 81 } 82 op.DeprecatedOperation = &deprecated 83 84 default: 85 return fmt.Errorf("unknown operation type: %s", typeOnly.Type) 86 } 87 88 return nil 89} 90 91func (op PLCOperation) MarshalJSON() ([]byte, error) { 92 if op.Operation != nil { 93 return json.Marshal(op.Operation) 94 } 95 if op.TombstoneOperation != nil { 96 return json.Marshal(op.TombstoneOperation) 97 } 98 if op.DeprecatedOperation != nil { 99 return json.Marshal(op.DeprecatedOperation) 100 } 101 return nil, fmt.Errorf("no valid operation data to marshal") 102} 103 104func (op PLCOperation) GetType() OperationType { 105 if op.Operation != nil { 106 return op.Operation.Type 107 } 108 if op.TombstoneOperation != nil { 109 return op.TombstoneOperation.Type 110 } 111 if op.DeprecatedOperation != nil { 112 return op.DeprecatedOperation.Type 113 } 114 return "" 115}