Codebase list golang-github-rainycape-unidecode / run/918931da-af35-4512-962f-63db5957145e/main unidecode.go
run/918931da-af35-4512-962f-63db5957145e/main

Tree @run/918931da-af35-4512-962f-63db5957145e/main (Download .tar.gz)

unidecode.go @run/918931da-af35-4512-962f-63db5957145e/mainraw · history · blame

// Package unidecode implements a unicode transliterator
// which replaces non-ASCII characters with their ASCII
// approximations.
package unidecode

import (
	"sync"
	"unicode"
)

const pooledCapacity = 64

var (
	slicePool    sync.Pool
	decodingOnce sync.Once
)

// Unidecode implements a unicode transliterator, which
// replaces non-ASCII characters with their ASCII
// counterparts.
// Given an unicode encoded string, returns
// another string with non-ASCII characters replaced
// with their closest ASCII counterparts.
// e.g. Unicode("áéíóú") => "aeiou"
func Unidecode(s string) string {
	decodingOnce.Do(decodeTransliterations)
	l := len(s)
	var r []rune
	if l > pooledCapacity {
		r = make([]rune, 0, len(s))
	} else {
		if x := slicePool.Get(); x != nil {
			r = x.([]rune)[:0]
		} else {
			r = make([]rune, 0, pooledCapacity)
		}
	}
	for _, c := range s {
		if c <= unicode.MaxASCII {
			r = append(r, c)
			continue
		}
		if c > unicode.MaxRune || c > transCount {
			/* Ignore reserved chars */
			continue
		}
		if d := transliterations[c]; d != nil {
			r = append(r, d...)
		}
	}
	res := string(r)
	if l <= pooledCapacity {
		slicePool.Put(r)
	}
	return res
}