github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/vendor_skip/golang.org/x/text/message/message.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package message // import "golang.org/x/text/message" 6 7 import ( 8 "io" 9 "os" 10 11 // Include features to facilitate generated catalogs. 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 // A Printer implements language-specific formatted I/O analogous to the fmt 20 // package. 21 type Printer struct { 22 // the language 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 // TODO: 34 // - allow %s to print integers in written form (tables are likely too large 35 // to enable this by default). 36 // - list behavior 37 // 38 } 39 40 // An Option defines an option of a Printer. 41 type Option func(o *options) 42 43 // Catalog defines the catalog to be used. 44 func Catalog(c catalog.Catalog) Option { 45 return func(o *options) { o.cat = c } 46 } 47 48 // NewPrinter returns a Printer that formats messages tailored to language t. 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 // Sprint is like fmt.Sprint, but using language-specific formatting. 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 // Fprint is like fmt.Fprint, but using language-specific formatting. 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 // Print is like fmt.Print, but using language-specific formatting. 84 func (p *Printer) Print(a ...interface{}) (n int, err error) { 85 return p.Fprint(os.Stdout, a...) 86 } 87 88 // Sprintln is like fmt.Sprintln, but using language-specific formatting. 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 // Fprintln is like fmt.Fprintln, but using language-specific formatting. 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 // Println is like fmt.Println, but using language-specific formatting. 107 func (p *Printer) Println(a ...interface{}) (n int, err error) { 108 return p.Fprintln(os.Stdout, a...) 109 } 110 111 // Sprintf is like fmt.Sprintf, but using language-specific formatting. 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 // Fprintf is like fmt.Fprintf, but using language-specific formatting. 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 // Printf is like fmt.Printf, but using language-specific formatting. 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 // Arg implements catmsg.Renderer. 167 func (p *printer) Arg(i int) interface{} { // TODO, also return "ok" bool 168 i-- 169 if uint(i) < uint(len(p.fmt.Args)) { 170 return p.fmt.Args[i] 171 } 172 return nil 173 } 174 175 // Render implements catmsg.Renderer. 176 func (p *printer) Render(msg string) { 177 p.doPrintf(msg) 178 } 179 180 // A Reference is a string or a message reference. 181 type Reference interface { 182 // TODO: also allow []string 183 } 184 185 // Key creates a message Reference for a message where the given id is used for 186 // message lookup and the fallback is returned when no matches are found. 187 func Key(id string, fallback string) Reference { 188 return key{id, fallback} 189 } 190 191 type key struct { 192 id, fallback string 193 }