github.com/greenpau/go-authcrunch@v1.1.4/pkg/tagging/tag.go (about)

     1  // Copyright 2022 Paul Greenberg greenpau@outlook.com
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package tagging
    16  
    17  import (
    18  	"fmt"
    19  )
    20  
    21  // Tag represents key-value tag.
    22  type Tag struct {
    23  	Key   string `json:"key,omitempty" xml:"key,omitempty" yaml:"key,omitempty"`
    24  	Value string `json:"value,omitempty" xml:"value,omitempty" yaml:"value,omitempty"`
    25  }
    26  
    27  // NewTag returns an instance of Tag
    28  func NewTag(key, value string) *Tag {
    29  	return &Tag{Key: key, Value: value}
    30  }
    31  
    32  func extractStringFromInteface(i interface{}) (string, error) {
    33  	switch v := i.(type) {
    34  	case string:
    35  		return v, nil
    36  	}
    37  	return "", fmt.Errorf("not string")
    38  }
    39  
    40  func extractMapKeyFromInteface(k string, m map[string]interface{}) (string, error) {
    41  	if v, exists := m[k]; exists {
    42  		key, err := extractStringFromInteface(v)
    43  		if err != nil {
    44  			return "", fmt.Errorf("tag %s is malformed: %v", k, err)
    45  		}
    46  		return key, nil
    47  	}
    48  
    49  	return "", fmt.Errorf("tag has no %s", k)
    50  }
    51  
    52  func extractTagFromMap(m map[string]interface{}) (*Tag, error) {
    53  	if m == nil {
    54  		return nil, fmt.Errorf("tag is nil")
    55  	}
    56  	key, err := extractMapKeyFromInteface("key", m)
    57  	if err != nil {
    58  		return nil, err
    59  	}
    60  	value, err := extractMapKeyFromInteface("value", m)
    61  	if err != nil {
    62  		return nil, err
    63  	}
    64  	tag := &Tag{
    65  		Key:   key,
    66  		Value: value,
    67  	}
    68  	return tag, nil
    69  }
    70  
    71  // ExtractTags extracts tags fom a map.
    72  func ExtractTags(m map[string]interface{}) ([]*Tag, error) {
    73  	tags := []*Tag{}
    74  	if m == nil {
    75  		return tags, fmt.Errorf("input data is nil")
    76  	}
    77  
    78  	extractedTags, tagExists := m["tags"]
    79  	if !tagExists {
    80  		return tags, nil
    81  	}
    82  
    83  	switch vs := extractedTags.(type) {
    84  	case []interface{}:
    85  		for _, extractedTag := range vs {
    86  
    87  			switch v := extractedTag.(type) {
    88  			case map[string]interface{}:
    89  				tag, err := extractTagFromMap(v)
    90  				if err != nil {
    91  					return tags, fmt.Errorf("malformed extracted tags: %v", err)
    92  				}
    93  				tags = append(tags, tag)
    94  			default:
    95  				return tags, fmt.Errorf("extracted tag is %T", extractedTag)
    96  			}
    97  		}
    98  	default:
    99  		return tags, fmt.Errorf("extracted tags are %T", vs)
   100  	}
   101  	return tags, nil
   102  }
   103  
   104  // ExtractLabels extracts labels fom a map.
   105  func ExtractLabels(m map[string]interface{}) ([]string, error) {
   106  	labels := []string{}
   107  	if m == nil {
   108  		return labels, fmt.Errorf("input data is nil")
   109  	}
   110  
   111  	extractedLabels, labelsExists := m["labels"]
   112  	if !labelsExists {
   113  		return labels, nil
   114  	}
   115  
   116  	switch vs := extractedLabels.(type) {
   117  	case []interface{}:
   118  		for _, extractedLabel := range vs {
   119  
   120  			switch label := extractedLabel.(type) {
   121  			case string:
   122  				labels = append(labels, label)
   123  			default:
   124  				return labels, fmt.Errorf("extracted label is %T", label)
   125  			}
   126  		}
   127  	default:
   128  		return labels, fmt.Errorf("extracted labels are %T", vs)
   129  	}
   130  	return labels, nil
   131  }