// Code generated by bebopc-go; DO NOT EDIT.

package generated

import (
	"github.com/200sc/bebop"
	"github.com/200sc/bebop/iohelp"
	"io"
)

var _ bebop.Record = &taggedStruct{}

type taggedStruct struct {
	foo string `json:"foo,omitempty"`
}

func (bbp taggedStruct) MarshalBebopTo(buf []byte) int {
	at := 0
	iohelp.WriteUint32Bytes(buf[at:], uint32(len(bbp.foo)))
	copy(buf[at+4:at+4+len(bbp.foo)], []byte(bbp.foo))
	at += 4 + len(bbp.foo)
	return at
}

func (bbp *taggedStruct) UnmarshalBebop(buf []byte) (err error) {
	at := 0
	bbp.foo, err = iohelp.ReadStringBytes(buf[at:])
	if err != nil {
		return err
	}
	at += 4 + len(bbp.foo)
	return nil
}

func (bbp *taggedStruct) MustUnmarshalBebop(buf []byte) {
	at := 0
	bbp.foo = iohelp.MustReadStringBytes(buf[at:])
	at += 4 + len(bbp.foo)
}

func (bbp taggedStruct) EncodeBebop(iow io.Writer) (err error) {
	w := iohelp.NewErrorWriter(iow)
	iohelp.WriteUint32(w, uint32(len(bbp.foo)))
	w.Write([]byte(bbp.foo))
	return w.Err
}

func (bbp *taggedStruct) DecodeBebop(ior io.Reader) (err error) {
	r := iohelp.NewErrorReader(ior)
	bbp.foo = iohelp.ReadString(r)
	return r.Err
}

func (bbp taggedStruct) Size() int {
	bodyLen := 0
	bodyLen += 4 + len(bbp.foo)
	return bodyLen
}

func (bbp taggedStruct) MarshalBebop() []byte {
	buf := make([]byte, bbp.Size())
	bbp.MarshalBebopTo(buf)
	return buf
}

func maketaggedStruct(r *iohelp.ErrorReader) (taggedStruct, error) {
	v := taggedStruct{}
	err := v.DecodeBebop(r)
	return v, err
}

func maketaggedStructFromBytes(buf []byte) (taggedStruct, error) {
	v := taggedStruct{}
	err := v.UnmarshalBebop(buf)
	return v, err
}

func mustMaketaggedStructFromBytes(buf []byte) taggedStruct {
	v := taggedStruct{}
	v.MustUnmarshalBebop(buf)
	return v
}

var _ bebop.Record = &taggedMessage{}

type taggedMessage struct {
	bar *uint8 `db:"bar"`
}

func (bbp taggedMessage) MarshalBebopTo(buf []byte) int {
	at := 0
	iohelp.WriteUint32Bytes(buf[at:], uint32(bbp.Size()-4))
	at += 4
	if bbp.bar != nil {
		buf[at] = 1
		at++
		iohelp.WriteUint8Bytes(buf[at:], *bbp.bar)
		at += 1
	}
	return at
}

func (bbp *taggedMessage) UnmarshalBebop(buf []byte) (err error) {
	at := 0
	_ = iohelp.ReadUint32Bytes(buf[at:])
	buf = buf[4:]
	for {
		switch buf[at] {
		case 1:
			at += 1
			bbp.bar = new(uint8)
			if len(buf[at:]) < 1 {
				return io.ErrUnexpectedEOF
			}
			(*bbp.bar) = iohelp.ReadUint8Bytes(buf[at:])
			at += 1
		default:
			return nil
		}
	}
}

func (bbp *taggedMessage) MustUnmarshalBebop(buf []byte) {
	at := 0
	_ = iohelp.ReadUint32Bytes(buf[at:])
	buf = buf[4:]
	for {
		switch buf[at] {
		case 1:
			at += 1
			bbp.bar = new(uint8)
			(*bbp.bar) = iohelp.ReadUint8Bytes(buf[at:])
			at += 1
		default:
			return
		}
	}
}

func (bbp taggedMessage) EncodeBebop(iow io.Writer) (err error) {
	w := iohelp.NewErrorWriter(iow)
	iohelp.WriteUint32(w, uint32(bbp.Size()-4))
	if bbp.bar != nil {
		w.Write([]byte{1})
		iohelp.WriteUint8(w, *bbp.bar)
	}
	w.Write([]byte{0})
	return w.Err
}

func (bbp *taggedMessage) DecodeBebop(ior io.Reader) (err error) {
	r := iohelp.NewErrorReader(ior)
	bodyLen := iohelp.ReadUint32(r)
	baseReader := r.Reader
	r.Reader = &io.LimitedReader{R: baseReader, N: int64(bodyLen)}
	for {
		switch iohelp.ReadByte(r) {
		case 1:
			bbp.bar = new(uint8)
			*bbp.bar = iohelp.ReadUint8(r)
		default:
			r.Drain()
			r.Reader = baseReader
			return r.Err
		}
	}
}

func (bbp taggedMessage) Size() int {
	bodyLen := 5
	if bbp.bar != nil {
		bodyLen += 1
		bodyLen += 1
	}
	return bodyLen
}

func (bbp taggedMessage) MarshalBebop() []byte {
	buf := make([]byte, bbp.Size())
	bbp.MarshalBebopTo(buf)
	return buf
}

func maketaggedMessage(r *iohelp.ErrorReader) (taggedMessage, error) {
	v := taggedMessage{}
	err := v.DecodeBebop(r)
	return v, err
}

func maketaggedMessageFromBytes(buf []byte) (taggedMessage, error) {
	v := taggedMessage{}
	err := v.UnmarshalBebop(buf)
	return v, err
}

func mustMaketaggedMessageFromBytes(buf []byte) taggedMessage {
	v := taggedMessage{}
	v.MustUnmarshalBebop(buf)
	return v
}

var _ bebop.Record = &taggedSubStruct{}

type taggedSubStruct struct {
	biz [16]byte `four:"four"`
}

func (bbp taggedSubStruct) MarshalBebopTo(buf []byte) int {
	at := 0
	iohelp.WriteGUIDBytes(buf[at:], bbp.biz)
	at += 16
	return at
}

func (bbp *taggedSubStruct) UnmarshalBebop(buf []byte) (err error) {
	at := 0
	if len(buf[at:]) < 16 {
		return io.ErrUnexpectedEOF
	}
	bbp.biz = iohelp.ReadGUIDBytes(buf[at:])
	at += 16
	return nil
}

func (bbp *taggedSubStruct) MustUnmarshalBebop(buf []byte) {
	at := 0
	bbp.biz = iohelp.ReadGUIDBytes(buf[at:])
	at += 16
}

func (bbp taggedSubStruct) EncodeBebop(iow io.Writer) (err error) {
	w := iohelp.NewErrorWriter(iow)
	iohelp.WriteGUID(w, bbp.biz)
	return w.Err
}

func (bbp *taggedSubStruct) DecodeBebop(ior io.Reader) (err error) {
	r := iohelp.NewErrorReader(ior)
	bbp.biz = iohelp.ReadGUID(r)
	return r.Err
}

func (bbp taggedSubStruct) Size() int {
	bodyLen := 0
	bodyLen += 16
	return bodyLen
}

func (bbp taggedSubStruct) MarshalBebop() []byte {
	buf := make([]byte, bbp.Size())
	bbp.MarshalBebopTo(buf)
	return buf
}

func maketaggedSubStruct(r *iohelp.ErrorReader) (taggedSubStruct, error) {
	v := taggedSubStruct{}
	err := v.DecodeBebop(r)
	return v, err
}

func maketaggedSubStructFromBytes(buf []byte) (taggedSubStruct, error) {
	v := taggedSubStruct{}
	err := v.UnmarshalBebop(buf)
	return v, err
}

func mustMaketaggedSubStructFromBytes(buf []byte) taggedSubStruct {
	v := taggedSubStruct{}
	v.MustUnmarshalBebop(buf)
	return v
}

var _ bebop.Record = &taggedUnion{}

type taggedUnion struct {
	taggedSubStruct *taggedSubStruct `one:"one" two:"two" boolean`
}

func (bbp taggedUnion) MarshalBebopTo(buf []byte) int {
	at := 0
	iohelp.WriteUint32Bytes(buf[at:], uint32(bbp.Size()-5))
	at += 4
	if bbp.taggedSubStruct != nil {
		buf[at] = 1
		at++
		(*bbp.taggedSubStruct).MarshalBebopTo(buf[at:])
		{
			tmp := (*bbp.taggedSubStruct)
			at += tmp.Size()
		}
		
		return at
	}
	return at
}

func (bbp *taggedUnion) UnmarshalBebop(buf []byte) (err error) {
	at := 0
	_ = iohelp.ReadUint32Bytes(buf[at:])
	buf = buf[4:]
	if len(buf) == 0 {
		return iohelp.ErrUnpopulatedUnion
	}
	for {
		switch buf[at] {
		case 1:
			at += 1
			bbp.taggedSubStruct = new(taggedSubStruct)
			(*bbp.taggedSubStruct), err = maketaggedSubStructFromBytes(buf[at:])
			if err != nil {
				return err
			}
			{
				tmp := ((*bbp.taggedSubStruct))
				at += tmp.Size()
			}
			
			return nil
		default:
			return nil
		}
	}
}

func (bbp *taggedUnion) MustUnmarshalBebop(buf []byte) {
	at := 0
	_ = iohelp.ReadUint32Bytes(buf[at:])
	buf = buf[4:]
	for {
		switch buf[at] {
		case 1:
			at += 1
			bbp.taggedSubStruct = new(taggedSubStruct)
			(*bbp.taggedSubStruct) = mustMaketaggedSubStructFromBytes(buf[at:])
			{
				tmp := ((*bbp.taggedSubStruct))
				at += tmp.Size()
			}
			
			return
		default:
			return
		}
	}
}

func (bbp taggedUnion) EncodeBebop(iow io.Writer) (err error) {
	w := iohelp.NewErrorWriter(iow)
	iohelp.WriteUint32(w, uint32(bbp.Size()-5))
	if bbp.taggedSubStruct != nil {
		w.Write([]byte{1})
		err = (*bbp.taggedSubStruct).EncodeBebop(w)
		if err != nil {
			return err
		}
		return w.Err
	}
	return w.Err
}

func (bbp *taggedUnion) DecodeBebop(ior io.Reader) (err error) {
	r := iohelp.NewErrorReader(ior)
	bodyLen := iohelp.ReadUint32(r)
	baseReader := r.Reader
	limitReader := &io.LimitedReader{R: baseReader, N: int64(bodyLen)+1}
	r.Reader = limitReader
	for {
		switch iohelp.ReadByte(r) {
		case 1:
			bbp.taggedSubStruct = new(taggedSubStruct)
			(*bbp.taggedSubStruct), err = maketaggedSubStruct(r)
			if err != nil {
				return err
			}
			r.Drain()
			r.Reader = baseReader
			return r.Err
		default:
			r.Drain()
			r.Reader = baseReader
			return r.Err
		}
	}
}

func (bbp taggedUnion) Size() int {
	bodyLen := 4
	if bbp.taggedSubStruct != nil {
		bodyLen += 1
		{
			tmp := (*bbp.taggedSubStruct)
			bodyLen += tmp.Size()
		}
		
		return bodyLen
	}
	return bodyLen
}

func (bbp taggedUnion) MarshalBebop() []byte {
	buf := make([]byte, bbp.Size())
	bbp.MarshalBebopTo(buf)
	return buf
}

func maketaggedUnion(r *iohelp.ErrorReader) (taggedUnion, error) {
	v := taggedUnion{}
	err := v.DecodeBebop(r)
	return v, err
}

func maketaggedUnionFromBytes(buf []byte) (taggedUnion, error) {
	v := taggedUnion{}
	err := v.UnmarshalBebop(buf)
	return v, err
}

func mustMaketaggedUnionFromBytes(buf []byte) taggedUnion {
	v := taggedUnion{}
	v.MustUnmarshalBebop(buf)
	return v
}

