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

package generated

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

var _ bebop.Record = &a{}

type a struct {
	b *uint32
}

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

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

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

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

func (bbp *a) 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.b = new(uint32)
			*bbp.b = iohelp.ReadUint32(r)
		default:
			r.Drain()
			r.Reader = baseReader
			return r.Err
		}
	}
}

func (bbp a) Size() int {
	bodyLen := 5
	if bbp.b != nil {
		bodyLen += 1
		bodyLen += 4
	}
	return bodyLen
}

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

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

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

func mustMakeaFromBytes(buf []byte) a {
	v := a{}
	v.MustUnmarshalBebop(buf)
	return v
}

var _ bebop.Record = &b{}

//*
//     * This branch is, too!
//     
type b struct {
	c bool
}

func (bbp b) MarshalBebopTo(buf []byte) int {
	at := 0
	iohelp.WriteBoolBytes(buf[at:], bbp.c)
	at += 1
	return at
}

func (bbp *b) UnmarshalBebop(buf []byte) (err error) {
	at := 0
	if len(buf[at:]) < 1 {
		return io.ErrUnexpectedEOF
	}
	bbp.c = iohelp.ReadBoolBytes(buf[at:])
	at += 1
	return nil
}

func (bbp *b) MustUnmarshalBebop(buf []byte) {
	at := 0
	bbp.c = iohelp.ReadBoolBytes(buf[at:])
	at += 1
}

func (bbp b) EncodeBebop(iow io.Writer) (err error) {
	w := iohelp.NewErrorWriter(iow)
	iohelp.WriteBool(w, bbp.c)
	return w.Err
}

func (bbp *b) DecodeBebop(ior io.Reader) (err error) {
	r := iohelp.NewErrorReader(ior)
	bbp.c = iohelp.ReadBool(r)
	return r.Err
}

func (bbp b) Size() int {
	bodyLen := 0
	bodyLen += 1
	return bodyLen
}

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

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

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

func mustMakebFromBytes(buf []byte) b {
	v := b{}
	v.MustUnmarshalBebop(buf)
	return v
}

var _ bebop.Record = &c{}

type c struct {
}

func (bbp c) MarshalBebopTo(buf []byte) int {
	return 0
}

func (bbp *c) UnmarshalBebop(buf []byte) (err error) {
	return nil
}

func (bbp *c) MustUnmarshalBebop(buf []byte) {
}

func (bbp c) EncodeBebop(iow io.Writer) (err error) {
	return nil
}

func (bbp *c) DecodeBebop(ior io.Reader) (err error) {
	return nil
}

func (bbp c) Size() int {
	return 0
}

func (bbp c) MarshalBebop() []byte {
	return []byte{}
}

func makec(r *iohelp.ErrorReader) (c, error) {
	return c{}, nil
}

func makecFromBytes(buf []byte) (c, error) {
	return c{}, nil
}

func mustMakecFromBytes(buf []byte) c {
	return c{}
}

const uOpCode = 0x68616579

var _ bebop.Record = &u{}

//*
// * This union is so documented!
// 
type u struct {
	a *a
	b *b
	c *c
}

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

func (bbp *u) 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.a = new(a)
			(*bbp.a), err = makeaFromBytes(buf[at:])
			if err != nil {
				return err
			}
			{
				tmp := ((*bbp.a))
				at += tmp.Size()
			}
			
			return nil
		case 2:
			at += 1
			bbp.b = new(b)
			(*bbp.b), err = makebFromBytes(buf[at:])
			if err != nil {
				return err
			}
			{
				tmp := ((*bbp.b))
				at += tmp.Size()
			}
			
			return nil
		case 3:
			at += 1
			bbp.c = new(c)
			(*bbp.c), err = makecFromBytes(buf[at:])
			if err != nil {
				return err
			}
			{
				tmp := ((*bbp.c))
				at += tmp.Size()
			}
			
			return nil
		default:
			return nil
		}
	}
}

func (bbp *u) MustUnmarshalBebop(buf []byte) {
	at := 0
	_ = iohelp.ReadUint32Bytes(buf[at:])
	buf = buf[4:]
	for {
		switch buf[at] {
		case 1:
			at += 1
			bbp.a = new(a)
			(*bbp.a) = mustMakeaFromBytes(buf[at:])
			{
				tmp := ((*bbp.a))
				at += tmp.Size()
			}
			
			return
		case 2:
			at += 1
			bbp.b = new(b)
			(*bbp.b) = mustMakebFromBytes(buf[at:])
			{
				tmp := ((*bbp.b))
				at += tmp.Size()
			}
			
			return
		case 3:
			at += 1
			bbp.c = new(c)
			(*bbp.c) = mustMakecFromBytes(buf[at:])
			{
				tmp := ((*bbp.c))
				at += tmp.Size()
			}
			
			return
		default:
			return
		}
	}
}

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

func (bbp *u) 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.a = new(a)
			(*bbp.a), err = makea(r)
			if err != nil {
				return err
			}
			r.Drain()
			r.Reader = baseReader
			return r.Err
		case 2:
			bbp.b = new(b)
			(*bbp.b), err = makeb(r)
			if err != nil {
				return err
			}
			r.Drain()
			r.Reader = baseReader
			return r.Err
		case 3:
			bbp.c = new(c)
			(*bbp.c), err = makec(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 u) Size() int {
	bodyLen := 4
	if bbp.a != nil {
		bodyLen += 1
		{
			tmp := (*bbp.a)
			bodyLen += tmp.Size()
		}
		
		return bodyLen
	}
	if bbp.b != nil {
		bodyLen += 1
		{
			tmp := (*bbp.b)
			bodyLen += tmp.Size()
		}
		
		return bodyLen
	}
	if bbp.c != nil {
		bodyLen += 1
		{
			tmp := (*bbp.c)
			bodyLen += tmp.Size()
		}
		
		return bodyLen
	}
	return bodyLen
}

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

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

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

func mustMakeuFromBytes(buf []byte) u {
	v := u{}
	v.MustUnmarshalBebop(buf)
	return v
}

var _ bebop.Record = &cons{}

type cons struct {
	head uint32
	tail list
}

func (bbp cons) MarshalBebopTo(buf []byte) int {
	at := 0
	iohelp.WriteUint32Bytes(buf[at:], bbp.head)
	at += 4
	(bbp.tail).MarshalBebopTo(buf[at:])
	{
		tmp := (bbp.tail)
		at += tmp.Size()
	}
	
	return at
}

func (bbp *cons) UnmarshalBebop(buf []byte) (err error) {
	at := 0
	if len(buf[at:]) < 4 {
		return io.ErrUnexpectedEOF
	}
	bbp.head = iohelp.ReadUint32Bytes(buf[at:])
	at += 4
	bbp.tail, err = makelistFromBytes(buf[at:])
	if err != nil {
		return err
	}
	{
		tmp := (bbp.tail)
		at += tmp.Size()
	}
	
	return nil
}

func (bbp *cons) MustUnmarshalBebop(buf []byte) {
	at := 0
	bbp.head = iohelp.ReadUint32Bytes(buf[at:])
	at += 4
	bbp.tail = mustMakelistFromBytes(buf[at:])
	{
		tmp := (bbp.tail)
		at += tmp.Size()
	}
	
}

func (bbp cons) EncodeBebop(iow io.Writer) (err error) {
	w := iohelp.NewErrorWriter(iow)
	iohelp.WriteUint32(w, bbp.head)
	err = (bbp.tail).EncodeBebop(w)
	if err != nil {
		return err
	}
	return w.Err
}

func (bbp *cons) DecodeBebop(ior io.Reader) (err error) {
	r := iohelp.NewErrorReader(ior)
	bbp.head = iohelp.ReadUint32(r)
	(bbp.tail), err = makelist(r)
	if err != nil {
		return err
	}
	return r.Err
}

func (bbp cons) Size() int {
	bodyLen := 0
	bodyLen += 4
	{
		tmp := (bbp.tail)
		bodyLen += tmp.Size()
	}
	
	return bodyLen
}

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

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

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

func mustMakeconsFromBytes(buf []byte) cons {
	v := cons{}
	v.MustUnmarshalBebop(buf)
	return v
}

var _ bebop.Record = &null{}

// nil is empty
type null struct {
}

func (bbp null) MarshalBebopTo(buf []byte) int {
	return 0
}

func (bbp *null) UnmarshalBebop(buf []byte) (err error) {
	return nil
}

func (bbp *null) MustUnmarshalBebop(buf []byte) {
}

func (bbp null) EncodeBebop(iow io.Writer) (err error) {
	return nil
}

func (bbp *null) DecodeBebop(ior io.Reader) (err error) {
	return nil
}

func (bbp null) Size() int {
	return 0
}

func (bbp null) MarshalBebop() []byte {
	return []byte{}
}

func makenull(r *iohelp.ErrorReader) (null, error) {
	return null{}, nil
}

func makenullFromBytes(buf []byte) (null, error) {
	return null{}, nil
}

func mustMakenullFromBytes(buf []byte) null {
	return null{}
}

var _ bebop.Record = &list{}

type list struct {
	cons *cons
	null *null
}

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

func (bbp *list) 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.cons = new(cons)
			(*bbp.cons), err = makeconsFromBytes(buf[at:])
			if err != nil {
				return err
			}
			{
				tmp := ((*bbp.cons))
				at += tmp.Size()
			}
			
			return nil
		case 2:
			at += 1
			bbp.null = new(null)
			(*bbp.null), err = makenullFromBytes(buf[at:])
			if err != nil {
				return err
			}
			{
				tmp := ((*bbp.null))
				at += tmp.Size()
			}
			
			return nil
		default:
			return nil
		}
	}
}

func (bbp *list) MustUnmarshalBebop(buf []byte) {
	at := 0
	_ = iohelp.ReadUint32Bytes(buf[at:])
	buf = buf[4:]
	for {
		switch buf[at] {
		case 1:
			at += 1
			bbp.cons = new(cons)
			(*bbp.cons) = mustMakeconsFromBytes(buf[at:])
			{
				tmp := ((*bbp.cons))
				at += tmp.Size()
			}
			
			return
		case 2:
			at += 1
			bbp.null = new(null)
			(*bbp.null) = mustMakenullFromBytes(buf[at:])
			{
				tmp := ((*bbp.null))
				at += tmp.Size()
			}
			
			return
		default:
			return
		}
	}
}

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

func (bbp *list) 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.cons = new(cons)
			(*bbp.cons), err = makecons(r)
			if err != nil {
				return err
			}
			r.Drain()
			r.Reader = baseReader
			return r.Err
		case 2:
			bbp.null = new(null)
			(*bbp.null), err = makenull(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 list) Size() int {
	bodyLen := 4
	if bbp.cons != nil {
		bodyLen += 1
		{
			tmp := (*bbp.cons)
			bodyLen += tmp.Size()
		}
		
		return bodyLen
	}
	if bbp.null != nil {
		bodyLen += 1
		{
			tmp := (*bbp.null)
			bodyLen += tmp.Size()
		}
		
		return bodyLen
	}
	return bodyLen
}

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

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

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

func mustMakelistFromBytes(buf []byte) list {
	v := list{}
	v.MustUnmarshalBebop(buf)
	return v
}

