...

Source file src/github.com/go-openapi/strfmt/ulid.go

Documentation: github.com/go-openapi/strfmt

     1  package strfmt
     2  
     3  import (
     4  	cryptorand "crypto/rand"
     5  	"database/sql/driver"
     6  	"encoding/json"
     7  	"errors"
     8  	"fmt"
     9  	"io"
    10  	"sync"
    11  
    12  	"github.com/oklog/ulid"
    13  	"go.mongodb.org/mongo-driver/bson"
    14  )
    15  
    16  // ULID represents a ulid string format
    17  // ref:
    18  //
    19  //	https://github.com/ulid/spec
    20  //
    21  // impl:
    22  //
    23  //	https://github.com/oklog/ulid
    24  //
    25  // swagger:strfmt ulid
    26  type ULID struct {
    27  	ulid.ULID
    28  }
    29  
    30  var (
    31  	ulidEntropyPool = sync.Pool{
    32  		New: func() interface{} {
    33  			return cryptorand.Reader
    34  		},
    35  	}
    36  
    37  	ULIDScanDefaultFunc = func(raw interface{}) (ULID, error) {
    38  		u := NewULIDZero()
    39  		switch x := raw.(type) {
    40  		case nil:
    41  			// zerp ulid
    42  			return u, nil
    43  		case string:
    44  			if x == "" {
    45  				// zero ulid
    46  				return u, nil
    47  			}
    48  			return u, u.UnmarshalText([]byte(x))
    49  		case []byte:
    50  			return u, u.UnmarshalText(x)
    51  		}
    52  
    53  		return u, fmt.Errorf("cannot sql.Scan() strfmt.ULID from: %#v: %w", raw, ulid.ErrScanValue)
    54  	}
    55  
    56  	// ULIDScanOverrideFunc allows you to override the Scan method of the ULID type
    57  	ULIDScanOverrideFunc = ULIDScanDefaultFunc
    58  
    59  	ULIDValueDefaultFunc = func(u ULID) (driver.Value, error) {
    60  		return driver.Value(u.String()), nil
    61  	}
    62  
    63  	// ULIDValueOverrideFunc allows you to override the Value method of the ULID type
    64  	ULIDValueOverrideFunc = ULIDValueDefaultFunc
    65  )
    66  
    67  func init() {
    68  	// register formats in the default registry:
    69  	//   - ulid
    70  	ulid := ULID{}
    71  	Default.Add("ulid", &ulid, IsULID)
    72  }
    73  
    74  // IsULID checks if provided string is ULID format
    75  // Be noticed that this function considers overflowed ULID as non-ulid.
    76  // For more details see https://github.com/ulid/spec
    77  func IsULID(str string) bool {
    78  	_, err := ulid.ParseStrict(str)
    79  	return err == nil
    80  }
    81  
    82  // ParseULID parses a string that represents an valid ULID
    83  func ParseULID(str string) (ULID, error) {
    84  	var u ULID
    85  
    86  	return u, u.UnmarshalText([]byte(str))
    87  }
    88  
    89  // NewULIDZero returns a zero valued ULID type
    90  func NewULIDZero() ULID {
    91  	return ULID{}
    92  }
    93  
    94  // NewULID generates new unique ULID value and a error if any
    95  func NewULID() (ULID, error) {
    96  	var u ULID
    97  
    98  	obj := ulidEntropyPool.Get()
    99  	entropy, ok := obj.(io.Reader)
   100  	if !ok {
   101  		return u, fmt.Errorf("failed to cast %+v to io.Reader", obj)
   102  	}
   103  
   104  	id, err := ulid.New(ulid.Now(), entropy)
   105  	if err != nil {
   106  		return u, err
   107  	}
   108  	ulidEntropyPool.Put(entropy)
   109  
   110  	u.ULID = id
   111  	return u, nil
   112  }
   113  
   114  // GetULID returns underlying instance of ULID
   115  func (u *ULID) GetULID() interface{} {
   116  	return u.ULID
   117  }
   118  
   119  // MarshalText returns this instance into text
   120  func (u ULID) MarshalText() ([]byte, error) {
   121  	return u.ULID.MarshalText()
   122  }
   123  
   124  // UnmarshalText hydrates this instance from text
   125  func (u *ULID) UnmarshalText(data []byte) error { // validation is performed later on
   126  	return u.ULID.UnmarshalText(data)
   127  }
   128  
   129  // Scan reads a value from a database driver
   130  func (u *ULID) Scan(raw interface{}) error {
   131  	ul, err := ULIDScanOverrideFunc(raw)
   132  	if err == nil {
   133  		*u = ul
   134  	}
   135  	return err
   136  }
   137  
   138  // Value converts a value to a database driver value
   139  func (u ULID) Value() (driver.Value, error) {
   140  	return ULIDValueOverrideFunc(u)
   141  }
   142  
   143  func (u ULID) String() string {
   144  	return u.ULID.String()
   145  }
   146  
   147  // MarshalJSON returns the ULID as JSON
   148  func (u ULID) MarshalJSON() ([]byte, error) {
   149  	return json.Marshal(u.String())
   150  }
   151  
   152  // UnmarshalJSON sets the ULID from JSON
   153  func (u *ULID) UnmarshalJSON(data []byte) error {
   154  	if string(data) == jsonNull {
   155  		return nil
   156  	}
   157  	var ustr string
   158  	if err := json.Unmarshal(data, &ustr); err != nil {
   159  		return err
   160  	}
   161  	id, err := ulid.ParseStrict(ustr)
   162  	if err != nil {
   163  		return fmt.Errorf("couldn't parse JSON value as ULID: %w", err)
   164  	}
   165  	u.ULID = id
   166  	return nil
   167  }
   168  
   169  // MarshalBSON document from this value
   170  func (u ULID) MarshalBSON() ([]byte, error) {
   171  	return bson.Marshal(bson.M{"data": u.String()})
   172  }
   173  
   174  // UnmarshalBSON document into this value
   175  func (u *ULID) UnmarshalBSON(data []byte) error {
   176  	var m bson.M
   177  	if err := bson.Unmarshal(data, &m); err != nil {
   178  		return err
   179  	}
   180  
   181  	if ud, ok := m["data"].(string); ok {
   182  		id, err := ulid.ParseStrict(ud)
   183  		if err != nil {
   184  			return fmt.Errorf("couldn't parse bson bytes as ULID: %w", err)
   185  		}
   186  		u.ULID = id
   187  		return nil
   188  	}
   189  	return errors.New("couldn't unmarshal bson bytes as ULID")
   190  }
   191  
   192  // DeepCopyInto copies the receiver and writes its value into out.
   193  func (u *ULID) DeepCopyInto(out *ULID) {
   194  	*out = *u
   195  }
   196  
   197  // DeepCopy copies the receiver into a new ULID.
   198  func (u *ULID) DeepCopy() *ULID {
   199  	if u == nil {
   200  		return nil
   201  	}
   202  	out := new(ULID)
   203  	u.DeepCopyInto(out)
   204  	return out
   205  }
   206  
   207  // GobEncode implements the gob.GobEncoder interface.
   208  func (u ULID) GobEncode() ([]byte, error) {
   209  	return u.ULID.MarshalBinary()
   210  }
   211  
   212  // GobDecode implements the gob.GobDecoder interface.
   213  func (u *ULID) GobDecode(data []byte) error {
   214  	return u.ULID.UnmarshalBinary(data)
   215  }
   216  
   217  // MarshalBinary implements the encoding.BinaryMarshaler interface.
   218  func (u ULID) MarshalBinary() ([]byte, error) {
   219  	return u.ULID.MarshalBinary()
   220  }
   221  
   222  // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
   223  func (u *ULID) UnmarshalBinary(data []byte) error {
   224  	return u.ULID.UnmarshalBinary(data)
   225  }
   226  
   227  // Equal checks if two ULID instances are equal by their underlying type
   228  func (u ULID) Equal(other ULID) bool {
   229  	return u.ULID == other.ULID
   230  }
   231  

View as plain text