github.com/cobalt77/jfrog-client-go@v0.14.5/artifactory/services/utils/properties.go (about)

     1  package utils
     2  
     3  import (
     4  	"encoding/base64"
     5  	"errors"
     6  	"fmt"
     7  	"net/url"
     8  	"strings"
     9  
    10  	"github.com/cobalt77/jfrog-client-go/utils/errorutils"
    11  )
    12  
    13  type PropertyParseOptions int
    14  
    15  const (
    16  	// Parsing properties
    17  	SplitCommas PropertyParseOptions = iota
    18  	JoinCommas
    19  )
    20  
    21  type Properties struct {
    22  	Properties []Property
    23  }
    24  
    25  type Property struct {
    26  	Key   string
    27  	Value string
    28  }
    29  
    30  // Parsing properties string to Properties struct.
    31  func ParseProperties(propStr string, option PropertyParseOptions) (*Properties, error) {
    32  	props := &Properties{}
    33  	propList := strings.Split(propStr, ";")
    34  	for _, prop := range propList {
    35  		if prop == "" {
    36  			continue
    37  		}
    38  
    39  		key, values, err := splitProp(prop)
    40  		if err != nil {
    41  			return props, err
    42  		}
    43  
    44  		switch option {
    45  		case SplitCommas:
    46  			splitedValues := strings.Split(values, ",")
    47  			for i, val := range splitedValues {
    48  				// If "\" is found, then it means that the original string contains the "\," which indicate this "," is part of the value
    49  				// and not a sperator
    50  				if strings.HasSuffix(val, "\\") && i+1 < len(splitedValues) {
    51  					splitedValues[i+1] = val[:len(val)-1] + "," + splitedValues[i+1]
    52  				} else {
    53  					props.Properties = append(props.Properties, Property{key, val})
    54  				}
    55  			}
    56  		case JoinCommas:
    57  			props.Properties = append(props.Properties, Property{key, values})
    58  		}
    59  	}
    60  	return props, nil
    61  }
    62  
    63  func (props *Properties) ToEncodedString() string {
    64  	encodedProps := ""
    65  	for _, v := range props.Properties {
    66  		jointProp := fmt.Sprintf("%s=%s", url.QueryEscape(v.Key), url.QueryEscape(v.Value))
    67  		encodedProps = fmt.Sprintf("%s;%s", encodedProps, jointProp)
    68  	}
    69  	// Remove leading semicolon
    70  	if strings.HasPrefix(encodedProps, ";") {
    71  		return encodedProps[1:]
    72  	}
    73  	return encodedProps
    74  }
    75  
    76  func (props *Properties) ToHeadersMap() map[string]string {
    77  	headers := map[string]string{}
    78  	for _, v := range props.Properties {
    79  		headers[v.Key] = base64.StdEncoding.EncodeToString([]byte(v.Value))
    80  	}
    81  	return headers
    82  }
    83  
    84  // Convert properties from Slice to map that build promotion REST API requires
    85  func (props *Properties) ToBuildPromoteMap() map[string][]string {
    86  	buildPromote := map[string][]string{}
    87  	for _, prop := range props.Properties {
    88  		buildPromote[prop.Key] = []string{prop.Value}
    89  	}
    90  	return buildPromote
    91  }
    92  
    93  // Split properties string of format key=value to key value strings
    94  func splitProp(prop string) (string, string, error) {
    95  	splitIndex := strings.Index(prop, "=")
    96  	if splitIndex < 1 || len(prop[splitIndex+1:]) < 1 {
    97  		err := errorutils.CheckError(errors.New("Invalid property: " + prop))
    98  		return "", "", err
    99  	}
   100  	return prop[:splitIndex], prop[splitIndex+1:], nil
   101  }