Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions codegen/source.go.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ var _ types.ENUM = {{capitalise .Name}}("")
// {{capitalise .Name}} is a {{.RawType}} type
type {{capitalise .Name}} struct {
{{- range $field := .Fields}}
{{capitalise $field.Name}} {{$field.Type.GoType}} `json:"{{$field.Name}}"{{if $field.IsBytesHex}} hex:"bytes16"{{else if $field.IsUint32}} hex:"uint32"{{else if $field.IsUint32List}} hex:"[]uint32"{{end}}`
{{capitalise $field.Name}} {{$field.Type.GoType}} `json:"{{$field.Name}}"{{if $field.IsOptional}} hex:"optional"{{else if $field.IsBytesHex}} hex:"bytes16"{{else if $field.IsUint32}} hex:"uint32"{{else if $field.IsUint32List}} hex:"[]uint32"{{end}}`
{{- end}}
}

Expand Down Expand Up @@ -359,7 +359,7 @@ func (t *{{capitalise .Name}}) UnmarshalHex(data string) error {
type {{capitalise .Name}}MCMSParams struct {
{{- range .Fields}}
{{- if not (isCallerField .Name)}}
{{capitalise .Name}} {{.Type.GoType}} `json:"{{.Name}}"{{if .IsBytesHex}} hex:"bytes16"{{else if .IsUint32}} hex:"uint32"{{else if .IsUint32List}} hex:"[]uint32"{{end}}`
{{capitalise .Name}} {{.Type.GoType}} `json:"{{.Name}}"{{if .IsOptional}} hex:"optional"{{else if .IsBytesHex}} hex:"bytes16"{{else if .IsUint32}} hex:"uint32"{{else if .IsUint32List}} hex:"[]uint32"{{end}}`
{{- end}}
{{- end}}
}
Expand Down
4 changes: 2 additions & 2 deletions examples/codegen/all_kinds_of_1_0_0.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,8 @@ type OneOfEverything struct {
SomeBoolean types.BOOL `json:"someBoolean"`
SomeInteger types.INT64 `json:"someInteger"`
SomeDecimal types.NUMERIC `json:"someDecimal"`
SomeMaybe *types.INT64 `json:"someMaybe"`
SomeMaybeNot *types.INT64 `json:"someMaybeNot"`
SomeMaybe *types.INT64 `json:"someMaybe" hex:"optional"`
SomeMaybeNot *types.INT64 `json:"someMaybeNot" hex:"optional"`
SomeText types.TEXT `json:"someText"`
SomeDate types.DATE `json:"someDate"`
SomeDatetime types.TIMESTAMP `json:"someDatetime"`
Expand Down
35 changes: 35 additions & 0 deletions pkg/codec/hex_codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,20 @@ func (c *HexCodec) encodeStruct(rv reflect.Value) ([]byte, error) {
if err != nil {
return nil, fmt.Errorf("failed to encode bytes16 field %s: %w", fieldType.Name, err)
}
case "optional":
// hex:"optional" - encode Daml Optional type: 0x00 for None, 0x01 + value for Some
if field.Kind() != reflect.Ptr {
return nil, fmt.Errorf("hex:\"optional\" tag only valid on pointer fields, got %v", field.Kind())
}
if field.IsNil() {
encoded = []byte{0x00}
} else {
valueEncoded, encErr := c.encode(field.Elem().Interface())
if encErr != nil {
return nil, fmt.Errorf("failed to encode optional field %s: %w", fieldType.Name, encErr)
}
encoded = append([]byte{0x01}, valueEncoded...)
}
default:
// No tag or unknown tag - use default encoding
encoded, err = c.encode(field.Interface())
Expand Down Expand Up @@ -874,6 +888,27 @@ func (c *HexCodec) decodeStruct(data []byte, offset int, target reflect.Value) (
rawBytes := data[offset : offset+byteCount]
field.SetString(hex.EncodeToString(rawBytes))
offset += byteCount
case "optional":
// hex:"optional" - decode Daml Optional type: 0x00 for None, 0x01 + value for Some
if field.Kind() != reflect.Ptr {
return offset, fmt.Errorf("hex:\"optional\" tag only valid on pointer fields, got %v", field.Kind())
}
if offset >= len(data) {
return offset, fmt.Errorf("not enough data for optional flag at offset %d", offset)
}
flag := data[offset]
offset++
if flag == 0x01 {
newVal := reflect.New(field.Type().Elem())
offset, err = c.decodeValue(data, offset, newVal.Elem())
if err != nil {
return offset, fmt.Errorf("failed to decode optional field %s: %w", fieldType.Name, err)
}
field.Set(newVal)
} else if flag != 0x00 {
return offset, fmt.Errorf("invalid optional flag 0x%02x for field %s", flag, fieldType.Name)
}
// flag == 0x00: leave field as nil (zero value)
default:
// No tag or unknown tag - use default decoding
offset, err = c.decodeValue(data, offset, field)
Expand Down
Loading