Skip to content
Snippets Groups Projects
Commit 22b236bd authored by Cornel Rautenbach's avatar Cornel Rautenbach
Browse files

Use Scan() method before json.Unmarshal for param values

parent b20650e1
No related branches found
No related tags found
No related merge requests found
package struct_utils package struct_utils
import ( import (
"database/sql"
"encoding/csv" "encoding/csv"
"encoding/json" "encoding/json"
"reflect" "reflect"
...@@ -283,19 +284,34 @@ func unmarshalValue(v interface{}, t reflect.Type) (reflect.Value, error) { ...@@ -283,19 +284,34 @@ func unmarshalValue(v interface{}, t reflect.Type) (reflect.Value, error) {
newValuePtr := reflect.New(t) newValuePtr := reflect.New(t)
if reflect.ValueOf(v).Type().AssignableTo(t) { if reflect.ValueOf(v).Type().AssignableTo(t) {
newValuePtr.Elem().Set(reflect.ValueOf(v)) //can assign as is newValuePtr.Elem().Set(reflect.ValueOf(v)) //can assign as is
} else { return newValuePtr.Elem(), nil
}
//needs conversion //needs conversion
s, ok := v.(string) s, ok := v.(string)
if !ok { if !ok {
jsonValue, _ := json.Marshal(v) jsonValue, _ := json.Marshal(v)
s = string(jsonValue) s = string(jsonValue)
} }
//is string value, unmarshal as quoted or unquoted JSON value
if err := json.Unmarshal([]byte("\""+s+"\""), newValuePtr.Interface()); err != nil { //now we have string value
if err := json.Unmarshal([]byte(s), newValuePtr.Interface()); err != nil { if valueScanner, ok := newValuePtr.Interface().(sql.Scanner); ok {
return newValuePtr.Elem(), errors.Wrapf(err, "invalid \"%s\"", s) //if has scanner - prefer that over json unmarshal
//because we do not know if json expects quoted/unquoted for this type
//and if we try quoted, it fail, then try unquoted, we have two different
//errors one one of them will be kind of meaning nothing, but which?
//scanner should always take the value as typed, so let's try that first
if err := valueScanner.Scan(s); err == nil {
return newValuePtr.Elem(), nil
}
} }
//try JSON unmarshal as is else with quotes
if err := json.Unmarshal([]byte(s), newValuePtr.Interface()); err == nil {
return newValuePtr.Elem(), nil
} }
if err := json.Unmarshal([]byte("\""+s+"\""), newValuePtr.Interface()); err != nil {
return newValuePtr.Elem(), errors.Wrapf(err, "invalid \"%s\"", s)
} }
return newValuePtr.Elem(), nil return newValuePtr.Elem(), nil
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment