// The LowerCase option defines a Profile's case mapping rule. Options can be // provided to determine the type of case folding used. func LowerCase(opts ...cases.Option) Option { return func(o *options) { if len(opts) == 0 { o.cases = cases.Lower(language.Und, cases.HandleFinalSigma(false)) return } opts = append([]cases.Option{cases.HandleFinalSigma(false)}, opts...) o.cases = cases.Lower(language.Und, opts...) } }
} x := b.next & 1 if b.buf[x] == nil { b.buf[x] = make([]byte, 0, 8+len(b.src)+len(b.src)>>2) } span := append(b.buf[x][:0], b.src[:n]...) b.src, _, err = transform.Append(t, span, b.src[n:]) b.buf[x] = b.src b.next++ return err } // Pre-allocate transformers when possible. In some cases this avoids allocation. var ( foldWidthT transform.SpanningTransformer = width.Fold lowerCaseT transform.SpanningTransformer = cases.Lower(language.Und, cases.HandleFinalSigma(false)) ) // TODO: make this a method on profile. func (b *buffers) enforce(p *Profile, src []byte, comparing bool) (str []byte, err error) { b.src = src ascii := true for _, c := range src { if c >= utf8.RuneSelf { ascii = false break } } // ASCII fast path.
func (b *buffers) enforce(p *Profile, src []byte, comparing bool) (str []byte, err error) { b.src = src // These transforms are applied in the order defined in // https://tools.ietf.org/html/rfc7564#section-7 // TODO: allow different width transforms options. if p.options.foldWidth || (p.options.ignorecase && comparing) { // TODO: use Span, once available. if err = b.apply(width.Fold); err != nil { return nil, err } } for _, f := range p.options.additional { if err = b.apply(f()); err != nil { return nil, err } } if p.options.cases != nil { if err = b.apply(p.options.cases); err != nil { return nil, err } } if comparing && p.options.ignorecase { if err = b.apply(cases.Lower(language.Und, cases.HandleFinalSigma(false))); err != nil { return nil, err } } if n := p.norm.QuickSpan(b.src); n < len(b.src) { x := b.next & 1 n = copy(b.buf[x], b.src[:n]) b.src, _, err = transform.Append(p.norm, b.buf[x][:n], b.src[n:]) b.buf[x] = b.src b.next++ if err != nil { return nil, err } } if p.options.bidiRule { if err := b.apply(bidirule.New()); err != nil { return nil, err } } c := checker{p: p} if _, err := c.span(b.src, true); err != nil { return nil, err } if p.disallow != nil { for i := 0; i < len(b.src); { r, size := utf8.DecodeRune(b.src[i:]) if p.disallow.Contains(r) { return nil, errDisallowedRune } i += size } } // TODO: Add the disallow empty rule with a dummy transformer? if p.options.disallowEmpty && len(b.src) == 0 { return nil, errEmptyString } return b.src, nil }