diff options
Diffstat (limited to 'vendor/golang.org/x/text/message/message.go')
-rw-r--r-- | vendor/golang.org/x/text/message/message.go | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/vendor/golang.org/x/text/message/message.go b/vendor/golang.org/x/text/message/message.go new file mode 100644 index 0000000..ba4f95a --- /dev/null +++ b/vendor/golang.org/x/text/message/message.go @@ -0,0 +1,169 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package message // import "golang.org/x/text/message" + +import ( + "io" + "os" + + "golang.org/x/text/language" + "golang.org/x/text/message/catalog" +) + +// TODO: allow more than one goroutine per printer. This will allow porting from +// fmt much less error prone. + +// A Printer implements language-specific formatted I/O analogous to the fmt +// package. Only one goroutine may use a Printer at the same time. +type Printer struct { + // Wrap the fields in a hidden type to hide some of the implemented methods. + printer printer + + // NOTE: limiting one goroutine per Printer allows for many optimizations + // and simplifications. We can consider removing this restriction down the + // road if it the benefits do not seem to outweigh the disadvantages. +} + +type options struct { + cat *catalog.Catalog + // TODO: + // - allow %s to print integers in written form (tables are likely too large + // to enable this by default). + // - list behavior + // +} + +// An Option defines an option of a Printer. +type Option func(o *options) + +// Catalog defines the catalog to be used. +func Catalog(c *catalog.Catalog) Option { + return func(o *options) { o.cat = c } +} + +// NewPrinter returns a Printer that formats messages tailored to language t. +func NewPrinter(t language.Tag, opts ...Option) *Printer { + options := &options{ + cat: defaultCatalog, + } + for _, o := range opts { + o(options) + } + p := &Printer{printer{ + tag: t, + }} + p.printer.toDecimal.InitDecimal(t) + p.printer.toScientific.InitScientific(t) + p.printer.catContext = options.cat.Context(t, &p.printer) + return p +} + +// Sprint is like fmt.Sprint, but using language-specific formatting. +func (p *Printer) Sprint(a ...interface{}) string { + p.printer.reset() + p.printer.doPrint(a) + return p.printer.String() +} + +// Fprint is like fmt.Fprint, but using language-specific formatting. +func (p *Printer) Fprint(w io.Writer, a ...interface{}) (n int, err error) { + p.printer.reset() + p.printer.doPrint(a) + n64, err := io.Copy(w, &p.printer.Buffer) + return int(n64), err +} + +// Print is like fmt.Print, but using language-specific formatting. +func (p *Printer) Print(a ...interface{}) (n int, err error) { + return p.Fprint(os.Stdout, a...) +} + +// Sprintln is like fmt.Sprintln, but using language-specific formatting. +func (p *Printer) Sprintln(a ...interface{}) string { + p.printer.reset() + p.printer.doPrintln(a) + return p.printer.String() +} + +// Fprintln is like fmt.Fprintln, but using language-specific formatting. +func (p *Printer) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { + p.printer.reset() + p.printer.doPrintln(a) + n64, err := io.Copy(w, &p.printer.Buffer) + return int(n64), err +} + +// Println is like fmt.Println, but using language-specific formatting. +func (p *Printer) Println(a ...interface{}) (n int, err error) { + return p.Fprintln(os.Stdout, a...) +} + +// Sprintf is like fmt.Sprintf, but using language-specific formatting. +func (p *Printer) Sprintf(key Reference, a ...interface{}) string { + lookupAndFormat(p, key, a) + return p.printer.String() +} + +// Fprintf is like fmt.Fprintf, but using language-specific formatting. +func (p *Printer) Fprintf(w io.Writer, key Reference, a ...interface{}) (n int, err error) { + lookupAndFormat(p, key, a) + return w.Write(p.printer.Bytes()) +} + +// Printf is like fmt.Printf, but using language-specific formatting. +func (p *Printer) Printf(key Reference, a ...interface{}) (n int, err error) { + lookupAndFormat(p, key, a) + return os.Stdout.Write(p.printer.Bytes()) +} + +func lookupAndFormat(p *Printer, r Reference, a []interface{}) { + p.printer.reset() + p.printer.args = a + var id, msg string + switch v := r.(type) { + case string: + id, msg = v, v + case key: + id, msg = v.id, v.fallback + default: + panic("key argument is not a Reference") + } + + if p.printer.catContext.Execute(id) == catalog.ErrNotFound { + if p.printer.catContext.Execute(msg) == catalog.ErrNotFound { + p.printer.Render(msg) + return + } + } +} + +// Arg implements catmsg.Renderer. +func (p *printer) Arg(i int) interface{} { // TODO, also return "ok" bool + i-- + if uint(i) < uint(len(p.args)) { + return p.args[i] + } + return nil +} + +// Render implements catmsg.Renderer. +func (p *printer) Render(msg string) { + p.doPrintf(msg) +} + +// A Reference is a string or a message reference. +type Reference interface { + // TODO: also allow []string +} + +// Key creates a message Reference for a message where the given id is used for +// message lookup and the fallback is returned when no matches are found. +func Key(id string, fallback string) Reference { + return key{id, fallback} +} + +type key struct { + id, fallback string +} |