Skip to content

Commit

Permalink
added the iterator over slice and map
Browse files Browse the repository at this point in the history
  • Loading branch information
2403905 committed Aug 1, 2024
1 parent ddbab45 commit 5832a4e
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 68 deletions.
41 changes: 31 additions & 10 deletions ocis-pkg/l10n/l10n.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func TranslateLocation(t Translator, locale string) func(string, ...any) string
return t.Locale(locale).Get
}

// TranslateEntity function tranlate all described fields in the struct in the given locale including nested structs
// TranslateEntity function translate all described fields in the given locale including nested structures, slises and maps.
//
// type InnreStruct struct {
// Description string
Expand All @@ -86,12 +86,29 @@ func TranslateLocation(t Translator, locale string) func(string, ...any) string
// TranslateField("DisplayName")))
func TranslateEntity(entity any, tr func(string, ...any) string, fields ...any) error {
value := reflect.ValueOf(entity)
if value.Kind() != reflect.Ptr || !value.IsNil() && value.Elem().Kind() != reflect.Struct {
// must be a pointer to a struct
return ErrStructPointer
// Indirect through pointers and interfaces
if value.Kind() == reflect.Ptr || value.Kind() == reflect.Interface {
if value.IsNil() {
// treat a nil struct pointer as valid
return nil
}
value = value.Elem()
}
if value.IsNil() {
// treat a nil struct pointer as valid

switch value.Kind() {
case reflect.Slice, reflect.Map:
for i := 0; i < value.Len(); i++ {
nextValue := value.Index(i)
// Indirect through pointers and interfaces
if nextValue.Kind() == reflect.Ptr || nextValue.Kind() == reflect.Interface {
if nextValue.IsNil() {
// treat a nil struct pointer as valid
continue
}
nextValue = value.Index(i).Elem()
}
translateInner(nextValue, tr, fields...)
}
return nil
}
translateInner(value, tr, fields...)
Expand All @@ -111,8 +128,8 @@ func translateField(value reflect.Value, tr func(string, ...any) string, fl fiel
return
}
fieldName, fields := fl()
// exported field
if value.Kind() == reflect.Ptr {
// Indirect through pointers and interfaces
if value.Kind() == reflect.Ptr || value.Kind() == reflect.Interface {
if value.IsNil() {
return
}
Expand All @@ -122,6 +139,12 @@ func translateField(value reflect.Value, tr func(string, ...any) string, fl fiel
if !innerValue.IsValid() {
return
}
switch innerValue.Kind() {
case reflect.Slice, reflect.Map:
for i := 0; i < innerValue.Len(); i++ {
translateInner(innerValue.Index(i), tr, fields...)
}
}
if isStruct(innerValue) {
translateInner(innerValue, tr, fields...)
return
Expand Down Expand Up @@ -169,8 +192,6 @@ func isStruct(r reflect.Value) bool {
}

var (
// ErrStructPointer is the error that a struct being validated is not specified as a pointer.
ErrStructPointer = errors.New("only a pointer to a struct can be validated")
ErrUnsupportedType = errors.New("unsupported type")
)

Expand Down
83 changes: 82 additions & 1 deletion ocis-pkg/l10n/l10n_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ func TestTranslateStruct(t *testing.T) {
SubStruct *InnreStruct
}

type WrapperStruct struct {
StructList []*InnreStruct
}

toStrPointer := func(str string) *string {
return &str
}
Expand All @@ -34,7 +38,68 @@ func TestTranslateStruct(t *testing.T) {
wantErr bool
}{
{
name: "empty struct",
name: "top level slice of struct",
args: args{
structPtr: []*InnreStruct{
{
Description: "inner 1",
DisplayName: toStrPointer("innerDisplayName 1"),
},
{
Description: "inner 2",
DisplayName: toStrPointer("innerDisplayName 2"),
},
},
request: []any{
TranslateField("Description"),
TranslateField("DisplayName")},
},
expected: []*InnreStruct{
{
Description: "new Inner 1",
DisplayName: toStrPointer("new InnerDisplayName 1"),
},
{
Description: "new Inner 2",
DisplayName: toStrPointer("new InnerDisplayName 2"),
},
},
},
{
name: "wrapped struct full",
args: args{
structPtr: &WrapperStruct{
StructList: []*InnreStruct{
{
Description: "inner 1",
DisplayName: toStrPointer("innerDisplayName 1"),
},
{
Description: "inner 2",
DisplayName: toStrPointer("innerDisplayName 2"),
},
},
},
request: []any{
TranslateField("StructList",
TranslateField("Description"),
TranslateField("DisplayName"))},
},
expected: &WrapperStruct{
StructList: []*InnreStruct{
{
Description: "new Inner 1",
DisplayName: toStrPointer("new InnerDisplayName 1"),
},
{
Description: "new Inner 2",
DisplayName: toStrPointer("new InnerDisplayName 2"),
},
},
},
},
{
name: "empty struct, NotExistingSubStructName",
args: args{
structPtr: &TopLevelStruct{},
request: []any{
Expand Down Expand Up @@ -140,6 +205,14 @@ func TestTranslateStruct(t *testing.T) {
},
},
},
{
name: "nil",
args: args{
structPtr: nil,
request: []any{TranslateField("Description")},
},
expected: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand All @@ -163,6 +236,14 @@ func mock() func(string, ...interface{}) string {
return "new Inner"
case "innerDisplayName":
return "new InnerDisplayName"
case "inner 1":
return "new Inner 1"
case "innerDisplayName 1":
return "new InnerDisplayName 1"
case "inner 2":
return "new Inner 2"
case "innerDisplayName 2":
return "new InnerDisplayName 2"
}
return s
}
Expand Down
8 changes: 4 additions & 4 deletions services/activitylog/pkg/service/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,6 @@ func (s *ActivitylogService) HandleGetItemActivities(w http.ResponseWriter, r *h
return
}

// FIXME: configurable default locale?
loc := l10n.MustGetUserLocale(r.Context(), activeUser.GetId().GetOpaqueId(), r.Header.Get(l10n.HeaderAcceptLanguage), s.valService)
t := l10n.NewTranslatorFromCommonConfig("en", _domain, "", _localeFS, _localeSubPath)

resp := GetActivitiesResponse{Activities: make([]libregraph.Activity, 0, len(evRes.GetEvents()))}
for _, e := range evRes.GetEvents() {
delete(toDelete, e.GetId())
Expand Down Expand Up @@ -168,6 +164,10 @@ func (s *ActivitylogService) HandleGetItemActivities(w http.ResponseWriter, r *h
continue
}

// FIXME: configurable default locale?
loc := l10n.MustGetUserLocale(r.Context(), activeUser.GetId().GetOpaqueId(), r.Header.Get(l10n.HeaderAcceptLanguage), s.valService)
t := l10n.NewTranslatorFromCommonConfig("en", _domain, "", _localeFS, _localeSubPath)

resp.Activities = append(resp.Activities, NewActivity(t.Translate(message, loc), ts, e.GetId(), vars))
}

Expand Down
35 changes: 0 additions & 35 deletions services/graph/pkg/l10n/locale/ru/LC_MESSAGES/graph.po
Original file line number Diff line number Diff line change
Expand Up @@ -25,38 +25,3 @@ msgstr ""
#: pkg/service/v0/spacetemplates.go:37
msgid "Here you can add a description for this Space."
msgstr "Здесь вы можете добавить описание этого пространства."

#: pkg/unifiedrole/unifiedrole.go:87
msgid "Can edit"
msgstr ""

#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/unifiedrole.go:79
msgid "Can view"
msgstr ""

#. default description for new spaces
#: pkg/service/v0/spacetemplates.go:31
msgid "Here you can add a description for this Space."
msgstr ""

#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/unifiedrole.go:77 pkg/unifiedrole/unifiedrole.go:82
msgid "View and download."
msgstr ""

#: pkg/unifiedrole/unifiedrole.go:91
msgid "View, download and edit."
msgstr ""

#: pkg/unifiedrole/unifiedrole.go:92
msgid "View, download and upload."
msgstr ""

#. canEdit := "Can edit"
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/unifiedrole.go:86 pkg/unifiedrole/unifiedrole.go:90
msgid "View, download, upload, edit, add and delete."
msgstr ""
30 changes: 12 additions & 18 deletions services/graph/pkg/service/v0/api_driveitem_permissions.go
Original file line number Diff line number Diff line change
Expand Up @@ -638,15 +638,12 @@ func (api DriveItemPermissionsApi) ListPermissions(w http.ResponseWriter, r *htt
w.Header().Add("Content-Language", loc)
if loc != "" && loc != "en" {
trf := l10n2.NewTranslateLocation(loc, "en")
for i, role := range permissions.LibreGraphPermissionsRolesAllowedValues {
err := l10n.TranslateEntity(&role, trf,
l10n.TranslateField("Description"),
l10n.TranslateField("DisplayName"))
if err != nil {
api.logger.Warn().Err(err).Msg("tranlation error")
continue
}
permissions.LibreGraphPermissionsRolesAllowedValues[i] = role
err := l10n.TranslateEntity(permissions.LibreGraphPermissionsRolesAllowedValues, trf,
l10n.TranslateField("Description"),
l10n.TranslateField("DisplayName"),
)
if err != nil {
api.logger.Error().Err(err).Msg("tranlation error")
}
}

Expand Down Expand Up @@ -675,15 +672,12 @@ func (api DriveItemPermissionsApi) ListSpaceRootPermissions(w http.ResponseWrite
w.Header().Add("Content-Language", loc)
if loc != "" && loc != "en" {
trf := l10n2.NewTranslateLocation(loc, "en")
for i, role := range permissions.LibreGraphPermissionsRolesAllowedValues {
err := l10n.TranslateEntity(&role, trf,
l10n.TranslateField("Description"),
l10n.TranslateField("DisplayName"))
if err != nil {
api.logger.Warn().Err(err).Msg("tranlation error")
continue
}
permissions.LibreGraphPermissionsRolesAllowedValues[i] = role
err := l10n.TranslateEntity(permissions.LibreGraphPermissionsRolesAllowedValues, trf,
l10n.TranslateField("Description"),
l10n.TranslateField("DisplayName"),
)
if err != nil {
api.logger.Error().Err(err).Msg("tranlation error")
}
}

Expand Down

0 comments on commit 5832a4e

Please sign in to comment.