allow locale to work with a fs.FS

Signed-off-by: jkoberg <jkoberg@owncloud.com>
This commit is contained in:
jkoberg 2023-03-16 10:53:22 +01:00
parent 6f9bcaa969
commit 9d5a301452
4 changed files with 57 additions and 9 deletions

View file

@ -8,6 +8,7 @@ package gotext
import (
"bytes"
"encoding/gob"
"io/fs"
"os"
"path"
"sync"
@ -60,6 +61,9 @@ type Locale struct {
// Sync Mutex
sync.RWMutex
// optional fs to use
fs fs.FS
}
// NewLocale creates and initializes a new Locale object for a given language.
@ -72,27 +76,34 @@ func NewLocale(p, l string) *Locale {
}
}
// NewLocaleFS returns a Locale working with a fs.FS
func NewLocaleFS(p, l string, filesystem fs.FS) *Locale {
loc := NewLocale(p, l)
loc.fs = filesystem
return loc
}
func (l *Locale) findExt(dom, ext string) string {
filename := path.Join(l.path, l.lang, "LC_MESSAGES", dom+"."+ext)
if _, err := os.Stat(filename); err == nil {
if l.fileExists(filename) {
return filename
}
if len(l.lang) > 2 {
filename = path.Join(l.path, l.lang[:2], "LC_MESSAGES", dom+"."+ext)
if _, err := os.Stat(filename); err == nil {
if l.fileExists(filename) {
return filename
}
}
filename = path.Join(l.path, l.lang, dom+"."+ext)
if _, err := os.Stat(filename); err == nil {
if l.fileExists(filename) {
return filename
}
if len(l.lang) > 2 {
filename = path.Join(l.path, l.lang[:2], dom+"."+ext)
if _, err := os.Stat(filename); err == nil {
if l.fileExists(filename) {
return filename
}
}
@ -100,6 +111,20 @@ func (l *Locale) findExt(dom, ext string) string {
return ""
}
func (l *Locale) fileExists(filename string) bool {
if l.fs != nil {
f, err := l.fs.Open(filename)
if err != nil {
return false
}
_, err = f.Stat()
return err == nil
}
_, err := os.Stat(filename)
return err == nil
}
// AddDomain creates a new domain for a given locale object and initializes the Po object.
// If the domain exists, it gets reloaded.
func (l *Locale) AddDomain(dom string) {
@ -107,13 +132,13 @@ func (l *Locale) AddDomain(dom string) {
file := l.findExt(dom, "po")
if file != "" {
poObj = NewPo()
poObj = NewPoFS(l.fs)
// Parse file.
poObj.ParseFile(file)
} else {
file = l.findExt(dom, "mo")
if file != "" {
poObj = NewMo()
poObj = NewMoFS(l.fs)
// Parse file.
poObj.ParseFile(file)
} else {

11
mo.go
View file

@ -8,6 +8,7 @@ package gotext
import (
"bytes"
"encoding/binary"
"io/fs"
)
const (
@ -52,6 +53,7 @@ type Mo struct {
Language string
PluralForms string
domain *Domain
fs fs.FS
}
//NewMo should always be used to instantiate a new Mo object
@ -62,6 +64,13 @@ func NewMo() *Mo {
return mo
}
// NewMoFS works like NewMO but adds an optional fs.FS
func NewMoFS(filesystem fs.FS) *Mo {
mo := NewMo()
mo.fs = filesystem
return mo
}
func (mo *Mo) GetDomain() *Domain {
return mo.domain
}
@ -92,7 +101,7 @@ func (mo *Mo) UnmarshalBinary(data []byte) error {
}
func (mo *Mo) ParseFile(f string) {
data, err := getFileData(f)
data, err := getFileData(f, mo.fs)
if err != nil {
return
}

11
po.go
View file

@ -6,6 +6,7 @@
package gotext
import (
"io/fs"
"strconv"
"strings"
)
@ -41,6 +42,7 @@ type Po struct {
PluralForms string
domain *Domain
fs fs.FS
}
type parseState int
@ -61,6 +63,13 @@ func NewPo() *Po {
return po
}
// NewPoFS works like NewPO but adds an optional fs.FS
func NewPoFS(filesystem fs.FS) *Po {
po := NewPo()
po.fs = filesystem
return po
}
func (po *Po) GetDomain() *Domain {
return po.domain
}
@ -118,7 +127,7 @@ func (po *Po) UnmarshalBinary(data []byte) error {
}
func (po *Po) ParseFile(f string) {
data, err := getFileData(f)
data, err := getFileData(f, po.fs)
if err != nil {
return
}

View file

@ -7,6 +7,7 @@ package gotext
import (
"errors"
"io/fs"
"io/ioutil"
"os"
)
@ -66,7 +67,11 @@ func (te *TranslatorEncoding) GetTranslator() Translator {
}
//getFileData reads a file and returns the byte slice after doing some basic sanity checking
func getFileData(f string) ([]byte, error) {
func getFileData(f string, filesystem fs.FS) ([]byte, error) {
if filesystem != nil {
return fs.ReadFile(filesystem, f)
}
// Check if file exists
info, err := os.Stat(f)
if err != nil {