...

Source file src/k8s.io/apimachinery/pkg/util/managedfields/internal/pathelement.go

Documentation: k8s.io/apimachinery/pkg/util/managedfields/internal

     1  /*
     2  Copyright 2018 The Kubernetes 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 internal
    18  
    19  import (
    20  	"encoding/json"
    21  	"errors"
    22  	"fmt"
    23  	"strconv"
    24  	"strings"
    25  
    26  	"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
    27  	"sigs.k8s.io/structured-merge-diff/v4/value"
    28  )
    29  
    30  const (
    31  	// Field indicates that the content of this path element is a field's name
    32  	Field = "f"
    33  
    34  	// Value indicates that the content of this path element is a field's value
    35  	Value = "v"
    36  
    37  	// Index indicates that the content of this path element is an index in an array
    38  	Index = "i"
    39  
    40  	// Key indicates that the content of this path element is a key value map
    41  	Key = "k"
    42  
    43  	// Separator separates the type of a path element from the contents
    44  	Separator = ":"
    45  )
    46  
    47  // NewPathElement parses a serialized path element
    48  func NewPathElement(s string) (fieldpath.PathElement, error) {
    49  	split := strings.SplitN(s, Separator, 2)
    50  	if len(split) < 2 {
    51  		return fieldpath.PathElement{}, fmt.Errorf("missing colon: %v", s)
    52  	}
    53  	switch split[0] {
    54  	case Field:
    55  		return fieldpath.PathElement{
    56  			FieldName: &split[1],
    57  		}, nil
    58  	case Value:
    59  		val, err := value.FromJSON([]byte(split[1]))
    60  		if err != nil {
    61  			return fieldpath.PathElement{}, err
    62  		}
    63  		return fieldpath.PathElement{
    64  			Value: &val,
    65  		}, nil
    66  	case Index:
    67  		i, err := strconv.Atoi(split[1])
    68  		if err != nil {
    69  			return fieldpath.PathElement{}, err
    70  		}
    71  		return fieldpath.PathElement{
    72  			Index: &i,
    73  		}, nil
    74  	case Key:
    75  		kv := map[string]json.RawMessage{}
    76  		err := json.Unmarshal([]byte(split[1]), &kv)
    77  		if err != nil {
    78  			return fieldpath.PathElement{}, err
    79  		}
    80  		fields := value.FieldList{}
    81  		for k, v := range kv {
    82  			b, err := json.Marshal(v)
    83  			if err != nil {
    84  				return fieldpath.PathElement{}, err
    85  			}
    86  			val, err := value.FromJSON(b)
    87  			if err != nil {
    88  				return fieldpath.PathElement{}, err
    89  			}
    90  
    91  			fields = append(fields, value.Field{
    92  				Name:  k,
    93  				Value: val,
    94  			})
    95  		}
    96  		return fieldpath.PathElement{
    97  			Key: &fields,
    98  		}, nil
    99  	default:
   100  		// Ignore unknown key types
   101  		return fieldpath.PathElement{}, nil
   102  	}
   103  }
   104  
   105  // PathElementString serializes a path element
   106  func PathElementString(pe fieldpath.PathElement) (string, error) {
   107  	switch {
   108  	case pe.FieldName != nil:
   109  		return Field + Separator + *pe.FieldName, nil
   110  	case pe.Key != nil:
   111  		kv := map[string]json.RawMessage{}
   112  		for _, k := range *pe.Key {
   113  			b, err := value.ToJSON(k.Value)
   114  			if err != nil {
   115  				return "", err
   116  			}
   117  			m := json.RawMessage{}
   118  			err = json.Unmarshal(b, &m)
   119  			if err != nil {
   120  				return "", err
   121  			}
   122  			kv[k.Name] = m
   123  		}
   124  		b, err := json.Marshal(kv)
   125  		if err != nil {
   126  			return "", err
   127  		}
   128  		return Key + ":" + string(b), nil
   129  	case pe.Value != nil:
   130  		b, err := value.ToJSON(*pe.Value)
   131  		if err != nil {
   132  			return "", err
   133  		}
   134  		return Value + ":" + string(b), nil
   135  	case pe.Index != nil:
   136  		return Index + ":" + strconv.Itoa(*pe.Index), nil
   137  	default:
   138  		return "", errors.New("Invalid type of path element")
   139  	}
   140  }
   141  

View as plain text