-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclosures.go
97 lines (83 loc) · 2.27 KB
/
closures.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package main
import (
"bufio"
"fmt"
"io"
"time"
)
func main() {
fmt.Println(addPng("test"))
}
func addPng(name string) string {
return name + ".png"
}
// this program takes an Invoice and writes it into a text file.
type Invoice struct {
Id int
CustomerId int
Raised time.Time
Due time.Time
Paid bool
Note string
Items []*Item
}
type Item struct {
Id string
Price float64
Quantity int
Note string
}
//make it easy to use a reader or writer for a specifc format in a generic way
type InvoiceMarshaler interface {
MarshalInvoices(writer io.Writer, invoices []*Invoice) error
}
type TxtMarshaler struct{}
func (TxtMarshaler) MarshalInvoices(writer io.Writer, invoices []*Invoice) error {
bufferedWriter := bufio.NewWriter(writer)
defer bufferedWriter.Flush()
// closure: defined as an anonymous function. Has access to bufferedWriter
var write writerFunc = func(format string, args ...interface{}) error {
_, err := fmt.Fprintf(bufferedWriter, format, args...)
return err
}
if err := write("%s %d\n", fileType, fileVersion); err != nil {
return err
}
//iterate over every invoice and call writeInvoice method on each
for _, invoice := range invoices {
if err := write.writeInvoice(invoice); err != nil {
return err
}
}
return nil
}
type writerFunc func(string, ...interface{}) error
// writeInvoice is a method of the write() function b/c we gave the write() function the type writerFunc
func (write writerFunc) writeInvoice(invoice *Invoice) error {
note := ""
if invoice.Note != "" {
note = ": " + invoice.Note
}
// %t used for Boolean
if err := write("INVOICE ID=%d CUSTOMER=%d RAISED=%s DUE=%s PAID=%t%s\n", invoice.Id, invoice.CustoemrId, invoice.Raised.Format(dateFormat),
invoice.Due.Format(dateFormat), invoice.Paid, note); error != nil {
return err
}
// call writeItems on the items in the invoice
if err := write.writeItems(invoice.Items); err != nil {
return err
}
return write("\f\n")
}
func (write writerFunc) writeItems(items []*Item) error {
for _, item := range items {
note := ""
if item.Note != "" {
note = ": " + item.Note
}
if err := write("ITEM ID=%s PRICE=%.2f QUANTITY=%d%s\n", item.Id, item.Price, item.Quantity, note); err != nil {
return err
}
}
return nil
}