diff --git a/deserialize/deserialize.go b/deserialize/deserialize.go index b2dc0f3..3004e5e 100644 --- a/deserialize/deserialize.go +++ b/deserialize/deserialize.go @@ -743,7 +743,9 @@ func makeStructDeserializerFromReflect(path string, typ reflect.Type, options in mightValidate := resultPtr.Interface() if validator, ok := mightValidate.(validation.Validator); ok { err = validator.Validate() - if err != nil { + if err == nil { + outPtr.Set(result) // Note: Wait, are we copying everything here? + } else { // Validation error, abort struct construction, wrap the error so that we can catch it. err = validation.WrapError(path, err) result = reflect.Zero(typ) diff --git a/deserialize/deserialize_test.go b/deserialize/deserialize_test.go index cd709fe..55eb3cf 100644 --- a/deserialize/deserialize_test.go +++ b/deserialize/deserialize_test.go @@ -1580,3 +1580,26 @@ func TestKVDeserializeUnderlyingPrimitiveSlices(t *testing.T) { assert.NilError(t, err) assert.DeepEqual(t, *deserialized, sample) } + +// --- Testing side-effects during validation. + +type TestValidateModifyStruct struct { + A string +} + +func (t *TestValidateModifyStruct) Validate() error { + t.A = strings.ToLower(t.A) + return nil +} + +func TestValidateModify(t *testing.T) { + kvlist := make(map[string][]string) + kvlist["A"] = []string{"ABC"} + + deserializer, err := deserialize.MakeKVListDeserializer[TestValidateModifyStruct](deserialize.JSONOptions("")) + assert.NilError(t, err) + deserialized, err := deserializer.DeserializeKVList(kvlist) + assert.NilError(t, err) + fmt.Println(*deserialized) + assert.Equal(t, deserialized.A, "abc") +}