github.com/seeker-insurance/kit@v0.0.13/pretty/text/cmd/agg/string.go (about) 1 package main 2 3 import ( 4 "math/rand" 5 "strings" 6 ) 7 8 func first(s, arg string) agg { return &sbinop{s, opfirst} } 9 func last(s, arg string) agg { return &sbinop{s, oplast} } 10 func prefix(s, arg string) agg { return &sbinop{s, opprefix} } 11 func join(s, arg string) agg { return &sbinop{s, opjoin(arg)} } 12 func smin(s, arg string) agg { return &sbinop{s, opsmin} } 13 func smax(s, arg string) agg { return &sbinop{s, opsmax} } 14 15 type sbinop struct { 16 s string 17 f func(a, b string) string 18 } 19 20 func (o *sbinop) String() string { return o.s } 21 22 func (o *sbinop) merge(s string) { o.s = o.f(o.s, s) } 23 24 func opfirst(a, b string) string { return a } 25 func oplast(a, b string) string { return b } 26 27 func opprefix(a, b string) string { 28 for i := range a { 29 if i >= len(b) || a[i] != b[i] { 30 return a[:i] 31 } 32 } 33 return a 34 } 35 36 func opjoin(sep string) func(a, b string) string { 37 return func(a, b string) string { 38 return a + sep + b // TODO(kr): too slow? maybe strings.Join? 39 } 40 } 41 42 func opsmin(a, b string) string { 43 if strings.Compare(a, b) <= 0 { 44 return a 45 } 46 return b 47 } 48 49 func opsmax(a, b string) string { 50 if strings.Compare(a, b) >= 0 { 51 return a 52 } 53 return b 54 } 55 56 type sampler struct { 57 n int 58 s string 59 } 60 61 func sample(s, arg string) agg { return &sampler{1, s} } 62 func (p *sampler) String() string { return p.s } 63 func (p *sampler) merge(s string) { 64 p.n++ 65 if rand.Intn(p.n) == 0 { 66 p.s = s 67 } 68 } 69 70 type constant string 71 72 func constf(init, arg string) agg { return constant(arg) } 73 func (c constant) String() string { return string(c) } 74 func (c constant) merge(string) {}