mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-28 07:29:58 +00:00
TUN-528: Move cloudflared into a separate repo
This commit is contained in:
164
vendor/zombiezen.com/go/capnproto2/pogs/doc.go
generated
vendored
Normal file
164
vendor/zombiezen.com/go/capnproto2/pogs/doc.go
generated
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
Package pogs provides functions to convert Cap'n Proto messages to and
|
||||
from Go structs. pogs operates similarly to encoding/json: define a
|
||||
struct that is optionally marked up with tags, then Insert and Extract
|
||||
will copy the fields to and from the corresponding Cap'n Proto struct.
|
||||
|
||||
Inserting
|
||||
|
||||
To copy data into a Cap'n Proto struct, we use the Insert function.
|
||||
Consider the following schema:
|
||||
|
||||
struct Message {
|
||||
name @0 :Text;
|
||||
body @1 :Text;
|
||||
time @2 :Int64;
|
||||
}
|
||||
|
||||
and the Go struct:
|
||||
|
||||
type Message struct {
|
||||
Name string
|
||||
Body string
|
||||
Time int64
|
||||
}
|
||||
|
||||
We can copy the Go struct into a Cap'n Proto struct like this:
|
||||
|
||||
_, arena, _ := capnp.NewMessage(capnp.SingleSegment(nil))
|
||||
root, _ := myschema.NewRootMessage(arena)
|
||||
m := &Message{"Alice", "Hello", 1294706395881547000}
|
||||
err := pogs.Insert(myschema.Message_TypeID, root.Struct, m)
|
||||
|
||||
Note that if any field names in our Go struct don't match to a field in
|
||||
the Cap'n Proto struct, Insert returns an error. We'll see how to fix
|
||||
that in a moment.
|
||||
|
||||
Extracting
|
||||
|
||||
Copying data back out from a Cap'n Proto struct is quite similar: we
|
||||
pass a pointer to our Go struct to Extract.
|
||||
|
||||
m := new(Message)
|
||||
err := pogs.Extract(m, myschema.Message_TypeID, root.Struct)
|
||||
|
||||
Types
|
||||
|
||||
The mapping between Cap'n Proto types and underlying Go types is as
|
||||
follows:
|
||||
|
||||
Bool -> bool
|
||||
Int8, Int16, Int32, Int64 -> int8, int16, int32, int64
|
||||
UInt8, UInt16, UInt32, UInt64 -> uint8, uint16, uint32, uint64
|
||||
Float32, Float64 -> float32, float64
|
||||
Text -> either []byte or string
|
||||
Data -> []byte
|
||||
List -> slice
|
||||
enum -> uint16
|
||||
struct -> a struct or pointer to struct
|
||||
interface -> a capnp.Client or struct with
|
||||
exactly one field, named
|
||||
"Client", of type capnp.Client
|
||||
|
||||
Note that the unsized int and uint type can't be used: int and float
|
||||
types must match in size. For Data and Text fields using []byte, the
|
||||
filled-in byte slice will point to original segment.
|
||||
|
||||
Renaming and Omitting Fields
|
||||
|
||||
By default, the Go field name is the same as the Cap'n Proto schema
|
||||
field name with the first letter capitalized. If we want to change this
|
||||
mapping, we use the capnp field tag.
|
||||
|
||||
type MessageRenamed struct {
|
||||
Subject string `capnp:"name"`
|
||||
Body string
|
||||
SentMillis int64 `capnp:"time"`
|
||||
}
|
||||
|
||||
Using a "-" will cause the field to be ignored by the Insert and
|
||||
Extract functions.
|
||||
|
||||
type ExtraFieldsMessage struct {
|
||||
ID uint64 `capnp:"-"`
|
||||
Name string
|
||||
Body string
|
||||
Time int64
|
||||
}
|
||||
|
||||
Unions
|
||||
|
||||
Since Go does not have support for variant types, Go structs that want
|
||||
to use fields inside a Cap'n Proto union must have an explicit
|
||||
discriminant field called Which. The Extract function will populate the
|
||||
Which field and the Insert function will read the Which field to
|
||||
determine which field to set. Given this schema:
|
||||
|
||||
struct Shape {
|
||||
area @0 :Float64;
|
||||
|
||||
union {
|
||||
circle @1 :Float64;
|
||||
square @2 :Float64;
|
||||
}
|
||||
}
|
||||
|
||||
the Go struct should look like this:
|
||||
|
||||
type Shape struct {
|
||||
Area float64
|
||||
|
||||
Which myschema.Shape_Which // or any other uint16 type
|
||||
Circle float64
|
||||
Square float64
|
||||
}
|
||||
|
||||
Attempting to use fields in a union without a uint16 Which field will
|
||||
result in an error. There is one exception: we can declare our Which
|
||||
field to be fixed to one particular union value by using a field tag.
|
||||
|
||||
type Square struct {
|
||||
Which struct{} `capnp:",which=square"`
|
||||
Area float64
|
||||
Width float64 `capnp:"square"`
|
||||
}
|
||||
|
||||
This can be useful if we want to use a different Go type depending on
|
||||
which field in the union is set.
|
||||
|
||||
shape, err := myschema.ReadRootShape(msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch shape.Which() {
|
||||
case myschema.Shape_Which_square:
|
||||
sq := new(Square)
|
||||
err = pogs.Extract(sq, myschema.Square_TypeID, shape.Struct)
|
||||
return sq, err
|
||||
case myschema.Shape_Which_circle:
|
||||
// ...
|
||||
}
|
||||
|
||||
Embedding
|
||||
|
||||
Anonymous struct fields are usually extracted or inserted as if their
|
||||
inner exported fields were fields in the outer struct, subject to the
|
||||
rules in the next paragraph. An anonymous struct field with a name
|
||||
given in its capnp tag is treated as having that name, rather than being
|
||||
anonymous. An anonymous struct field with a capnp tag of "-" will be
|
||||
ignored.
|
||||
|
||||
The visibility rules for struct fields are amended for pogs in the same
|
||||
way they are amended in encoding/json: if there are multiple fields at
|
||||
the same level, and that level is the least nested, the following extra
|
||||
rules apply:
|
||||
|
||||
1) Of those fields, if any are capnp-tagged, only tagged fields are
|
||||
considered, even if there are multiple untagged fields that would
|
||||
otherwise conflict.
|
||||
2) If there is exactly one field (tagged or not according to the first
|
||||
rule), that is selected.
|
||||
3) Otherwise, there are multiple fields, and all are ignored; no error
|
||||
occurs.
|
||||
*/
|
||||
package pogs // import "zombiezen.com/go/capnproto2/pogs"
|
Reference in New Issue
Block a user