github.com/IBM-Blockchain/fabric-operator@v1.0.4/pkg/util/merge/merge.go (about)

     1  /*
     2   * Copyright contributors to the Hyperledger Fabric Operator project
     3   *
     4   * SPDX-License-Identifier: Apache-2.0
     5   *
     6   * Licensed under the Apache License, Version 2.0 (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at:
     9   *
    10   * 	  http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing, software
    13   * distributed under the License is distributed on an "AS IS" BASIS,
    14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15   * See the License for the specific language governing permissions and
    16   * limitations under the License.
    17   */
    18  
    19  package merge
    20  
    21  import (
    22  	"reflect"
    23  
    24  	"github.com/imdario/mergo"
    25  )
    26  
    27  // BoolTransformer will overwrite the behavior of merging boolean pointers such that
    28  // a pointer to 'false' is not considered an empty value. Therefore, if the src's
    29  // boolean pointer is not nil, it should overwrite the dst's boolean pointer value.
    30  //
    31  // This is required because the default behavior of mergo is to treat a pointer to 'false'
    32  // as an empty value, which prevents boolean fields to be set from 'true' to 'false' if needed.
    33  type BoolTransformer struct{}
    34  
    35  func (t BoolTransformer) Transformer(typ reflect.Type) func(dst, src reflect.Value) error {
    36  	falseVal := false
    37  	if typ == reflect.TypeOf(&falseVal) {
    38  		return func(dst, src reflect.Value) error {
    39  			if dst.CanSet() && !src.IsNil() {
    40  				dst.Set(src)
    41  			}
    42  			return nil
    43  		}
    44  	}
    45  	return nil
    46  }
    47  
    48  // TODO: Can add transformers for other primitive types (i.e. int, string) if we run into
    49  // issues setting non-empty primitive fields back to empty values - see unit tests for
    50  // use cases.
    51  
    52  // WithOverwrite encapsulates mergo's implementation of MergeWithOverwrite with our
    53  // custom transformers.
    54  func WithOverwrite(dst interface{}, src interface{}) error {
    55  	err := mergo.MergeWithOverwrite(dst, src, mergo.WithTransformers(BoolTransformer{}))
    56  	if err != nil {
    57  		return err
    58  	}
    59  
    60  	return nil
    61  }