mirror of
https://github.com/photoprism/photoprism.git
synced 2025-12-11 16:24:11 +01:00
Backend: Refactor new enum package and yes/no matching #5191
Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
@@ -1,6 +1,15 @@
|
|||||||
package enum
|
package enum
|
||||||
|
|
||||||
// YesMap map to represent Yes in the following languages Czech, Danish, Dutch, English, French, German, Indonesian, Italian, Polish, Portuguese, Russian, Ukrainian.
|
// True and False specify boolean string representations.
|
||||||
|
const (
|
||||||
|
True = "true"
|
||||||
|
False = "false"
|
||||||
|
)
|
||||||
|
|
||||||
|
// YesMap enumerates lower-case tokens we accept as an affirmative answer across
|
||||||
|
// supported languages (Czech, Danish, Dutch, English, French, German,
|
||||||
|
// Indonesian, Italian, Polish, Portuguese, Russian, Ukrainian). Callers should
|
||||||
|
// trim and lowercase input before performing lookups.
|
||||||
var YesMap = map[string]struct{}{
|
var YesMap = map[string]struct{}{
|
||||||
"1": {},
|
"1": {},
|
||||||
"yes": {},
|
"yes": {},
|
||||||
@@ -12,6 +21,7 @@ var YesMap = map[string]struct{}{
|
|||||||
"ja": {},
|
"ja": {},
|
||||||
"oui": {},
|
"oui": {},
|
||||||
"si": {},
|
"si": {},
|
||||||
|
"sí": {},
|
||||||
"tak": {},
|
"tak": {},
|
||||||
"sim": {},
|
"sim": {},
|
||||||
"да": {},
|
"да": {},
|
||||||
@@ -19,7 +29,9 @@ var YesMap = map[string]struct{}{
|
|||||||
"так": {},
|
"так": {},
|
||||||
}
|
}
|
||||||
|
|
||||||
// NoMap map to represent No in the following languages Czech, Danish, Dutch, English, French, German, Indonesian, Italian, Polish, Portuguese, Russian, Ukrainian.
|
// NoMap enumerates lower-case tokens we accept as a negative answer across the
|
||||||
|
// same set of supported languages. Callers should trim and lowercase input
|
||||||
|
// before performing lookups.
|
||||||
var NoMap = map[string]struct{}{
|
var NoMap = map[string]struct{}{
|
||||||
"0": {},
|
"0": {},
|
||||||
"no": {},
|
"no": {},
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Package enum provides declarations of enum.
|
Package enum centralizes canonical string constants and lookup tables that we
|
||||||
|
use when interpreting enumerations throughout PhotoPrism.
|
||||||
|
|
||||||
Copyright (c) 2018 - 2025 PhotoPrism UG. All rights reserved.
|
Copyright (c) 2018 - 2025 PhotoPrism UG. All rights reserved.
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
package enum
|
|
||||||
|
|
||||||
// True and False specify boolean string representations.
|
|
||||||
const (
|
|
||||||
True = "true"
|
|
||||||
False = "false"
|
|
||||||
)
|
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
package list
|
package list
|
||||||
|
|
||||||
import "github.com/photoprism/photoprism/pkg/enum"
|
import (
|
||||||
|
"github.com/photoprism/photoprism/pkg/enum"
|
||||||
|
)
|
||||||
|
|
||||||
// StringLengthLimit specifies the maximum length of string return values.
|
// StringLengthLimit specifies the maximum length of string return values.
|
||||||
var StringLengthLimit = 767
|
var StringLengthLimit = 767
|
||||||
|
|||||||
@@ -1,56 +0,0 @@
|
|||||||
package txt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/photoprism/photoprism/pkg/enum"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Bool casts a string to bool.
|
|
||||||
func Bool(s string) bool {
|
|
||||||
s = strings.TrimSpace(s)
|
|
||||||
|
|
||||||
if s == "" || No(s) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Yes tests if a string represents "yes" in the following languages Czech, Danish, Dutch, English, French, German, Indonesian, Italian, Polish, Portuguese, Russian, Ukrainian.
|
|
||||||
func Yes(s string) (result bool) {
|
|
||||||
t := strings.ToLower(strings.TrimSpace(s))
|
|
||||||
if t == "" {
|
|
||||||
return false
|
|
||||||
} else if strings.Contains(t, " ") {
|
|
||||||
result = false
|
|
||||||
} else {
|
|
||||||
|
|
||||||
_, result = enum.YesMap[t]
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// No tests if a string represents "no" in the following languages Czech, Danish, Dutch, English, French, German, Indonesian, Italian, Polish, Portuguese, Russian, Ukrainian.
|
|
||||||
func No(s string) (result bool) {
|
|
||||||
t := strings.ToLower(strings.TrimSpace(s))
|
|
||||||
if t == "" {
|
|
||||||
return false
|
|
||||||
} else if strings.Contains(t, " ") {
|
|
||||||
result = false
|
|
||||||
} else {
|
|
||||||
_, result = enum.NoMap[t]
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// New tests if a string represents "new".
|
|
||||||
func New(s string) bool {
|
|
||||||
if s == "" {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
s = strings.ToLower(strings.TrimSpace(s))
|
|
||||||
|
|
||||||
return s == EnNew
|
|
||||||
}
|
|
||||||
21
pkg/txt/const.go
Normal file
21
pkg/txt/const.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package txt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/photoprism/photoprism/pkg/enum"
|
||||||
|
)
|
||||||
|
|
||||||
|
// True and False specify boolean string representations.
|
||||||
|
const (
|
||||||
|
True = enum.True
|
||||||
|
False = enum.False
|
||||||
|
)
|
||||||
|
|
||||||
|
// Additional english language strings.
|
||||||
|
const (
|
||||||
|
EnOr = "or"
|
||||||
|
EnAnd = "and"
|
||||||
|
EnWith = "with"
|
||||||
|
EnIn = "in"
|
||||||
|
EnAt = "at"
|
||||||
|
EnNew = "new"
|
||||||
|
)
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package txt
|
|
||||||
|
|
||||||
const (
|
|
||||||
EnOr = "or"
|
|
||||||
EnAnd = "and"
|
|
||||||
EnWith = "with"
|
|
||||||
EnIn = "in"
|
|
||||||
EnAt = "at"
|
|
||||||
EnNew = "new"
|
|
||||||
)
|
|
||||||
57
pkg/txt/match.go
Normal file
57
pkg/txt/match.go
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
package txt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
|
"github.com/photoprism/photoprism/pkg/enum"
|
||||||
|
)
|
||||||
|
|
||||||
|
// New tests if a string represents "new".
|
||||||
|
func New(s string) bool {
|
||||||
|
if s == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
s = strings.ToLower(strings.TrimSpace(s))
|
||||||
|
|
||||||
|
return s == EnNew
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bool casts a string to bool by treating any non-empty value that is not a
|
||||||
|
// known negative token as true.
|
||||||
|
func Bool(s string) bool {
|
||||||
|
s = strings.TrimSpace(s)
|
||||||
|
|
||||||
|
if s == "" || No(s) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Yes reports whether s matches a supported affirmative token in the languages
|
||||||
|
// represented by enum.YesMap.
|
||||||
|
func Yes(s string) bool {
|
||||||
|
return matchEnumToken(enum.YesMap, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// No reports whether s matches a supported negative token in the languages
|
||||||
|
// represented by enum.NoMap.
|
||||||
|
func No(s string) bool {
|
||||||
|
return matchEnumToken(enum.NoMap, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// matchEnumToken normalizes s and checks whether it exists in tokens.
|
||||||
|
func matchEnumToken(tokens map[string]struct{}, s string) bool {
|
||||||
|
t := strings.ToLower(strings.TrimSpace(s))
|
||||||
|
if t == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if strings.IndexFunc(t, unicode.IsSpace) >= 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
_, ok := tokens[t]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
@@ -6,6 +6,30 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestNew(t *testing.T) {
|
||||||
|
t.Run("Empty", func(t *testing.T) {
|
||||||
|
assert.False(t, New(""))
|
||||||
|
})
|
||||||
|
t.Run("EnNew", func(t *testing.T) {
|
||||||
|
assert.True(t, New(EnNew))
|
||||||
|
})
|
||||||
|
t.Run("Spaces", func(t *testing.T) {
|
||||||
|
assert.True(t, New(" new "))
|
||||||
|
})
|
||||||
|
t.Run("Uppercase", func(t *testing.T) {
|
||||||
|
assert.True(t, New("NEW"))
|
||||||
|
})
|
||||||
|
t.Run("Lowercase", func(t *testing.T) {
|
||||||
|
assert.True(t, New("new"))
|
||||||
|
})
|
||||||
|
t.Run("True", func(t *testing.T) {
|
||||||
|
assert.True(t, New("New"))
|
||||||
|
})
|
||||||
|
t.Run("False", func(t *testing.T) {
|
||||||
|
assert.False(t, New("non"))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestBool(t *testing.T) {
|
func TestBool(t *testing.T) {
|
||||||
t.Run("NotEmpty", func(t *testing.T) {
|
t.Run("NotEmpty", func(t *testing.T) {
|
||||||
assert.True(t, Bool("Browse your life in pictures"))
|
assert.True(t, Bool("Browse your life in pictures"))
|
||||||
@@ -34,6 +58,9 @@ func TestBool(t *testing.T) {
|
|||||||
t.Run("Empty", func(t *testing.T) {
|
t.Run("Empty", func(t *testing.T) {
|
||||||
assert.False(t, Bool(""))
|
assert.False(t, Bool(""))
|
||||||
})
|
})
|
||||||
|
t.Run("UppercaseNo", func(t *testing.T) {
|
||||||
|
assert.False(t, Bool("NO"))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestYes(t *testing.T) {
|
func TestYes(t *testing.T) {
|
||||||
@@ -98,6 +125,12 @@ func TestYes(t *testing.T) {
|
|||||||
assert.True(t, Yes("да"))
|
assert.True(t, Yes("да"))
|
||||||
assert.True(t, Yes("Да"))
|
assert.True(t, Yes("Да"))
|
||||||
})
|
})
|
||||||
|
t.Run("TabSeparatedPhrase", func(t *testing.T) {
|
||||||
|
assert.False(t, Yes("yes\tplease"))
|
||||||
|
})
|
||||||
|
t.Run("NonBreakingSpace", func(t *testing.T) {
|
||||||
|
assert.False(t, Yes("yes\u00a0please"))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNo(t *testing.T) {
|
func TestNo(t *testing.T) {
|
||||||
@@ -181,28 +214,10 @@ func TestNo(t *testing.T) {
|
|||||||
t.Run("Nein", func(t *testing.T) {
|
t.Run("Nein", func(t *testing.T) {
|
||||||
assert.True(t, No("nein"))
|
assert.True(t, No("nein"))
|
||||||
})
|
})
|
||||||
}
|
t.Run("TabSeparatedPhrase", func(t *testing.T) {
|
||||||
|
assert.False(t, No("no\tthanks"))
|
||||||
func TestNew(t *testing.T) {
|
|
||||||
t.Run("Empty", func(t *testing.T) {
|
|
||||||
assert.False(t, New(""))
|
|
||||||
})
|
})
|
||||||
t.Run("EnNew", func(t *testing.T) {
|
t.Run("NonBreakingSpace", func(t *testing.T) {
|
||||||
assert.True(t, New(EnNew))
|
assert.True(t, No("нет\u00a0"))
|
||||||
})
|
|
||||||
t.Run("Spaces", func(t *testing.T) {
|
|
||||||
assert.True(t, New(" new "))
|
|
||||||
})
|
|
||||||
t.Run("Uppercase", func(t *testing.T) {
|
|
||||||
assert.True(t, New("NEW"))
|
|
||||||
})
|
|
||||||
t.Run("Lowercase", func(t *testing.T) {
|
|
||||||
assert.True(t, New("new"))
|
|
||||||
})
|
|
||||||
t.Run("True", func(t *testing.T) {
|
|
||||||
assert.True(t, New("New"))
|
|
||||||
})
|
|
||||||
t.Run("False", func(t *testing.T) {
|
|
||||||
assert.False(t, New("non"))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user