letters.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. package transformers
  2. import (
  3. "unicode"
  4. "unicode/utf8"
  5. "golang.org/x/text/transform"
  6. )
  7. func Replace(f func(r rune) []rune) transform.Transformer {
  8. return replaceF(f)
  9. }
  10. const runeErrorString = string(utf8.RuneError)
  11. type replaceF func(r rune) []rune
  12. func (replaceF) Reset() {}
  13. func (t replaceF) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
  14. for nSrc < len(src) {
  15. r, _ := utf8.DecodeRune(src[nSrc:])
  16. if r == utf8.RuneError {
  17. if !atEOF && !utf8.FullRune(src[nSrc:]) {
  18. err = transform.ErrShortSrc
  19. break
  20. }
  21. if nDst+3 > len(dst) {
  22. err = transform.ErrShortDst
  23. break
  24. }
  25. dst[nDst+0] = runeErrorString[0]
  26. dst[nDst+1] = runeErrorString[1]
  27. dst[nDst+2] = runeErrorString[2]
  28. nSrc++
  29. continue
  30. }
  31. replacement := t(r)
  32. size := 0
  33. for _, r2 := range replacement {
  34. r2b := []byte(string(r2))
  35. size += len(r2b)
  36. }
  37. if nDst+size > len(dst) {
  38. err = transform.ErrShortDst
  39. break
  40. }
  41. for _, r2 := range replacement {
  42. r2b := []byte(string(r2))
  43. s := len(r2b)
  44. for i := 0; i < s; i++ {
  45. dst[nDst] = r2b[i]
  46. nDst++
  47. }
  48. nSrc++
  49. }
  50. }
  51. return
  52. }
  53. type Replacer interface {
  54. Replace(r rune) []rune
  55. }
  56. func IsNonAlphanum(r rune) bool {
  57. return !(unicode.IsLetter(r) || unicode.IsDigit(r))
  58. }