summaryrefslogtreecommitdiff
path: root/go/beer-song/beer.go
blob: fe2dfe22b3355d4418f42643968e2c5f2414c365 (plain)
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
package beer

import (
	"bytes"
	"errors"
	"text/template"
)

const lyrics = `{{define "verse" -}}
{{template "Plural" .N}} of beer on the wall, {{template "plural" .N}} of beer.
{{if eq .N 0}}Go to the store and buy some more
{{- else}}Take {{if eq .N 1}}it{{else}}one{{end}} down and pass it around
{{- end}}, {{template "plural" .M}} of beer on the wall.
{{end}}

{{define "plural"}}{{if eq . 0}}no more{{else}}{{.}}
{{- end}} bottle{{if ne . 1}}s{{end}}{{end}}

{{define "Plural"}}{{if eq . 0}}No more{{else}}{{.}}
{{- end}} bottle{{if ne . 1}}s{{end}}{{end}}`

var tmpl = template.Must(template.New("song").Parse(lyrics))

type Bottles struct {
	N, M int
}

func Verse(n int) (string, error) {
	if n < 0 || n > 99 {
		return "", errors.New("Go home, you're drunk")
	}
	buf := &bytes.Buffer{}
	err := tmpl.ExecuteTemplate(buf, "verse", Bottles{n, (100 + n - 1) % 100})
	return buf.String(), err
}

func Verses(from, to int) (string, error) {
	if from <= to {
		return "", errors.New("Wrong order")
	}
	var s string
	for i := from; i >= to; i-- {
		v, err := Verse(i)
		if err != nil {
			return "", err
		}
		s += v + "\n"
	}
	return s, nil
}

func Song() string {
	s, err := Verses(99, 0)
	if err != nil {
		panic(err)
	}
	return s
}