knative.dev/pkg@v0.0.0-20260602142205-ac97e43f6622/apis/duck/patch.go (about)

     1  /*
     2  Copyright 2018 The Knative Authors
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package duck
    18  
    19  import (
    20  	"encoding/json"
    21  
    22  	jsonmergepatch "github.com/evanphx/json-patch/v5"
    23  	jsonpatch "gomodules.xyz/jsonpatch/v2"
    24  )
    25  
    26  func marshallBeforeAfter(before, after interface{}) ([]byte, []byte, error) {
    27  	rawBefore, err := json.Marshal(before)
    28  	if err != nil {
    29  		return nil, nil, err
    30  	}
    31  
    32  	rawAfter, err := json.Marshal(after)
    33  	if err != nil {
    34  		return rawBefore, nil, err
    35  	}
    36  
    37  	return rawBefore, rawAfter, nil
    38  }
    39  
    40  // CreateMergePatch creates a json merge patch as specified in
    41  // http://tools.ietf.org/html/draft-ietf-appsawg-json-merge-patch-07
    42  func CreateMergePatch(before, after interface{}) ([]byte, error) {
    43  	rawBefore, rawAfter, err := marshallBeforeAfter(before, after)
    44  	if err != nil {
    45  		return nil, err
    46  	}
    47  	return jsonmergepatch.CreateMergePatch(rawBefore, rawAfter)
    48  }
    49  
    50  // CreateBytePatch is a helper function that creates the same content as
    51  // CreatePatch, but returns in []byte format instead of JSONPatch.
    52  func CreateBytePatch(before, after interface{}) ([]byte, error) {
    53  	patch, err := CreatePatch(before, after)
    54  	if err != nil {
    55  		return nil, err
    56  	}
    57  	return patch.MarshalJSON()
    58  }
    59  
    60  // CreatePatch creates a patch as specified in http://jsonpatch.com/
    61  func CreatePatch(before, after interface{}) (JSONPatch, error) {
    62  	rawBefore, rawAfter, err := marshallBeforeAfter(before, after)
    63  	if err != nil {
    64  		return nil, err
    65  	}
    66  	return jsonpatch.CreatePatch(rawBefore, rawAfter)
    67  }
    68  
    69  type JSONPatch []jsonpatch.JsonPatchOperation
    70  
    71  func (p JSONPatch) MarshalJSON() ([]byte, error) {
    72  	return json.Marshal([]jsonpatch.JsonPatchOperation(p))
    73  }