github.com/go-xe2/third@v1.0.3/golang.org/x/text/unicode/norm/example_iter_test.go (about) 1 // Copyright 2012 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 norm_test 6 7 import ( 8 "bytes" 9 "fmt" 10 "unicode/utf8" 11 12 "github.com/go-xe2/third/golang.org/x/text/unicode/norm" 13 ) 14 15 // EqualSimple uses a norm.Iter to compare two non-normalized 16 // strings for equivalence. 17 func EqualSimple(a, b string) bool { 18 var ia, ib norm.Iter 19 ia.InitString(norm.NFKD, a) 20 ib.InitString(norm.NFKD, b) 21 for !ia.Done() && !ib.Done() { 22 if !bytes.Equal(ia.Next(), ib.Next()) { 23 return false 24 } 25 } 26 return ia.Done() && ib.Done() 27 } 28 29 // FindPrefix finds the longest common prefix of ASCII characters 30 // of a and b. 31 func FindPrefix(a, b string) int { 32 i := 0 33 for ; i < len(a) && i < len(b) && a[i] < utf8.RuneSelf && a[i] == b[i]; i++ { 34 } 35 return i 36 } 37 38 // EqualOpt is like EqualSimple, but optimizes the special 39 // case for ASCII characters. 40 func EqualOpt(a, b string) bool { 41 n := FindPrefix(a, b) 42 a, b = a[n:], b[n:] 43 var ia, ib norm.Iter 44 ia.InitString(norm.NFKD, a) 45 ib.InitString(norm.NFKD, b) 46 for !ia.Done() && !ib.Done() { 47 if !bytes.Equal(ia.Next(), ib.Next()) { 48 return false 49 } 50 if n := int64(FindPrefix(a[ia.Pos():], b[ib.Pos():])); n != 0 { 51 ia.Seek(n, 1) 52 ib.Seek(n, 1) 53 } 54 } 55 return ia.Done() && ib.Done() 56 } 57 58 var compareTests = []struct{ a, b string }{ 59 {"aaa", "aaa"}, 60 {"aaa", "aab"}, 61 {"a\u0300a", "\u00E0a"}, 62 {"a\u0300\u0320b", "a\u0320\u0300b"}, 63 {"\u1E0A\u0323", "\x44\u0323\u0307"}, 64 // A character that decomposes into multiple segments 65 // spans several iterations. 66 {"\u3304", "\u30A4\u30CB\u30F3\u30AF\u3099"}, 67 } 68 69 func ExampleIter() { 70 for i, t := range compareTests { 71 r0 := EqualSimple(t.a, t.b) 72 r1 := EqualOpt(t.a, t.b) 73 fmt.Printf("%d: %v %v\n", i, r0, r1) 74 } 75 // Output: 76 // 0: true true 77 // 1: false false 78 // 2: true true 79 // 3: true true 80 // 4: true true 81 // 5: true true 82 }