Remove usage of gob
This commit is contained in:
parent
7af07d2ba5
commit
7911f2a8a9
10 changed files with 34 additions and 303 deletions
45
domain.go
45
domain.go
|
@ -2,7 +2,6 @@ package gotext
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"sort"
|
||||
|
@ -684,47 +683,3 @@ func EscapeSpecialCharacters(s string) string {
|
|||
}
|
||||
return strings.Join(data, "\n")
|
||||
}
|
||||
|
||||
// MarshalBinary implements encoding.BinaryMarshaler interface
|
||||
func (do *Domain) MarshalBinary() ([]byte, error) {
|
||||
obj := new(TranslatorEncoding)
|
||||
obj.Headers = do.Headers
|
||||
obj.Language = do.Language
|
||||
obj.PluralForms = do.PluralForms
|
||||
obj.Nplurals = do.nplurals
|
||||
obj.Plural = do.plural
|
||||
obj.Translations = do.translations
|
||||
obj.Contexts = do.contextTranslations
|
||||
|
||||
var buff bytes.Buffer
|
||||
encoder := gob.NewEncoder(&buff)
|
||||
err := encoder.Encode(obj)
|
||||
|
||||
return buff.Bytes(), err
|
||||
}
|
||||
|
||||
// UnmarshalBinary implements encoding.BinaryUnmarshaler interface
|
||||
func (do *Domain) UnmarshalBinary(data []byte) error {
|
||||
buff := bytes.NewBuffer(data)
|
||||
obj := new(TranslatorEncoding)
|
||||
|
||||
decoder := gob.NewDecoder(buff)
|
||||
err := decoder.Decode(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
do.Headers = obj.Headers
|
||||
do.Language = obj.Language
|
||||
do.PluralForms = obj.PluralForms
|
||||
do.nplurals = obj.Nplurals
|
||||
do.plural = obj.Plural
|
||||
do.translations = obj.Translations
|
||||
do.contextTranslations = obj.Contexts
|
||||
|
||||
if expr, err := plurals.Compile(do.plural); err == nil {
|
||||
do.pluralforms = expr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -9,37 +9,6 @@ const (
|
|||
arFixture = "fixtures/ar/categories.po"
|
||||
)
|
||||
|
||||
//since both Po and Mo just pass-through to Domain for MarshalBinary and UnmarshalBinary, test it here
|
||||
func TestBinaryEncoding(t *testing.T) {
|
||||
// Create po objects
|
||||
po := NewPo()
|
||||
po2 := NewPo()
|
||||
|
||||
// Parse file
|
||||
po.ParseFile(enUSFixture)
|
||||
|
||||
buff, err := po.GetDomain().MarshalBinary()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = po2.GetDomain().UnmarshalBinary(buff)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Test translations
|
||||
tr := po2.Get("My text")
|
||||
if tr != translatedText {
|
||||
t.Errorf("Expected '%s' but got '%s'", translatedText, tr)
|
||||
}
|
||||
// Test translations
|
||||
tr = po2.Get("language")
|
||||
if tr != "en_US" {
|
||||
t.Errorf("Expected 'en_US' but got '%s'", tr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDomain_GetTranslations(t *testing.T) {
|
||||
po := NewPo()
|
||||
po.ParseFile(enUSFixture)
|
||||
|
|
29
gotext.go
29
gotext.go
|
@ -3,27 +3,25 @@ Package gotext implements GNU gettext utilities.
|
|||
|
||||
For quick/simple translations you can use the package level functions directly.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/leonelquinteros/gotext"
|
||||
)
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/leonelquinteros/gotext"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Configure package
|
||||
gotext.Configure("/path/to/locales/root/dir", "en_UK", "domain-name")
|
||||
func main() {
|
||||
// Configure package
|
||||
gotext.Configure("/path/to/locales/root/dir", "en_UK", "domain-name")
|
||||
|
||||
// Translate text from default domain
|
||||
fmt.Println(gotext.Get("My text on 'domain-name' domain"))
|
||||
|
||||
// Translate text from a different domain without reconfigure
|
||||
fmt.Println(gotext.GetD("domain2", "Another text on a different domain"))
|
||||
}
|
||||
// Translate text from default domain
|
||||
fmt.Println(gotext.Get("My text on 'domain-name' domain"))
|
||||
|
||||
// Translate text from a different domain without reconfigure
|
||||
fmt.Println(gotext.GetD("domain2", "Another text on a different domain"))
|
||||
}
|
||||
*/
|
||||
package gotext
|
||||
|
||||
import (
|
||||
"encoding/gob"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
@ -57,9 +55,6 @@ func init() {
|
|||
library: "/usr/local/share/locale",
|
||||
locales: nil,
|
||||
}
|
||||
|
||||
// Register Translator types for gob encoding
|
||||
gob.Register(TranslatorEncoding{})
|
||||
}
|
||||
|
||||
// loadLocales creates a new Locale object for every language (specified using Configure)
|
||||
|
|
94
locale.go
94
locale.go
|
@ -6,8 +6,6 @@
|
|||
package gotext
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path"
|
||||
|
@ -21,30 +19,28 @@ multiple languages at the same time by working with this object.
|
|||
|
||||
Example:
|
||||
|
||||
import (
|
||||
"encoding/gob"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/leonelquinteros/gotext"
|
||||
)
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/leonelquinteros/gotext"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Create Locale with library path and language code
|
||||
l := gotext.NewLocale("/path/to/i18n/dir", "en_US")
|
||||
func main() {
|
||||
// Create Locale with library path and language code
|
||||
l := gotext.NewLocale("/path/to/i18n/dir", "en_US")
|
||||
|
||||
// Load domain '/path/to/i18n/dir/en_US/LC_MESSAGES/default.{po,mo}'
|
||||
l.AddDomain("default")
|
||||
// Load domain '/path/to/i18n/dir/en_US/LC_MESSAGES/default.{po,mo}'
|
||||
l.AddDomain("default")
|
||||
|
||||
// Translate text from default domain
|
||||
fmt.Println(l.Get("Translate this"))
|
||||
// Translate text from default domain
|
||||
fmt.Println(l.Get("Translate this"))
|
||||
|
||||
// Load different domain ('/path/to/i18n/dir/en_US/LC_MESSAGES/extras.{po,mo}')
|
||||
l.AddDomain("extras")
|
||||
|
||||
// Translate text from domain
|
||||
fmt.Println(l.GetD("extras", "Translate this"))
|
||||
}
|
||||
// Load different domain ('/path/to/i18n/dir/en_US/LC_MESSAGES/extras.{po,mo}')
|
||||
l.AddDomain("extras")
|
||||
|
||||
// Translate text from domain
|
||||
fmt.Println(l.GetD("extras", "Translate this"))
|
||||
}
|
||||
*/
|
||||
type Locale struct {
|
||||
// Path to locale files.
|
||||
|
@ -333,7 +329,7 @@ func (l *Locale) GetNDC(dom, str, plural string, n int, ctx string, vars ...inte
|
|||
return Printf(plural, vars...)
|
||||
}
|
||||
|
||||
//GetTranslations returns a copy of all translations in all domains of this locale. It does not support contexts.
|
||||
// GetTranslations returns a copy of all translations in all domains of this locale. It does not support contexts.
|
||||
func (l *Locale) GetTranslations() map[string]*Translation {
|
||||
all := make(map[string]*Translation)
|
||||
|
||||
|
@ -415,57 +411,3 @@ type LocaleEncoding struct {
|
|||
Domains map[string][]byte
|
||||
DefaultDomain string
|
||||
}
|
||||
|
||||
// MarshalBinary implements encoding BinaryMarshaler interface
|
||||
func (l *Locale) MarshalBinary() ([]byte, error) {
|
||||
obj := new(LocaleEncoding)
|
||||
obj.DefaultDomain = l.defaultDomain
|
||||
obj.Domains = make(map[string][]byte)
|
||||
for k, v := range l.Domains {
|
||||
var err error
|
||||
obj.Domains[k], err = v.MarshalBinary()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
obj.Lang = l.lang
|
||||
obj.Path = l.path
|
||||
|
||||
var buff bytes.Buffer
|
||||
encoder := gob.NewEncoder(&buff)
|
||||
err := encoder.Encode(obj)
|
||||
|
||||
return buff.Bytes(), err
|
||||
}
|
||||
|
||||
// UnmarshalBinary implements encoding BinaryUnmarshaler interface
|
||||
func (l *Locale) UnmarshalBinary(data []byte) error {
|
||||
buff := bytes.NewBuffer(data)
|
||||
obj := new(LocaleEncoding)
|
||||
|
||||
decoder := gob.NewDecoder(buff)
|
||||
err := decoder.Decode(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
l.defaultDomain = obj.DefaultDomain
|
||||
l.lang = obj.Lang
|
||||
l.path = obj.Path
|
||||
|
||||
// Decode Domains
|
||||
l.Domains = make(map[string]Translator)
|
||||
for k, v := range obj.Domains {
|
||||
var tr TranslatorEncoding
|
||||
buff := bytes.NewBuffer(v)
|
||||
trDecoder := gob.NewDecoder(buff)
|
||||
err := trDecoder.Decode(&tr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
l.Domains[k] = tr.GetTranslator()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -654,55 +654,6 @@ func TestArabicMissingPluralForm(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLocaleBinaryEncoding(t *testing.T) {
|
||||
var locales []*Locale
|
||||
{ // test os
|
||||
// Create Locale
|
||||
locales = append(locales, NewLocale("fixtures/", "en_US"))
|
||||
}
|
||||
{ // test fs
|
||||
locales = append(locales, NewLocaleFS("en_US", os.DirFS("fixtures")))
|
||||
}
|
||||
|
||||
for _, l := range locales {
|
||||
l.AddDomain("default")
|
||||
|
||||
buff, err := l.MarshalBinary()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
l2 := new(Locale)
|
||||
err = l2.UnmarshalBinary(buff)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Check object properties
|
||||
if l.path != l2.path {
|
||||
t.Fatalf("path doesn't match: '%s' vs '%s'", l.path, l2.path)
|
||||
}
|
||||
if l.lang != l2.lang {
|
||||
t.Fatalf("lang doesn't match: '%s' vs '%s'", l.lang, l2.lang)
|
||||
}
|
||||
if l.defaultDomain != l2.defaultDomain {
|
||||
t.Fatalf("defaultDomain doesn't match: '%s' vs '%s'", l.defaultDomain, l2.defaultDomain)
|
||||
}
|
||||
|
||||
// Check translations
|
||||
if l.Get("My text") != l2.Get("My text") {
|
||||
t.Errorf("'%s' is different from '%s", l.Get("My text"), l2.Get("My text"))
|
||||
}
|
||||
if l.Get("More") != l2.Get("More") {
|
||||
t.Errorf("'%s' is different from '%s", l.Get("More"), l2.Get("More"))
|
||||
}
|
||||
if l.GetN("One with var: %s", "Several with vars: %s", 3, "VALUE") != l2.GetN("One with var: %s", "Several with vars: %s", 3, "VALUE") {
|
||||
t.Errorf("'%s' is different from '%s", l.GetN("One with var: %s", "Several with vars: %s", 3, "VALUE"), l2.GetN("One with var: %s", "Several with vars: %s", 3, "VALUE"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLocale_GetTranslations(t *testing.T) {
|
||||
var locales []*Locale
|
||||
{ // test os
|
||||
|
|
13
mo.go
13
mo.go
|
@ -45,7 +45,6 @@ Example:
|
|||
// Get Translation
|
||||
fmt.Println(mo.Get("Translate this"))
|
||||
}
|
||||
|
||||
*/
|
||||
type Mo struct {
|
||||
//these three public members are for backwards compatibility. they are just set to the value in the domain
|
||||
|
@ -56,7 +55,7 @@ type Mo struct {
|
|||
fs fs.FS
|
||||
}
|
||||
|
||||
//NewMo should always be used to instantiate a new Mo object
|
||||
// NewMo should always be used to instantiate a new Mo object
|
||||
func NewMo() *Mo {
|
||||
mo := new(Mo)
|
||||
mo.domain = NewDomain()
|
||||
|
@ -75,7 +74,7 @@ func (mo *Mo) GetDomain() *Domain {
|
|||
return mo.domain
|
||||
}
|
||||
|
||||
//all of the Get functions are for convenience and aid in backwards compatibility
|
||||
// all of the Get functions are for convenience and aid in backwards compatibility
|
||||
func (mo *Mo) Get(str string, vars ...interface{}) string {
|
||||
return mo.domain.Get(str, vars...)
|
||||
}
|
||||
|
@ -105,14 +104,6 @@ func (mo *Mo) IsTranslatedNC(str string, n int, ctx string) bool {
|
|||
return mo.domain.IsTranslatedNC(str, n, ctx)
|
||||
}
|
||||
|
||||
func (mo *Mo) MarshalBinary() ([]byte, error) {
|
||||
return mo.domain.MarshalBinary()
|
||||
}
|
||||
|
||||
func (mo *Mo) UnmarshalBinary(data []byte) error {
|
||||
return mo.domain.UnmarshalBinary(data)
|
||||
}
|
||||
|
||||
func (mo *Mo) ParseFile(f string) {
|
||||
data, err := getFileData(f, mo.fs)
|
||||
if err != nil {
|
||||
|
|
30
mo_test.go
30
mo_test.go
|
@ -204,33 +204,3 @@ func TestNewMoTranslatorRace(t *testing.T) {
|
|||
<-pc
|
||||
<-rc
|
||||
}
|
||||
|
||||
func TestMoBinaryEncoding(t *testing.T) {
|
||||
// Create mo objects
|
||||
mo := NewMo()
|
||||
mo2 := NewMo()
|
||||
|
||||
// Parse file
|
||||
mo.ParseFile("fixtures/en_US/default.mo")
|
||||
|
||||
buff, err := mo.MarshalBinary()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = mo2.UnmarshalBinary(buff)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Test translations
|
||||
tr := mo2.Get("My text")
|
||||
if tr != translatedText {
|
||||
t.Errorf("Expected '%s' but got '%s'", translatedText, tr)
|
||||
}
|
||||
// Test translations
|
||||
tr = mo2.Get("language")
|
||||
if tr != "en_US" {
|
||||
t.Errorf("Expected 'en_US' but got '%s'", tr)
|
||||
}
|
||||
}
|
||||
|
|
11
po.go
11
po.go
|
@ -33,7 +33,6 @@ Example:
|
|||
// Get Translation
|
||||
fmt.Println(po.Get("Translate this"))
|
||||
}
|
||||
|
||||
*/
|
||||
type Po struct {
|
||||
//these three public members are for backwards compatibility. they are just set to the value in the domain
|
||||
|
@ -55,7 +54,7 @@ const (
|
|||
msgStr
|
||||
)
|
||||
|
||||
//NewPo should always be used to instantiate a new Po object
|
||||
// NewPo should always be used to instantiate a new Po object
|
||||
func NewPo() *Po {
|
||||
po := new(Po)
|
||||
po.domain = NewDomain()
|
||||
|
@ -131,14 +130,6 @@ func (po *Po) MarshalText() ([]byte, error) {
|
|||
return po.domain.MarshalText()
|
||||
}
|
||||
|
||||
func (po *Po) MarshalBinary() ([]byte, error) {
|
||||
return po.domain.MarshalBinary()
|
||||
}
|
||||
|
||||
func (po *Po) UnmarshalBinary(data []byte) error {
|
||||
return po.domain.UnmarshalBinary(data)
|
||||
}
|
||||
|
||||
func (po *Po) ParseFile(f string) {
|
||||
data, err := getFileData(f, po.fs)
|
||||
if err != nil {
|
||||
|
|
30
po_test.go
30
po_test.go
|
@ -594,36 +594,6 @@ func TestNewPoTranslatorRace(t *testing.T) {
|
|||
<-rc
|
||||
}
|
||||
|
||||
func TestPoBinaryEncoding(t *testing.T) {
|
||||
// Create po objects
|
||||
po := NewPo()
|
||||
po2 := NewPo()
|
||||
|
||||
// Parse file
|
||||
po.ParseFile("fixtures/en_US/default.po")
|
||||
|
||||
buff, err := po.MarshalBinary()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = po2.UnmarshalBinary(buff)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Test translations
|
||||
tr := po2.Get("My text")
|
||||
if tr != "Translated text" {
|
||||
t.Errorf("Expected 'Translated text' but got '%s'", tr)
|
||||
}
|
||||
// Test translations
|
||||
tr = po2.Get("language")
|
||||
if tr != "en_US" {
|
||||
t.Errorf("Expected 'en_US' but got '%s'", tr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPoTextEncoding(t *testing.T) {
|
||||
// Create po objects
|
||||
po := NewPo()
|
||||
|
|
|
@ -14,7 +14,6 @@ import (
|
|||
|
||||
// Translator interface is used by Locale and Po objects.Translator
|
||||
// It contains all methods needed to parse translation sources and obtain corresponding translations.
|
||||
// Also implements gob.GobEncoder/gob.DobDecoder interfaces to allow serialization of Locale objects.
|
||||
type Translator interface {
|
||||
ParseFile(f string)
|
||||
Parse(buf []byte)
|
||||
|
@ -23,8 +22,6 @@ type Translator interface {
|
|||
GetC(str, ctx string, vars ...interface{}) string
|
||||
GetNC(str, plural string, n int, ctx string, vars ...interface{}) string
|
||||
|
||||
MarshalBinary() ([]byte, error)
|
||||
UnmarshalBinary([]byte) error
|
||||
GetDomain() *Domain
|
||||
}
|
||||
|
||||
|
@ -66,7 +63,7 @@ func (te *TranslatorEncoding) GetTranslator() Translator {
|
|||
return po
|
||||
}
|
||||
|
||||
//getFileData reads a file and returns the byte slice after doing some basic sanity checking
|
||||
// getFileData reads a file and returns the byte slice after doing some basic sanity checking
|
||||
func getFileData(f string, filesystem fs.FS) ([]byte, error) {
|
||||
if filesystem != nil {
|
||||
return fs.ReadFile(filesystem, f)
|
||||
|
|
Loading…
Reference in a new issue