cuelang.org/go@v0.10.1/pkg/uuid/uuid.go (about)

     1  // Copyright 2021 CUE Authors
     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 uuid defines functionality for creating UUIDs as defined in RFC 4122.
    16  //
    17  // Currently only Version 5 (SHA1) and Version 3 (MD5) are supported.
    18  package uuid
    19  
    20  import (
    21  	"fmt"
    22  	"math/big"
    23  	"regexp"
    24  	"sync"
    25  
    26  	"github.com/google/uuid"
    27  )
    28  
    29  var valid = sync.OnceValue(func() *regexp.Regexp {
    30  	return regexp.MustCompile("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$")
    31  })
    32  
    33  // TODO(mvdan): should Valid not use [uuid.Validate]?
    34  
    35  // Valid can be used to define a valid Valid.
    36  func Valid(s string) error {
    37  	if !valid().MatchString(string(s)) {
    38  		return fmt.Errorf("invalid UUID %q", s)
    39  	}
    40  	return nil
    41  }
    42  
    43  // Parse decodes s into a UUID or returns an error. Both the standard UUID forms
    44  // of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and
    45  // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the
    46  // Microsoft encoding {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} and the raw hex
    47  // encoding: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
    48  func Parse(s string) (string, error) {
    49  	x, err := uuid.Parse(s)
    50  	return string(x.String()), err
    51  }
    52  
    53  // String represents a 128-bit UUID value as a string.
    54  func ToString(x string) string {
    55  	return string(x)
    56  }
    57  
    58  // URN reports the canonical URN of a UUID.
    59  func URN(x string) (string, error) {
    60  	u, err := uuid.Parse(string(x))
    61  	if err != nil {
    62  		return "", err
    63  	}
    64  	return u.URN(), nil
    65  }
    66  
    67  // FromInt creates a UUID from an integer.
    68  //
    69  //	DNS:  uuid.FromInt(0x6ba7b810_9dad_11d1_80b4_00c04fd430c8)
    70  func FromInt(i *big.Int) (string, error) {
    71  	// must be uint128
    72  	var buf [16]byte
    73  	b := i.Bytes()
    74  	if len(b) < 16 {
    75  		copy(buf[16-len(b):], b)
    76  		b = buf[:]
    77  	}
    78  	u, err := uuid.FromBytes(b)
    79  	return string(u.String()), err
    80  }
    81  
    82  // ToInt represents a UUID string as a 128-bit value.
    83  func ToInt(x string) *big.Int {
    84  	var i big.Int
    85  	i.SetBytes([]byte(x[:]))
    86  	return &i
    87  }
    88  
    89  // Variant reports the UUID variant.
    90  func Variant(x string) (int, error) {
    91  	u, err := uuid.Parse(string(x))
    92  	if err != nil {
    93  		return 0, err
    94  	}
    95  	return int(u.Variant()), nil
    96  }
    97  
    98  // Version reports the UUID version.
    99  func Version(x string) (int, error) {
   100  	u, err := uuid.Parse(string(x))
   101  	if err != nil {
   102  		return 0, err
   103  	}
   104  	return int(u.Version()), nil
   105  }
   106  
   107  // SHA1 generates a version 5 UUID based on the supplied name space and data.
   108  func SHA1(space string, data []byte) (string, error) {
   109  	u, err := uuid.Parse(string(space))
   110  	if err != nil {
   111  		return "", err
   112  	}
   113  	return string(uuid.NewSHA1(u, data).String()), nil
   114  }
   115  
   116  // MD5 generates a version 3 UUID based on the supplied name space and data.
   117  // Use SHA1 instead if you can.
   118  func MD5(space string, data []byte) (string, error) {
   119  	u, err := uuid.Parse(string(space))
   120  	if err != nil {
   121  		return "", err
   122  	}
   123  	return string(uuid.NewMD5(u, data).String()), nil
   124  }