github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/common/struct.go (about)

     1  // This file is part of the Smart Home
     2  // Program complex distribution https://github.com/e154/smart-home
     3  // Copyright (C) 2024, Filippov Alex
     4  //
     5  // This library is free software: you can redistribute it and/or
     6  // modify it under the terms of the GNU Lesser General Public
     7  // License as published by the Free Software Foundation; either
     8  // version 3 of the License, or (at your option) any later version.
     9  //
    10  // This library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13  // Library General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public
    16  // License along with this library.  If not, see
    17  // <https://www.gnu.org/licenses/>.
    18  
    19  package common
    20  
    21  import (
    22  	"fmt"
    23  	"reflect"
    24  
    25  	"github.com/iancoleman/strcase"
    26  	"github.com/pkg/errors"
    27  )
    28  
    29  func SetField(obj interface{}, name string, value interface{}) error {
    30  	structValue := reflect.ValueOf(obj).Elem()
    31  	structFieldValue := structValue.FieldByName(strcase.ToCamel(name))
    32  
    33  	if !structFieldValue.IsValid() {
    34  		return fmt.Errorf("No such field: %s in obj", name)
    35  	}
    36  
    37  	if !structFieldValue.CanSet() {
    38  		return fmt.Errorf("Cannot set %s field value", name)
    39  	}
    40  
    41  	structFieldType := structFieldValue.Type()
    42  	val := reflect.ValueOf(value)
    43  	if structFieldType != val.Type() {
    44  		invalidTypeError := errors.New("Provided value type didn't match obj field type")
    45  		return invalidTypeError
    46  	}
    47  
    48  	structFieldValue.Set(val)
    49  	return nil
    50  }
    51  
    52  func SetFields(obj interface{}, params map[string]interface{}) (err error) {
    53  	for k, v := range params {
    54  		if err = SetField(obj, k, v); err != nil {
    55  			return
    56  		}
    57  	}
    58  	return
    59  }