diff --git a/cdns.go b/cdns.go index 75cb0d1..2d284d7 100644 --- a/cdns.go +++ b/cdns.go @@ -20,10 +20,12 @@ import ( "github.com/blinklabs-io/gouroboros/cbor" ) +type CardanoDnsTtl uint + type CardanoDnsDomain struct { Origin []byte Records []CardanoDnsDomainRecord - AdditionalData any + AdditionalData CardanoDnsMaybe[any] } func (c CardanoDnsDomain) String() string { @@ -52,53 +54,79 @@ func (c *CardanoDnsDomain) UnmarshalCBOR(cborData []byte) error { return fmt.Errorf("unexpected constructor index: %d", tmpData.Constructor()) } tmpFields := tmpData.Fields() - switch len(tmpFields) { - case 2, 3: - c.Origin = tmpFields[0].(cbor.ByteString).Bytes() - for _, record := range tmpFields[1].([]any) { - recordConstr := record.(cbor.Constructor) - recordFields := recordConstr.Fields() - if recordConstr.Constructor() != 1 { - return fmt.Errorf("unexpected constructor index: %d", recordConstr.Constructor()) - } - var tmpRecord CardanoDnsDomainRecord - switch len(recordFields) { - case 3: - tmpRecord.Lhs = recordFields[0].(cbor.ByteString).Bytes() - tmpRecord.Type = recordFields[1].(cbor.ByteString).Bytes() - tmpRecord.Rhs = recordFields[2].(cbor.ByteString).Bytes() - case 4: - tmpRecord.Lhs = recordFields[0].(cbor.ByteString).Bytes() - tmpRecord.Ttl = uint(recordFields[1].(uint64)) - tmpRecord.Type = recordFields[2].(cbor.ByteString).Bytes() - tmpRecord.Rhs = recordFields[3].(cbor.ByteString).Bytes() - default: - return fmt.Errorf("unexpected constructor field length: %d", len(recordFields)) - } - c.Records = append(c.Records, tmpRecord) - } - if len(tmpData.Fields()) == 3 { - c.AdditionalData = tmpData.Fields()[2] + c.Origin = tmpFields[0].(cbor.ByteString).Bytes() + for _, record := range tmpFields[1].([]any) { + recordConstr := record.(cbor.Constructor) + var tmpRecord CardanoDnsDomainRecord + if _, err := cbor.Decode(recordConstr.Cbor(), &tmpRecord); err != nil { + return err } - default: - return fmt.Errorf("unexpected constructor field length: %d", len(tmpData.Fields())) + c.Records = append(c.Records, tmpRecord) } return nil } type CardanoDnsDomainRecord struct { + // This allows the type to be used with cbor.DecodeGeneric + cbor.StructAsArray Lhs []byte - Ttl uint + Ttl CardanoDnsMaybe[CardanoDnsTtl] Type []byte Rhs []byte } +func (c *CardanoDnsDomainRecord) UnmarshalCBOR(data []byte) error { + var tmpConstr cbor.Constructor + if _, err := cbor.Decode(data, &tmpConstr); err != nil { + return err + } + if tmpConstr.Constructor() != 1 { + return fmt.Errorf("unexpected constructor index: %d", tmpConstr.Constructor()) + } + return cbor.DecodeGeneric(tmpConstr.FieldsCbor(), c) +} + func (c CardanoDnsDomainRecord) String() string { return fmt.Sprintf( "CardanoDnsDomainRecord { Lhs = %s, Ttl = %d, Type = %s, Rhs = %s }", c.Lhs, - c.Ttl, + c.Ttl.Value, c.Type, c.Rhs, ) } + +type CardanoDnsMaybe[T any] struct { + // This allows the type to be used with cbor.DecodeGeneric + cbor.StructAsArray + Value T + hasValue bool +} + +func NewCardanoDnsMaybe[T any](v any) CardanoDnsMaybe[T] { + if v == nil { + return CardanoDnsMaybe[T]{} + } + return CardanoDnsMaybe[T]{ + Value: v.(T), + hasValue: true, + } +} + +func (c CardanoDnsMaybe[T]) HasValue() bool { + return c.hasValue +} + +func (c *CardanoDnsMaybe[T]) UnmarshalCBOR(data []byte) error { + var tmpConstr cbor.Constructor + if _, err := cbor.Decode(data, &tmpConstr); err != nil { + return err + } + if tmpConstr.Constructor() == 0 { + if err := cbor.DecodeGeneric(tmpConstr.FieldsCbor(), c); err != nil { + return err + } + c.hasValue = true + } + return nil +} diff --git a/cdns_test.go b/cdns_test.go index 13c57e6..dfd23dd 100644 --- a/cdns_test.go +++ b/cdns_test.go @@ -29,30 +29,53 @@ var cardanoDnsTestDefs = []struct { expectedObj models.CardanoDnsDomain }{ { - cborHex: "d87a9f4b666f6f2e63617264616e6f9fd87a9f4b666f6f2e63617264616e6f426e734f6e73312e666f6f2e63617264616e6fffd87a9f4b666f6f2e63617264616e6f426e734f6e73322e666f6f2e63617264616e6fffd87a9f4f6e73312e666f6f2e63617264616e6f41614a3137322e32382e302e32ffd87a9f4f6e73322e666f6f2e63617264616e6f187b416147312e322e332e34ffffff", + cborHex: "d87a9f4776696c6c6167659fd87a9f4f76696c6c6167652e63617264616e6fd8799f190e10ff41414a3137322e32382e302e32ffd87a9f4f76696c6c6167652e63617264616e6fd8799f197080ff426e73536e73312e76696c6c6167652e63617264616e6fffffd87a80ff", expectedObj: models.CardanoDnsDomain{ - Origin: []byte("foo.cardano"), + Origin: []byte("village"), Records: []models.CardanoDnsDomainRecord{ { - Lhs: []byte("foo.cardano"), + Lhs: []byte("village.cardano"), + Type: []byte("A"), + Rhs: []byte("172.28.0.2"), + Ttl: models.NewCardanoDnsMaybe[models.CardanoDnsTtl](models.CardanoDnsTtl(3600)), + }, + { + Lhs: []byte("village.cardano"), Type: []byte("ns"), - Rhs: []byte("ns1.foo.cardano"), + Rhs: []byte("ns1.village.cardano"), + Ttl: models.NewCardanoDnsMaybe[models.CardanoDnsTtl](models.CardanoDnsTtl(28800)), + }, + }, + }, + }, + { + cborHex: "d87a9f47656e636c6176659fd87a9f4f656e636c6176652e63617264616e6fd8799f190e10ff41414f3430312e3430312e3430312e343031ffd87a9f4f656e636c6176652e63617264616e6fd8799f197080ff426e73536e73312e656e636c6176652e63617264616e6fffd87a9f4f656e636c6176652e63617264616e6fd8799f190e10ff41414a3137322e32382e302e32ffd87a9f4f656e636c6176652e63617264616e6fd87a80426e73536e73322e656e636c6176652e63617264616e6fffffd87a80ff", + expectedObj: models.CardanoDnsDomain{ + Origin: []byte("enclave"), + Records: []models.CardanoDnsDomainRecord{ + { + Lhs: []byte("enclave.cardano"), + Type: []byte("A"), + Rhs: []byte("401.401.401.401"), + Ttl: models.NewCardanoDnsMaybe[models.CardanoDnsTtl](models.CardanoDnsTtl(3600)), }, { - Lhs: []byte("foo.cardano"), + Lhs: []byte("enclave.cardano"), Type: []byte("ns"), - Rhs: []byte("ns2.foo.cardano"), + Rhs: []byte("ns1.enclave.cardano"), + Ttl: models.NewCardanoDnsMaybe[models.CardanoDnsTtl](models.CardanoDnsTtl(28800)), }, { - Lhs: []byte("ns1.foo.cardano"), - Type: []byte("a"), + Lhs: []byte("enclave.cardano"), + Type: []byte("A"), Rhs: []byte("172.28.0.2"), + Ttl: models.NewCardanoDnsMaybe[models.CardanoDnsTtl](models.CardanoDnsTtl(3600)), }, { - Lhs: []byte("ns2.foo.cardano"), - Ttl: 123, - Type: []byte("a"), - Rhs: []byte("1.2.3.4"), + Lhs: []byte("enclave.cardano"), + Type: []byte("ns"), + Rhs: []byte("ns2.enclave.cardano"), + Ttl: models.NewCardanoDnsMaybe[models.CardanoDnsTtl](nil), }, }, }, diff --git a/go.mod b/go.mod index f93a5c5..9381386 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/blinklabs-io/cardano-models go 1.20 require ( - github.com/blinklabs-io/gouroboros v0.69.5 + github.com/blinklabs-io/gouroboros v0.70.0 github.com/fxamacker/cbor/v2 v2.5.0 github.com/go-playground/validator/v10 v10.17.0 ) diff --git a/go.sum b/go.sum index a449255..f461e99 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/blinklabs-io/gouroboros v0.69.5 h1:oFTObwPchrzZAunNA/+Y6g5NwMZQhA1Zj+iZGzX4TsU= -github.com/blinklabs-io/gouroboros v0.69.5/go.mod h1:ecxtryJb+vIeVizQl4nYJr0tVdyIgOTze7R9xeGqFu4= +github.com/blinklabs-io/gouroboros v0.70.0 h1:/Jlo1G2c7rQDjijSXNti4v+J34QSkQwS57Vso6STqBo= +github.com/blinklabs-io/gouroboros v0.70.0/go.mod h1:ecxtryJb+vIeVizQl4nYJr0tVdyIgOTze7R9xeGqFu4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=