go_wireproto/types.go
brent saner d4bb259b83
v1.0.0
Initial release.
2024-07-10 00:18:54 -04:00

183 lines
6.7 KiB
Go

package wireproto
import (
`encoding/xml`
`github.com/google/uuid`
)
/*
Fields, commonly referred to in this library as "fv", "fvpair", etc. consist of both a name and a value.
This not intended to be a map conceptually so much as a "type" of data and the data itself, but it certainly can be represented as map-like.
*/
type (
// FieldName represents the name/identifier of a field.
FieldName []byte
// FieldValue is the value (data) of a specified field
FieldValue []byte
)
type common struct {
size uint32
}
type (
FVP interface {
Model
GetParent() (rec Record)
ToMap() (m map[string]interface{})
}
Record interface {
Model
GetParent() (rg RecordGroup)
ToMap() (m []map[string]interface{})
getFvps() (fvp []FVP)
}
RecordGroup interface {
Model
GetParent() (msg Message)
ToMap() (m [][]map[string]interface{})
getRecords() (records []Record)
}
Message interface {
Model
ToMap() (m [][][]map[string]interface{})
getRecordGroups() (recordGroups []RecordGroup)
}
Model interface {
Model() (out string)
ModelCustom(indent, sep string, level uint) (out string)
getIdx() (idx int)
}
)
/*
Request contains a Request message as sent to a remote target. It conforms to Message.
Either end ("client" or "server") may send a request, but it should represent the beginning of a complete/new transaction (a Message).
*/
type Request struct {
XMLName xml.Name `xml:"request" json:"-" yaml:"-" toml:"-" validate:"-"`
*common
/*
Checksum is a CRC32 (see specification) checksum of the message.
It is optional (but recommended) for requests.
*/
Checksum *uint32 `json:"cksum,omitempty" xml:"cksum,attr,omitempty" yaml:"Checksum,omitempty" toml:"Checksum,omitempty" validate:"omitempty"`
// ProtocolVersion specifies the specification version of this message.
ProtocolVersion uint32 `json:"proto_ver" xml:"protoVer,attr" yaml:"Protocol Version" toml:"ProtocolVersion" validate:"required"`
/*
RecordGroups contains grouped sets (RequestRecordGroup) of RequestRecord.
At least one is required.
Most implementations are likely to use only a single RequestRecordGroup in RecordGroups,
but multiple may be included. They are assumed to be seperate contexts/queries/commands/etc. if
multiple groups are included.
*/
RecordGroups []*RequestRecordGroup `json:"rg" xml:"recordGroups>recordGroup" yaml:"Record Groups" toml:"RecordGroups" validate:"required,dive"`
resp *ResponseRecord // only if part of a Response.
connId uuid.UUID
}
// RequestRecordGroup contains one or more related RequestRecord. It conforms to RecordGroup.
type RequestRecordGroup struct {
XMLName xml.Name `xml:"recordGroup" json:"-" yaml:"-" toml:"-" validate:"-"`
*common
// Records contains the sets of one or more related RequestRecord.
Records []*RequestRecord `json:"rec" xml:"records>record" yaml:"Records" toml:"Records" validate:"required,dive"`
connId uuid.UUID
parent *Request
rgIdx int
}
/*
RequestRecord contains a record of one or more related FieldValuePair. It conforms to Record.
It is designed such that a single RequestRecord is responded with a single ResponseRecord.
*/
type RequestRecord struct {
XMLName xml.Name `xml:"record" json:"-" yaml:"-" toml:"-" validate:"-"`
*common
// Pairs contains one or more related FieldValuePair.
Pairs []*FieldValuePair `json:"fvp" xml:"fvPairs>fvPair" yaml:"Field/Value Pairs" toml:"FieldValuePairs" validate:"required,dive"`
connId uuid.UUID
parent *RequestRecordGroup
rgIdx int
rIdx int
}
// Response contains an entire response message to a Request. It conforms to Message.
type Response struct {
XMLName xml.Name `xml:"response" json:"-" yaml:"-" toml:"-" validate:"-"`
*common
/*
Status is a short identifier of the status for the Request as executed.
It is the very first byte on the wire to allow the remote end to easily check whether an error has occurred.
(Detailed error messages should be contained in the RecordGroups.)
TODO: custom type, marshal/unmarshalers?
*/
Status uint8 `json:"status" xml:"status,attr" yaml:"Status" toml:"Status" validate:"required"`
/*
Checksum is a CRC32 (see specification) checksum of the message.
It is required for responses.
*/
Checksum uint32 `json:"cksum" xml:"cksum,attr" yaml:"Checksum" toml:"Checksum" validate:"required"`
// ProtocolVersion specifies the specification version of this message.
ProtocolVersion uint32 `json:"proto_ver" xml:"protoVer,attr" yaml:"Protocol Version" toml:"ProtocolVersion" validate:"required"`
/*
RecordGroups contains grouped sets (ResponseRecordGroup) of ResponseRecord.
At least one is required.
Most implementations are likely to use only a single ResponseRecordGroup in RecordGroups,
but multiple may be included. They are assumed to be seperate contexts/queries/commands/etc. if
multiple groups are included.
*/
RecordGroups []*ResponseRecordGroup `json:"rg" xml:"recordGroups>recordGroup" yaml:"Record Groups"`
}
// ResponseRecordGroup contains related ResponseRecord objects. It conforms to RecordGroup.
type ResponseRecordGroup struct {
XMLName xml.Name `xml:"recordGroup" json:"-" yaml:"-" toml:"-" validate:"-"`
*common
// Records contains one or more related ResponseRecord.
Records []*ResponseRecord `json:"rec" xml:"records>record" yaml:"Records" toml:"Records" validate:"required,dive"`
parent *Response
rgIdx int
}
// ResponseRecord contains the response to a single RequestRecord. It conforms to Record.
type ResponseRecord struct {
XMLName xml.Name `xml:"record" json:"-" yaml:"-" toml:"-" validate:"-"`
*common
Pairs []*FieldValuePair `json:"fvp" xml:"fvPairs>fvPair" yaml:"Field/Value Pairs" toml:"FieldValuePairs" validate:"required,dive"`
/*
OriginalRecord contains the associcated RequestRecord.
*/
OriginalRecord *RequestRecord `json:"orig_req" xml:"originalReq" yaml:"Original Request" toml:"OriginalRequest"`
parent *ResponseRecordGroup
rgIdx int
rIdx int
}
// FieldValuePair contains a single "key" (identifier) and value. It is found in both a RequestRecord and a ResponseRecord. It conforms to FVP.
type FieldValuePair struct {
XMLName xml.Name `xml:"fvPair" json:"-" yaml:"-" toml:"-" validate:"-"`
*common
// Name should be treated as a "type" or "identifier" for the data in Value.
Name FieldName `json:"name,omitempty" xml:"name,attr,omitempty" yaml:"Name,omitempty" toml:"Name,omitempty" validate:"omitempty"`
/*
Value containts arbitrary data.
Content, validation/verification, parsing, etc. of the data is left to downstream implementations and is out of spec for this protocol.
*/
Value FieldValue `json:"value,omitempty" xml:"value,chardata,omitempty" yaml:"Value,omitempty" toml:"Value,omitempty" validate:"omitempty"`
connId *uuid.UUID
parent Record
rgIdx int
rIdx int
fvpidx int
}