src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

serializer.go (6167B)


      1 package eventstream
      2 
      3 import (
      4 	"math/big"
      5 	"time"
      6 
      7 	"github.com/aws/smithy-go"
      8 	"github.com/aws/smithy-go/document"
      9 	"github.com/aws/smithy-go/traits"
     10 )
     11 
     12 // ShapeSerializer wraps a [smithy.ShapeSerializer], much like the internal
     13 // httpbinding serializer, to handle event stream message binding traits.
     14 type ShapeSerializer struct {
     15 	Message *Message
     16 
     17 	inner       smithy.ShapeSerializer
     18 	contentType string // may be inflenced by bindings
     19 	depth       int
     20 	hasBody     bool
     21 }
     22 
     23 var _ smithy.ShapeSerializer = (*ShapeSerializer)(nil)
     24 
     25 // NewShapeSerializer returns a serializer for a single Message.
     26 func NewShapeSerializer(msg *Message, inner smithy.ShapeSerializer) *ShapeSerializer {
     27 	return &ShapeSerializer{
     28 		Message: msg,
     29 		inner:   inner,
     30 	}
     31 }
     32 
     33 // ContentType returns the resolved content type for the event message payload
     34 // after serialization, which may be affected by bindings.
     35 func (s *ShapeSerializer) ContentType() string {
     36 	return s.contentType
     37 }
     38 
     39 // Bytes returns the serialized body bytes.
     40 func (s *ShapeSerializer) Bytes() []byte {
     41 	return s.inner.Bytes()
     42 }
     43 
     44 // WriteBool implements [smithy.ShapeSerializer].
     45 func (s *ShapeSerializer) WriteBool(schema *smithy.Schema, v bool) {
     46 	if isEventHeader(schema) {
     47 		s.Message.Headers.Set(schema.MemberName(), BoolValue(v))
     48 		return
     49 	}
     50 	s.inner.WriteBool(schema, v)
     51 }
     52 
     53 // WriteInt8 implements [smithy.ShapeSerializer].
     54 func (s *ShapeSerializer) WriteInt8(schema *smithy.Schema, v int8) {
     55 	if isEventHeader(schema) {
     56 		s.Message.Headers.Set(schema.MemberName(), Int8Value(v))
     57 		return
     58 	}
     59 	s.inner.WriteInt8(schema, v)
     60 }
     61 
     62 // WriteInt16 implements [smithy.ShapeSerializer].
     63 func (s *ShapeSerializer) WriteInt16(schema *smithy.Schema, v int16) {
     64 	if isEventHeader(schema) {
     65 		s.Message.Headers.Set(schema.MemberName(), Int16Value(v))
     66 		return
     67 	}
     68 	s.inner.WriteInt16(schema, v)
     69 }
     70 
     71 // WriteInt32 implements [smithy.ShapeSerializer].
     72 func (s *ShapeSerializer) WriteInt32(schema *smithy.Schema, v int32) {
     73 	if isEventHeader(schema) {
     74 		s.Message.Headers.Set(schema.MemberName(), Int32Value(v))
     75 		return
     76 	}
     77 	s.inner.WriteInt32(schema, v)
     78 }
     79 
     80 // WriteInt64 implements [smithy.ShapeSerializer].
     81 func (s *ShapeSerializer) WriteInt64(schema *smithy.Schema, v int64) {
     82 	if isEventHeader(schema) {
     83 		s.Message.Headers.Set(schema.MemberName(), Int64Value(v))
     84 		return
     85 	}
     86 	s.inner.WriteInt64(schema, v)
     87 }
     88 
     89 // WriteFloat32 implements [smithy.ShapeSerializer].
     90 func (s *ShapeSerializer) WriteFloat32(schema *smithy.Schema, v float32) {
     91 	s.inner.WriteFloat32(schema, v)
     92 }
     93 
     94 // WriteFloat64 implements [smithy.ShapeSerializer].
     95 func (s *ShapeSerializer) WriteFloat64(schema *smithy.Schema, v float64) {
     96 	s.inner.WriteFloat64(schema, v)
     97 }
     98 
     99 // WriteString implements [smithy.ShapeSerializer].
    100 func (s *ShapeSerializer) WriteString(schema *smithy.Schema, v string) {
    101 	if isEventHeader(schema) {
    102 		s.Message.Headers.Set(schema.MemberName(), StringValue(v))
    103 		return
    104 	}
    105 	if isEventPayload(schema) {
    106 		s.Message.Payload = []byte(v)
    107 		s.contentType = "text/plain"
    108 		return
    109 	}
    110 	s.inner.WriteString(schema, v)
    111 }
    112 
    113 // WriteBlob implements [smithy.ShapeSerializer].
    114 func (s *ShapeSerializer) WriteBlob(schema *smithy.Schema, v []byte) {
    115 	if isEventHeader(schema) {
    116 		s.Message.Headers.Set(schema.MemberName(), BytesValue(v))
    117 		return
    118 	}
    119 	if isEventPayload(schema) {
    120 		s.Message.Payload = v
    121 		s.contentType = "application/octet-stream"
    122 		return
    123 	}
    124 	s.inner.WriteBlob(schema, v)
    125 }
    126 
    127 // WriteTime implements [smithy.ShapeSerializer].
    128 func (s *ShapeSerializer) WriteTime(schema *smithy.Schema, v time.Time) {
    129 	if isEventHeader(schema) {
    130 		s.Message.Headers.Set(schema.MemberName(), TimestampValue(v))
    131 		return
    132 	}
    133 	s.inner.WriteTime(schema, v)
    134 }
    135 
    136 // WriteBigInt implements [smithy.ShapeSerializer].
    137 func (s *ShapeSerializer) WriteBigInt(schema *smithy.Schema, v *big.Int) {
    138 	s.inner.WriteBigInt(schema, v)
    139 }
    140 
    141 // WriteBigFloat implements [smithy.ShapeSerializer].
    142 func (s *ShapeSerializer) WriteBigFloat(schema *smithy.Schema, v *big.Float) {
    143 	s.inner.WriteBigFloat(schema, v)
    144 }
    145 
    146 // WriteStruct implements [smithy.ShapeSerializer].
    147 func (s *ShapeSerializer) WriteStruct(schema *smithy.Schema) {
    148 	s.depth++
    149 	if s.depth > 1 {
    150 		s.inner.WriteStruct(schema)
    151 		return
    152 	}
    153 	// At depth 1 (the event struct itself), start a JSON body if there are
    154 	// implicit body members (members without @eventHeader or @eventPayload).
    155 	for _, m := range schema.Members() {
    156 		if !isEventBound(m) {
    157 			s.inner.WriteStruct(schema)
    158 			s.hasBody = true
    159 			return
    160 		}
    161 	}
    162 }
    163 
    164 // CloseStruct implements [smithy.ShapeSerializer].
    165 func (s *ShapeSerializer) CloseStruct() {
    166 	if s.depth > 1 || s.hasBody {
    167 		s.inner.CloseStruct()
    168 	}
    169 	if s.depth == 1 {
    170 		s.hasBody = false
    171 	}
    172 	s.depth--
    173 }
    174 
    175 // WriteUnion implements [smithy.ShapeSerializer].
    176 func (s *ShapeSerializer) WriteUnion(schema, variant *smithy.Schema) {
    177 	s.inner.WriteUnion(schema, variant)
    178 }
    179 
    180 // CloseUnion implements [smithy.ShapeSerializer].
    181 func (s *ShapeSerializer) CloseUnion() {
    182 	s.inner.CloseUnion()
    183 }
    184 
    185 // WriteNil implements [smithy.ShapeSerializer].
    186 func (s *ShapeSerializer) WriteNil(schema *smithy.Schema) {
    187 	s.inner.WriteNil(schema)
    188 }
    189 
    190 // WriteList implements [smithy.ShapeSerializer].
    191 func (s *ShapeSerializer) WriteList(schema *smithy.Schema) {
    192 	s.inner.WriteList(schema)
    193 }
    194 
    195 // CloseList implements [smithy.ShapeSerializer].
    196 func (s *ShapeSerializer) CloseList() {
    197 	s.inner.CloseList()
    198 }
    199 
    200 // WriteMap implements [smithy.ShapeSerializer].
    201 func (s *ShapeSerializer) WriteMap(schema *smithy.Schema) {
    202 	s.inner.WriteMap(schema)
    203 }
    204 
    205 // WriteKey implements [smithy.ShapeSerializer].
    206 func (s *ShapeSerializer) WriteKey(schema *smithy.Schema, key string) {
    207 	s.inner.WriteKey(schema, key)
    208 }
    209 
    210 // CloseMap implements [smithy.ShapeSerializer].
    211 func (s *ShapeSerializer) CloseMap() {
    212 	s.inner.CloseMap()
    213 }
    214 
    215 // WriteDocument implements [smithy.ShapeSerializer].
    216 func (s *ShapeSerializer) WriteDocument(schema *smithy.Schema, v document.Value) {
    217 	s.inner.WriteDocument(schema, v)
    218 }
    219 
    220 func isEventHeader(schema *smithy.Schema) bool {
    221 	_, ok := smithy.SchemaTrait[*traits.EventHeader](schema)
    222 	return ok
    223 }
    224 
    225 func isEventPayload(schema *smithy.Schema) bool {
    226 	_, ok := smithy.SchemaTrait[*traits.EventPayload](schema)
    227 	return ok
    228 }