-
Notifications
You must be signed in to change notification settings - Fork 66
Expand file tree
/
Copy pathbson.go
More file actions
139 lines (120 loc) · 3.29 KB
/
bson.go
File metadata and controls
139 lines (120 loc) · 3.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers
// SPDX-License-Identifier: Apache-2.0
package strfmt
import (
"database/sql/driver"
"encoding/hex"
"encoding/json"
"fmt"
)
func init() { //nolint:gochecknoinits // registers bsonobjectid format in the default registry
var id ObjectId
Default.Add("bsonobjectid", &id, IsBSONObjectID)
}
// IsBSONObjectID returns true when the string is a valid BSON [ObjectId].
func IsBSONObjectID(str string) bool {
_, err := objectIDFromHex(str)
return err == nil
}
// ObjectId represents a BSON object ID (a 12-byte unique identifier).
//
// swagger:strfmt bsonobjectid.
type ObjectId [12]byte //nolint:revive
// nilObjectID is the zero-value ObjectId.
var nilObjectID ObjectId //nolint:gochecknoglobals // package-level sentinel
// NewObjectId creates a [ObjectId] from a hexadecimal String.
func NewObjectId(hex string) ObjectId { //nolint:revive
oid, err := objectIDFromHex(hex)
if err != nil {
panic(err)
}
return oid
}
// MarshalText turns this instance into text.
func (id ObjectId) MarshalText() ([]byte, error) {
if id == nilObjectID {
return nil, nil
}
return []byte(id.Hex()), nil
}
// UnmarshalText hydrates this instance from text.
func (id *ObjectId) UnmarshalText(data []byte) error { // validation is performed later on
if len(data) == 0 {
*id = nilObjectID
return nil
}
oid, err := objectIDFromHex(string(data))
if err != nil {
return err
}
*id = oid
return nil
}
// Scan read a value from a database driver.
func (id *ObjectId) Scan(raw any) error {
var data []byte
switch v := raw.(type) {
case []byte:
data = v
case string:
data = []byte(v)
default:
return fmt.Errorf("cannot sql.Scan() strfmt.URI from: %#v: %w", v, ErrFormat)
}
return id.UnmarshalText(data)
}
// Value converts a value to a database driver value.
func (id ObjectId) Value() (driver.Value, error) {
return driver.Value(id.Hex()), nil
}
// Hex returns the hex string representation of the [ObjectId].
func (id ObjectId) Hex() string {
return hex.EncodeToString(id[:])
}
func (id ObjectId) String() string {
return id.Hex()
}
// MarshalJSON returns the [ObjectId] as JSON.
func (id ObjectId) MarshalJSON() ([]byte, error) {
return json.Marshal(id.Hex())
}
// UnmarshalJSON sets the [ObjectId] from JSON.
func (id *ObjectId) UnmarshalJSON(data []byte) error {
var hexStr string
if err := json.Unmarshal(data, &hexStr); err != nil {
return err
}
oid, err := objectIDFromHex(hexStr)
if err != nil {
return err
}
*id = oid
return nil
}
// DeepCopyInto copies the receiver and writes its value into out.
func (id *ObjectId) DeepCopyInto(out *ObjectId) {
*out = *id
}
// DeepCopy copies the receiver into a new [ObjectId].
func (id *ObjectId) DeepCopy() *ObjectId {
if id == nil {
return nil
}
out := new(ObjectId)
id.DeepCopyInto(out)
return out
}
// objectIDFromHex parses a 24-character hex string into an [ObjectId].
func objectIDFromHex(s string) (ObjectId, error) {
const objectIDHexLen = 24
if len(s) != objectIDHexLen {
return nilObjectID, fmt.Errorf("the provided hex string %q is not a valid ObjectID: %w", s, ErrFormat)
}
b, err := hex.DecodeString(s)
if err != nil {
return nilObjectID, fmt.Errorf("the provided hex string %q is not a valid ObjectID: %w", s, err)
}
var oid ObjectId
copy(oid[:], b)
return oid, nil
}