1
2
3
4
5 package message
6
7 import (
8 "io"
9 "os"
10
11
12 _ "golang.org/x/text/feature/plural"
13
14 "golang.org/x/text/internal/number"
15 "golang.org/x/text/language"
16 "golang.org/x/text/message/catalog"
17 )
18
19
20
21 type Printer struct {
22
23 tag language.Tag
24
25 toDecimal number.Formatter
26 toScientific number.Formatter
27
28 cat catalog.Catalog
29 }
30
31 type options struct {
32 cat catalog.Catalog
33
34
35
36
37
38 }
39
40
41 type Option func(o *options)
42
43
44 func Catalog(c catalog.Catalog) Option {
45 return func(o *options) { o.cat = c }
46 }
47
48
49 func NewPrinter(t language.Tag, opts ...Option) *Printer {
50 options := &options{
51 cat: DefaultCatalog,
52 }
53 for _, o := range opts {
54 o(options)
55 }
56 p := &Printer{
57 tag: t,
58 cat: options.cat,
59 }
60 p.toDecimal.InitDecimal(t)
61 p.toScientific.InitScientific(t)
62 return p
63 }
64
65
66 func (p *Printer) Sprint(a ...interface{}) string {
67 pp := newPrinter(p)
68 pp.doPrint(a)
69 s := pp.String()
70 pp.free()
71 return s
72 }
73
74
75 func (p *Printer) Fprint(w io.Writer, a ...interface{}) (n int, err error) {
76 pp := newPrinter(p)
77 pp.doPrint(a)
78 n64, err := io.Copy(w, &pp.Buffer)
79 pp.free()
80 return int(n64), err
81 }
82
83
84 func (p *Printer) Print(a ...interface{}) (n int, err error) {
85 return p.Fprint(os.Stdout, a...)
86 }
87
88
89 func (p *Printer) Sprintln(a ...interface{}) string {
90 pp := newPrinter(p)
91 pp.doPrintln(a)
92 s := pp.String()
93 pp.free()
94 return s
95 }
96
97
98 func (p *Printer) Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
99 pp := newPrinter(p)
100 pp.doPrintln(a)
101 n64, err := io.Copy(w, &pp.Buffer)
102 pp.free()
103 return int(n64), err
104 }
105
106
107 func (p *Printer) Println(a ...interface{}) (n int, err error) {
108 return p.Fprintln(os.Stdout, a...)
109 }
110
111
112 func (p *Printer) Sprintf(key Reference, a ...interface{}) string {
113 pp := newPrinter(p)
114 lookupAndFormat(pp, key, a)
115 s := pp.String()
116 pp.free()
117 return s
118 }
119
120
121 func (p *Printer) Fprintf(w io.Writer, key Reference, a ...interface{}) (n int, err error) {
122 pp := newPrinter(p)
123 lookupAndFormat(pp, key, a)
124 n, err = w.Write(pp.Bytes())
125 pp.free()
126 return n, err
127
128 }
129
130
131 func (p *Printer) Printf(key Reference, a ...interface{}) (n int, err error) {
132 pp := newPrinter(p)
133 lookupAndFormat(pp, key, a)
134 n, err = os.Stdout.Write(pp.Bytes())
135 pp.free()
136 return n, err
137 }
138
139 func lookupAndFormat(p *printer, r Reference, a []interface{}) {
140 p.fmt.Reset(a)
141 var id, msg string
142 switch v := r.(type) {
143 case string:
144 id, msg = v, v
145 case key:
146 id, msg = v.id, v.fallback
147 default:
148 panic("key argument is not a Reference")
149 }
150
151 if p.catContext.Execute(id) == catalog.ErrNotFound {
152 if p.catContext.Execute(msg) == catalog.ErrNotFound {
153 p.Render(msg)
154 return
155 }
156 }
157 }
158
159 type rawPrinter struct {
160 p *printer
161 }
162
163 func (p rawPrinter) Render(msg string) { p.p.WriteString(msg) }
164 func (p rawPrinter) Arg(i int) interface{} { return nil }
165
166
167 func (p *printer) Arg(i int) interface{} {
168 i--
169 if uint(i) < uint(len(p.fmt.Args)) {
170 return p.fmt.Args[i]
171 }
172 return nil
173 }
174
175
176 func (p *printer) Render(msg string) {
177 p.doPrintf(msg)
178 }
179
180
181 type Reference interface {
182
183 }
184
185
186
187 func Key(id string, fallback string) Reference {
188 return key{id, fallback}
189 }
190
191 type key struct {
192 id, fallback string
193 }
194
View as plain text