Платформа ЦРНП "Мирокод" для разработки проектов
https://git.mirocod.ru
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
221 lines
4.9 KiB
221 lines
4.9 KiB
package strfmt |
|
|
|
import ( |
|
cryptorand "crypto/rand" |
|
"database/sql/driver" |
|
"encoding/json" |
|
"errors" |
|
"fmt" |
|
"io" |
|
"sync" |
|
|
|
"github.com/oklog/ulid" |
|
"go.mongodb.org/mongo-driver/bson" |
|
) |
|
|
|
// ULID represents a ulid string format |
|
// ref: |
|
// https://github.com/ulid/spec |
|
// impl: |
|
// https://github.com/oklog/ulid |
|
// |
|
// swagger:strfmt ulid |
|
type ULID struct { |
|
ulid.ULID |
|
} |
|
|
|
var ( |
|
ulidEntropyPool = sync.Pool{ |
|
New: func() interface{} { |
|
return cryptorand.Reader |
|
}, |
|
} |
|
|
|
ULIDScanDefaultFunc = func(raw interface{}) (ULID, error) { |
|
var u ULID = NewULIDZero() |
|
switch x := raw.(type) { |
|
case nil: |
|
// zerp ulid |
|
return u, nil |
|
case string: |
|
if x == "" { |
|
// zero ulid |
|
return u, nil |
|
} |
|
return u, u.UnmarshalText([]byte(x)) |
|
case []byte: |
|
return u, u.UnmarshalText(x) |
|
} |
|
|
|
return u, fmt.Errorf("cannot sql.Scan() strfmt.ULID from: %#v: %w", raw, ulid.ErrScanValue) |
|
} |
|
|
|
// ULIDScanOverrideFunc allows you to override the Scan method of the ULID type |
|
ULIDScanOverrideFunc = ULIDScanDefaultFunc |
|
|
|
ULIDValueDefaultFunc = func(u ULID) (driver.Value, error) { |
|
return driver.Value(u.String()), nil |
|
} |
|
|
|
// ULIDValueOverrideFunc allows you to override the Value method of the ULID type |
|
ULIDValueOverrideFunc = ULIDValueDefaultFunc |
|
) |
|
|
|
func init() { |
|
// register formats in the default registry: |
|
// - ulid |
|
ulid := ULID{} |
|
Default.Add("ulid", &ulid, IsULID) |
|
} |
|
|
|
// IsULID checks if provided string is ULID format |
|
// Be noticed that this function considers overflowed ULID as non-ulid. |
|
// For more details see https://github.com/ulid/spec |
|
func IsULID(str string) bool { |
|
_, err := ulid.ParseStrict(str) |
|
return err == nil |
|
} |
|
|
|
// ParseULID parses a string that represents an valid ULID |
|
func ParseULID(str string) (ULID, error) { |
|
var u ULID |
|
|
|
return u, u.UnmarshalText([]byte(str)) |
|
} |
|
|
|
// NewULIDZero returns a zero valued ULID type |
|
func NewULIDZero() ULID { |
|
return ULID{} |
|
} |
|
|
|
// NewULID generates new unique ULID value and a error if any |
|
func NewULID() (u ULID, err error) { |
|
entropy := ulidEntropyPool.Get().(io.Reader) |
|
|
|
id, err := ulid.New(ulid.Now(), entropy) |
|
if err != nil { |
|
return u, err |
|
} |
|
ulidEntropyPool.Put(entropy) |
|
|
|
u.ULID = id |
|
return u, nil |
|
} |
|
|
|
// GetULID returns underlying instance of ULID |
|
func (u *ULID) GetULID() interface{} { |
|
return u.ULID |
|
} |
|
|
|
// MarshalText returns this instance into text |
|
func (u ULID) MarshalText() ([]byte, error) { |
|
return u.ULID.MarshalText() |
|
} |
|
|
|
// UnmarshalText hydrates this instance from text |
|
func (u *ULID) UnmarshalText(data []byte) error { // validation is performed later on |
|
return u.ULID.UnmarshalText(data) |
|
} |
|
|
|
// Scan reads a value from a database driver |
|
func (u *ULID) Scan(raw interface{}) error { |
|
ul, err := ULIDScanOverrideFunc(raw) |
|
if err == nil { |
|
*u = ul |
|
} |
|
return err |
|
} |
|
|
|
// Value converts a value to a database driver value |
|
func (u ULID) Value() (driver.Value, error) { |
|
return ULIDValueOverrideFunc(u) |
|
} |
|
|
|
func (u ULID) String() string { |
|
return u.ULID.String() |
|
} |
|
|
|
// MarshalJSON returns the ULID as JSON |
|
func (u ULID) MarshalJSON() ([]byte, error) { |
|
return json.Marshal(u.String()) |
|
} |
|
|
|
// UnmarshalJSON sets the ULID from JSON |
|
func (u *ULID) UnmarshalJSON(data []byte) error { |
|
if string(data) == jsonNull { |
|
return nil |
|
} |
|
var ustr string |
|
if err := json.Unmarshal(data, &ustr); err != nil { |
|
return err |
|
} |
|
id, err := ulid.ParseStrict(ustr) |
|
if err != nil { |
|
return fmt.Errorf("couldn't parse JSON value as ULID: %w", err) |
|
} |
|
u.ULID = id |
|
return nil |
|
} |
|
|
|
// MarshalBSON document from this value |
|
func (u ULID) MarshalBSON() ([]byte, error) { |
|
return bson.Marshal(bson.M{"data": u.String()}) |
|
} |
|
|
|
// UnmarshalBSON document into this value |
|
func (u *ULID) UnmarshalBSON(data []byte) error { |
|
var m bson.M |
|
if err := bson.Unmarshal(data, &m); err != nil { |
|
return err |
|
} |
|
|
|
if ud, ok := m["data"].(string); ok { |
|
id, err := ulid.ParseStrict(ud) |
|
if err != nil { |
|
return fmt.Errorf("couldn't parse bson bytes as ULID: %w", err) |
|
} |
|
u.ULID = id |
|
return nil |
|
} |
|
return errors.New("couldn't unmarshal bson bytes as ULID") |
|
} |
|
|
|
// DeepCopyInto copies the receiver and writes its value into out. |
|
func (u *ULID) DeepCopyInto(out *ULID) { |
|
*out = *u |
|
} |
|
|
|
// DeepCopy copies the receiver into a new ULID. |
|
func (u *ULID) DeepCopy() *ULID { |
|
if u == nil { |
|
return nil |
|
} |
|
out := new(ULID) |
|
u.DeepCopyInto(out) |
|
return out |
|
} |
|
|
|
// GobEncode implements the gob.GobEncoder interface. |
|
func (u ULID) GobEncode() ([]byte, error) { |
|
return u.ULID.MarshalBinary() |
|
} |
|
|
|
// GobDecode implements the gob.GobDecoder interface. |
|
func (u *ULID) GobDecode(data []byte) error { |
|
return u.ULID.UnmarshalBinary(data) |
|
} |
|
|
|
// MarshalBinary implements the encoding.BinaryMarshaler interface. |
|
func (u ULID) MarshalBinary() ([]byte, error) { |
|
return u.ULID.MarshalBinary() |
|
} |
|
|
|
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. |
|
func (u *ULID) UnmarshalBinary(data []byte) error { |
|
return u.ULID.UnmarshalBinary(data) |
|
} |
|
|
|
// Equal checks if two ULID instances are equal by their underlying type |
|
func (u ULID) Equal(other ULID) bool { |
|
return u.ULID == other.ULID |
|
}
|
|
|