gopkg.in/alecthomas/gometalinter.v3@v3.0.0/_linters/src/github.com/stretchr/objx/conversions.go (about)

     1  package objx
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/base64"
     6  	"encoding/json"
     7  	"errors"
     8  	"net/url"
     9  	"strconv"
    10  )
    11  
    12  // SignatureSeparator is the character that is used to
    13  // separate the Base64 string from the security signature.
    14  const SignatureSeparator = "_"
    15  
    16  // URLValuesSliceKeySuffix is the character that is used to
    17  // specify a suffic for slices parsed by URLValues.
    18  // If the suffix is set to "[i]", then the index of the slice
    19  // is used in place of i
    20  // Ex: Suffix "[]" would have the form a[]=b&a[]=c
    21  // OR Suffix "[i]" would have the form a[0]=b&a[1]=c
    22  // OR Suffix "" would have the form a=b&a=c
    23  var urlValuesSliceKeySuffix = "[]"
    24  
    25  const (
    26  	URLValuesSliceKeySuffixEmpty = ""
    27  	URLValuesSliceKeySuffixArray = "[]"
    28  	URLValuesSliceKeySuffixIndex = "[i]"
    29  )
    30  
    31  // SetURLValuesSliceKeySuffix sets the character that is used to
    32  // specify a suffic for slices parsed by URLValues.
    33  // If the suffix is set to "[i]", then the index of the slice
    34  // is used in place of i
    35  // Ex: Suffix "[]" would have the form a[]=b&a[]=c
    36  // OR Suffix "[i]" would have the form a[0]=b&a[1]=c
    37  // OR Suffix "" would have the form a=b&a=c
    38  func SetURLValuesSliceKeySuffix(s string) error {
    39  	if s == URLValuesSliceKeySuffixEmpty || s == URLValuesSliceKeySuffixArray || s == URLValuesSliceKeySuffixIndex {
    40  		urlValuesSliceKeySuffix = s
    41  		return nil
    42  	}
    43  
    44  	return errors.New("objx: Invalid URLValuesSliceKeySuffix provided.")
    45  }
    46  
    47  // JSON converts the contained object to a JSON string
    48  // representation
    49  func (m Map) JSON() (string, error) {
    50  	result, err := json.Marshal(m)
    51  	if err != nil {
    52  		err = errors.New("objx: JSON encode failed with: " + err.Error())
    53  	}
    54  	return string(result), err
    55  }
    56  
    57  // MustJSON converts the contained object to a JSON string
    58  // representation and panics if there is an error
    59  func (m Map) MustJSON() string {
    60  	result, err := m.JSON()
    61  	if err != nil {
    62  		panic(err.Error())
    63  	}
    64  	return result
    65  }
    66  
    67  // Base64 converts the contained object to a Base64 string
    68  // representation of the JSON string representation
    69  func (m Map) Base64() (string, error) {
    70  	var buf bytes.Buffer
    71  
    72  	jsonData, err := m.JSON()
    73  	if err != nil {
    74  		return "", err
    75  	}
    76  
    77  	encoder := base64.NewEncoder(base64.StdEncoding, &buf)
    78  	_, _ = encoder.Write([]byte(jsonData))
    79  	_ = encoder.Close()
    80  
    81  	return buf.String(), nil
    82  }
    83  
    84  // MustBase64 converts the contained object to a Base64 string
    85  // representation of the JSON string representation and panics
    86  // if there is an error
    87  func (m Map) MustBase64() string {
    88  	result, err := m.Base64()
    89  	if err != nil {
    90  		panic(err.Error())
    91  	}
    92  	return result
    93  }
    94  
    95  // SignedBase64 converts the contained object to a Base64 string
    96  // representation of the JSON string representation and signs it
    97  // using the provided key.
    98  func (m Map) SignedBase64(key string) (string, error) {
    99  	base64, err := m.Base64()
   100  	if err != nil {
   101  		return "", err
   102  	}
   103  
   104  	sig := HashWithKey(base64, key)
   105  	return base64 + SignatureSeparator + sig, nil
   106  }
   107  
   108  // MustSignedBase64 converts the contained object to a Base64 string
   109  // representation of the JSON string representation and signs it
   110  // using the provided key and panics if there is an error
   111  func (m Map) MustSignedBase64(key string) string {
   112  	result, err := m.SignedBase64(key)
   113  	if err != nil {
   114  		panic(err.Error())
   115  	}
   116  	return result
   117  }
   118  
   119  /*
   120  	URL Query
   121  	------------------------------------------------
   122  */
   123  
   124  // URLValues creates a url.Values object from an Obj. This
   125  // function requires that the wrapped object be a map[string]interface{}
   126  func (m Map) URLValues() url.Values {
   127  	vals := make(url.Values)
   128  
   129  	m.parseURLValues(m, vals, "")
   130  
   131  	return vals
   132  }
   133  
   134  func (m Map) parseURLValues(queryMap Map, vals url.Values, key string) {
   135  	useSliceIndex := false
   136  	if urlValuesSliceKeySuffix == "[i]" {
   137  		useSliceIndex = true
   138  	}
   139  
   140  	for k, v := range queryMap {
   141  		val := &Value{data: v}
   142  		switch {
   143  		case val.IsObjxMap():
   144  			if key == "" {
   145  				m.parseURLValues(val.ObjxMap(), vals, k)
   146  			} else {
   147  				m.parseURLValues(val.ObjxMap(), vals, key+"["+k+"]")
   148  			}
   149  		case val.IsObjxMapSlice():
   150  			sliceKey := k
   151  			if key != "" {
   152  				sliceKey = key + "[" + k + "]"
   153  			}
   154  
   155  			if useSliceIndex {
   156  				for i, sv := range val.MustObjxMapSlice() {
   157  					sk := sliceKey + "[" + strconv.FormatInt(int64(i), 10) + "]"
   158  					m.parseURLValues(sv, vals, sk)
   159  				}
   160  			} else {
   161  				sliceKey = sliceKey + urlValuesSliceKeySuffix
   162  				for _, sv := range val.MustObjxMapSlice() {
   163  					m.parseURLValues(sv, vals, sliceKey)
   164  				}
   165  			}
   166  		case val.IsMSISlice():
   167  			sliceKey := k
   168  			if key != "" {
   169  				sliceKey = key + "[" + k + "]"
   170  			}
   171  
   172  			if useSliceIndex {
   173  				for i, sv := range val.MustMSISlice() {
   174  					sk := sliceKey + "[" + strconv.FormatInt(int64(i), 10) + "]"
   175  					m.parseURLValues(New(sv), vals, sk)
   176  				}
   177  			} else {
   178  				sliceKey = sliceKey + urlValuesSliceKeySuffix
   179  				for _, sv := range val.MustMSISlice() {
   180  					m.parseURLValues(New(sv), vals, sliceKey)
   181  				}
   182  			}
   183  		case val.IsStrSlice(), val.IsBoolSlice(),
   184  			val.IsFloat32Slice(), val.IsFloat64Slice(),
   185  			val.IsIntSlice(), val.IsInt8Slice(), val.IsInt16Slice(), val.IsInt32Slice(), val.IsInt64Slice(),
   186  			val.IsUintSlice(), val.IsUint8Slice(), val.IsUint16Slice(), val.IsUint32Slice(), val.IsUint64Slice():
   187  
   188  			sliceKey := k
   189  			if key != "" {
   190  				sliceKey = key + "[" + k + "]"
   191  			}
   192  
   193  			if useSliceIndex {
   194  				for i, sv := range val.StringSlice() {
   195  					sk := sliceKey + "[" + strconv.FormatInt(int64(i), 10) + "]"
   196  					vals.Set(sk, sv)
   197  				}
   198  			} else {
   199  				sliceKey = sliceKey + urlValuesSliceKeySuffix
   200  				vals[sliceKey] = val.StringSlice()
   201  			}
   202  
   203  		default:
   204  			if key == "" {
   205  				vals.Set(k, val.String())
   206  			} else {
   207  				vals.Set(key+"["+k+"]", val.String())
   208  			}
   209  		}
   210  	}
   211  }
   212  
   213  // URLQuery gets an encoded URL query representing the given
   214  // Obj. This function requires that the wrapped object be a
   215  // map[string]interface{}
   216  func (m Map) URLQuery() (string, error) {
   217  	return m.URLValues().Encode(), nil
   218  }