Remove usage of gob

This commit is contained in:
Trevor Slocum 2024-07-21 23:30:26 -07:00
parent 7af07d2ba5
commit 7911f2a8a9
10 changed files with 34 additions and 303 deletions

View file

@ -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
}

View file

@ -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)

View file

@ -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)

View file

@ -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
}

View file

@ -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
View file

@ -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 {

View file

@ -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
View file

@ -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 {

View file

@ -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()

View file

@ -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)