fix(options): converting to go types

This commit is contained in:
Denis Gukov 2024-07-07 23:53:32 +05:00
parent 8796cfd8f5
commit 3ce78b11fd
3 changed files with 90 additions and 70 deletions

View File

@ -19,35 +19,32 @@ func getUser(w http.ResponseWriter, r *http.Request) {
return
}
type app struct {
ID string `json:"id"`
Title string `json:"title"`
Icon string `json:"icon"`
}
var user struct {
db.User
CanCreateProject bool `json:"can_create_project"`
//Apps []db.AppPublic `json:"apps"`
CanCreateProject bool `json:"can_create_project"`
Apps []app `json:"apps"`
}
user.User = *context.Get(r, "user").(*db.User)
user.CanCreateProject = user.Admin || util.Config.NonAdminCanCreateProject
//str, err := helpers.Store(r).GetOption("apps")
//if err != nil {
// w.WriteHeader(http.StatusInternalServerError)
// return
//}
for k, a := range util.Config.Apps {
if !a.Active {
continue
}
//var apps []db.App
//err = json.Unmarshal([]byte(str), &apps)
//if err != nil {
// w.WriteHeader(http.StatusInternalServerError)
// return
//}
//
//for _, app := range apps {
// if app.Mode == db.AppActive {
// user.Apps = append(user.Apps, app.AppPublic)
//
// }
//}
user.Apps = append(user.Apps, app{
ID: k,
Title: a.Title,
Icon: a.Icon,
})
}
helpers.WriteJSON(w, http.StatusOK, user)
}

View File

@ -50,56 +50,68 @@ func assignMapToStructRecursive(m map[string]interface{}, structValue reflect.Va
fieldValue := structValue.FieldByName(field.Name)
if fieldValue.CanSet() {
val := reflect.ValueOf(value)
switch fieldValue.Kind() {
case reflect.Struct:
// Handle nested struct
if val.Kind() == reflect.Map {
mapValue, ok := value.(map[string]interface{})
if !ok {
return fmt.Errorf("cannot assign value of type %T to field %s of type %s", value, field.Name, field.Type)
}
err := assignMapToStructRecursive(mapValue, fieldValue)
if err != nil {
return err
}
} else {
if val.Kind() != reflect.Map {
return fmt.Errorf("expected map for nested struct field %s but got %T", field.Name, value)
}
mapValue, ok := value.(map[string]interface{})
if !ok {
return fmt.Errorf("cannot assign value of type %T to field %s of type %s", value, field.Name, field.Type)
}
err := assignMapToStructRecursive(mapValue, fieldValue)
if err != nil {
return err
}
case reflect.Map:
// Handle map
if val.Kind() == reflect.Map {
mapValue := reflect.MakeMap(fieldValue.Type())
for _, key := range val.MapKeys() {
mapElemValue := val.MapIndex(key)
mapElemType := fieldValue.Type().Elem()
mapElem := reflect.New(mapElemType).Elem()
if val.Kind() != reflect.Map {
return fmt.Errorf("expected map for field %s but got %T", field.Name, value)
}
mapValue := reflect.MakeMap(fieldValue.Type())
for _, key := range val.MapKeys() {
mapElemValue := val.MapIndex(key)
mapElemType := fieldValue.Type().Elem()
mapElem := reflect.New(mapElemType).Elem()
if mapElemType.Kind() == reflect.Struct {
if err := assignMapToStructRecursive(mapElemValue.Interface().(map[string]interface{}), mapElem); err != nil {
return err
}
if mapElemType.Kind() == reflect.Struct {
if err := assignMapToStructRecursive(mapElemValue.Interface().(map[string]interface{}), mapElem); err != nil {
return err
}
} else {
if mapElemValue.Type().ConvertibleTo(mapElemType) {
mapElem.Set(mapElemValue.Convert(mapElemType))
} else {
if mapElemValue.Type().ConvertibleTo(mapElemType) {
mapElem.Set(mapElemValue.Convert(mapElemType))
} else {
newVal, converted := util.CastValueToKind(mapElemValue.Interface(), mapElemType.Kind())
if !converted {
return fmt.Errorf("cannot assign value of type %s to map element of type %s",
mapElemValue.Type(), mapElemType)
}
mapElem.Set(reflect.ValueOf(newVal))
}
mapValue.SetMapIndex(key, mapElem)
}
fieldValue.Set(mapValue)
} else {
return fmt.Errorf("expected map for field %s but got %T", field.Name, value)
mapValue.SetMapIndex(key, mapElem)
}
fieldValue.Set(mapValue)
default:
// Handle simple types
if val.Type().ConvertibleTo(fieldValue.Type()) {
fieldValue.Set(val.Convert(fieldValue.Type()))
} else {
return fmt.Errorf("cannot assign value of type %s to field %s of type %s",
val.Type(), field.Name, fieldValue.Type())
newVal, converted := util.CastValueToKind(val.Interface(), fieldValue.Type().Kind())
if !converted {
return fmt.Errorf("cannot assign value of type %s to map element of type %s",
val.Type(), val)
}
fieldValue.Set(reflect.ValueOf(newVal))
}
}
}

View File

@ -394,28 +394,39 @@ func castStringToBool(value string) bool {
}
func CastValueToKind(value interface{}, kind reflect.Kind) (res interface{}, ok bool) {
res = value
switch kind {
case reflect.Int:
if reflect.ValueOf(value).Kind() != reflect.Int {
res = castStringToInt(fmt.Sprintf("%v", reflect.ValueOf(value)))
ok = true
}
case reflect.Bool:
if reflect.ValueOf(value).Kind() != reflect.Bool {
res = castStringToBool(fmt.Sprintf("%v", reflect.ValueOf(value)))
ok = true
}
case reflect.Map:
if reflect.ValueOf(value).Kind() == reflect.String {
mapValue := make(map[string]string)
err := json.Unmarshal([]byte(value.(string)), &mapValue)
if err != nil {
panic(err)
}
res = mapValue
ok = true
}
}
return
}
func setConfigValue(attribute reflect.Value, value interface{}) {
if attribute.IsValid() {
switch attribute.Kind() {
case reflect.Int:
if reflect.ValueOf(value).Kind() != reflect.Int {
value = castStringToInt(fmt.Sprintf("%v", reflect.ValueOf(value)))
}
case reflect.Bool:
if reflect.ValueOf(value).Kind() != reflect.Bool {
value = castStringToBool(fmt.Sprintf("%v", reflect.ValueOf(value)))
}
case reflect.Map:
if reflect.ValueOf(value).Kind() == reflect.String {
mapValue := make(map[string]string)
err := json.Unmarshal([]byte(value.(string)), &mapValue)
if err != nil {
panic(err)
}
value = mapValue
}
}
value, _ = CastValueToKind(value, attribute.Kind())
attribute.Set(reflect.ValueOf(value))
} else {
panic(fmt.Errorf("got non-existent config attribute"))