9 type Inv []NamedInvList
11 type NamedInvList struct {
16 func (inv Inv) List(name string) *NamedInvList {
17 for i, l := range inv {
25 func (i Inv) Serialize(w io.Writer) error {
27 if _, err := fmt.Fprintln(w, "List", l.Name, len(l.Stacks)); err != nil {
30 if err := l.Serialize(w); err != nil {
34 _, err := fmt.Fprintln(w, "EndInventory")
38 func (i *Inv) Deserialize(r io.Reader) (err error) {
46 if err := readCmdLn(r, map[string]interface{}{
47 "List": func(name string, size int) {
50 l = &NamedInvList{Name: name}
53 if err := l.Deserialize(r); err != nil {
54 s.ret(fmt.Errorf("List %s %d: %w", name, size, err))
56 if len(l.Stacks) != size {
57 s.ret(fmt.Errorf("List %s %d: contains %d stacks", name, size, len(l.Stacks)))
62 "KeepList": func(name string) {
65 s.ret(fmt.Errorf("KeepList %s: list does not exist", name))
70 "EndInventory": func() {
75 s.ret(io.ErrUnexpectedEOF)
87 func (l InvList) Serialize(w io.Writer) error {
88 if _, err := fmt.Fprintln(w, "Width", l.Width); err != nil {
91 for _, i := range l.Stacks {
93 if _, err := fmt.Fprintln(w, "Item", i); err != nil {
97 if _, err := fmt.Fprintln(w, "Empty"); err != nil {
102 _, err := fmt.Fprintln(w, "EndInventoryList")
106 func (i *InvList) Deserialize(r io.Reader) (err error) {
108 defer s.recover(&err)
110 if _, err := fmt.Fscanf(r, "Width %d\n", &i.Width); err != nil {
114 i.Stacks = i.Stacks[:0]
117 if err := readCmdLn(r, map[string]interface{}{
119 i.Stacks = append(i.Stacks, Stack{})
121 "Item": func(stk Stack) {
122 i.Stacks = append(i.Stacks, stk)
125 if len(i.Stacks) < cap(i.Stacks) {
126 i.Stacks = i.Stacks[:len(i.Stacks)+1]
128 i.Stacks = append(i.Stacks, Stack{})
131 "EndInventoryList": func() {
136 s.ret(io.ErrUnexpectedEOF)
143 func readCmdLn(r io.Reader, cmds map[string]interface{}) error {
144 if _, ok := r.(io.RuneScanner); !ok {
145 r = &readRune{Reader: r, peekRune: -1}
149 if _, err := fmt.Fscan(r, &cmd); err != nil {
155 return fmt.Errorf("unsupported line type: %+q", cmd)
158 t := reflect.TypeOf(f)
160 a := make([]interface{}, t.NumIn())
162 a[i] = reflect.New(t.In(i)).Interface()
166 args := make([]reflect.Value, t.NumIn())
167 for i := range args {
168 args[i] = reflect.ValueOf(a[i]).Elem()
170 reflect.ValueOf(f).Call(args)
175 type sentinal struct {
179 func (s *sentinal) ret(err error) {
184 func (s *sentinal) recover(p *error) {
185 if r := recover(); r == s {