Skip to content

Commit 40635e4

Browse files
authored
schema: introduce byteprefix union representation strategy (ipld#194)
Ref: https://github.com/filecoin-project/specs/
1 parent cda87a2 commit 40635e4

3 files changed

Lines changed: 59 additions & 5 deletions

File tree

schemas/representations.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ Link is also not described in this section, as it's a rather unique business.)
4343
- `kinded` representation -- transcribes to varying (!) kinds in the Data Model.
4444
- `envelope` representation -- transcribes to a dual-entry `map` in the Data Model.
4545
- `inline` representation -- transcribes to a `map` in the Data Model (and has additional limitations).
46+
- `byteprefix` representation -- transcribes to `bytes` in the Data Model, only usable for unions of `bytes`.
4647
- Struct
4748
- `map` representation -- the default -- transcribes to `map` in the Data Model.
4849
- `tuple` representation -- transcribes to `list` in the Data Model.
@@ -291,3 +292,19 @@ This is because inline unions are only a defined concept when working with types
291292
that have a map representation -- so, our `Bar` type in the previously examples,
292293
which was of `int` kind, doesn't work for this example. We replaced it with
293294
another struct type, which -- since it has a `map` representation -- works.
295+
296+
#### union byteprefix representation example
297+
298+
```ipldsch
299+
type Signature union {
300+
| Secp256k1Signature 0
301+
| Bls12_381Signature 1
302+
} representation byteprefix
303+
304+
type Secp256k1Signature bytes
305+
type Bls12_381Signature bytes
306+
```
307+
308+
At the block level, this presents as a byte array, where the first byte is the discriminator (`0x00` or `0x01`) and the remainder is sliced to form either of the two types depending on the discriminator.
309+
310+
`byteprefix` is not valid for unions where any of the constitutive types are _not_ `Bytes`.

schemas/schema-schema.ipldsch

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -342,10 +342,18 @@ type TypeUnion struct {
342342
## UnionRepresentation is a union of all the distinct ways a TypeUnion's values
343343
## can be mapped onto a serialized format for the IPLD Data Model.
344344
##
345-
## There are "keyed", "envelop", and "inline" strategies, which are all ways
346-
## to produce representations in a map format (some literature may describe
347-
## this as "tagged" style unions), and a fourth style, "kinded" unions, may
348-
## actually encode itself as any of the other representation kinds!
345+
## There are five strategies that can be used to encode a union:
346+
## "keyed", "envelope", "inline", "byteprefix", and "kinded".
347+
## The "keyed", "envelope", and "inline" strategies are all ways to produce
348+
## representations in a map format, using map keys as type discriminators
349+
## (some literature may describe this as a "tagged" style of union).
350+
## The "byteprefix" strategy, only available only for unions in which all
351+
## member types themselves represent as bytes in the data model, uses another
352+
## byte as the type discrimination hint (and like the map-oriented strategies,
353+
## may also be seen as a form of "tagged" style unions).
354+
## The "kinded" strategy can describe a union in which member types have
355+
## several different representation kinds, and uses the representation kind
356+
## itself as the type discrimination hint to do so.
349357
##
350358
## Note: Unions can be used to produce a "nominative" style of type declarations
351359
## -- yes, even given that IPLD Schema systems are natively "structural" typing!
@@ -355,6 +363,7 @@ type UnionRepresentation union {
355363
| UnionRepresentation_Keyed "keyed"
356364
| UnionRepresentation_Envelope "envelope"
357365
| UnionRepresentation_Inline "inline"
366+
| UnionRepresentation_BytePrefix "byteprefix"
358367
} representation keyed
359368

360369
## "Kinded" union representations describe a bidirectional mapping between
@@ -408,6 +417,18 @@ type UnionRepresentation_Inline struct {
408417
discriminantTable {String:TypeName}
409418
}
410419

420+
## UnionRepresentation_BytePrefix describes a union representation for unions
421+
## whose member types are all bytes. It is encoded to a byte array whose
422+
## first byte is the discriminator and subsequent bytes form the discriminated
423+
## type.
424+
##
425+
## byteprefix is an invalid representation for any union that contains a type
426+
## that does not have a bytes representation.
427+
##
428+
type UnionRepresentation_BytePrefix struct {
429+
discriminantTable {TypeName:Int}
430+
}
431+
411432
## TypeStruct describes a type which has a group of fields of varying Type.
412433
## Each field has a name, which is used to access its value, similarly to
413434
## accessing values in a map.

schemas/schema-schema.ipldsch.json

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,8 @@
293293
"kinded": "UnionRepresentation_Kinded",
294294
"keyed": "UnionRepresentation_Keyed",
295295
"envelope": "UnionRepresentation_Envelope",
296-
"inline": "UnionRepresentation_Inline"
296+
"inline": "UnionRepresentation_Inline",
297+
"byteprefix": "UnionRepresentation_BytePrefix"
297298
}
298299
}
299300
},
@@ -346,6 +347,21 @@
346347
"map": {}
347348
}
348349
},
350+
"UnionRepresentation_BytePrefix": {
351+
"kind": "struct",
352+
"fields": {
353+
"discriminantTable": {
354+
"type": {
355+
"kind": "map",
356+
"keyType": "TypeName",
357+
"valueType": "Int"
358+
}
359+
}
360+
},
361+
"representation": {
362+
"map": {}
363+
}
364+
},
349365
"TypeStruct": {
350366
"kind": "struct",
351367
"fields": {

0 commit comments

Comments
 (0)