...
1
2
3
4
5
6
7
8
9
10 package bson
11
12 import (
13 "bytes"
14 "encoding/hex"
15 "encoding/json"
16 "errors"
17 "fmt"
18 )
19
20
21 var ErrInvalidHex = errors.New("the provided hex string is not a valid ObjectID")
22
23
24 type ObjectID [12]byte
25
26
27 var NilObjectID ObjectID
28
29
30 func (id ObjectID) Hex() string {
31 return hex.EncodeToString(id[:])
32 }
33
34 func (id ObjectID) String() string {
35 return fmt.Sprintf("ObjectID(%q)", id.Hex())
36 }
37
38
39 func (id ObjectID) IsZero() bool {
40 return bytes.Equal(id[:], NilObjectID[:])
41 }
42
43
44
45 func ObjectIDFromHex(s string) (ObjectID, error) {
46 b, err := hex.DecodeString(s)
47 if err != nil {
48 return NilObjectID, err
49 }
50
51 if len(b) != 12 {
52 return NilObjectID, ErrInvalidHex
53 }
54
55 var oid [12]byte
56 copy(oid[:], b[:])
57
58 return oid, nil
59 }
60
61
62 func (id ObjectID) MarshalJSON() ([]byte, error) {
63 return json.Marshal(id.Hex())
64 }
65
66
67
68
69
70 func (id *ObjectID) UnmarshalJSON(b []byte) error {
71
72
73
74 if string(b) == "null" {
75 return nil
76 }
77
78 var err error
79 switch len(b) {
80 case 12:
81 copy(id[:], b)
82 default:
83
84 var res interface{}
85 err := json.Unmarshal(b, &res)
86 if err != nil {
87 return err
88 }
89 str, ok := res.(string)
90 if !ok {
91 m, ok := res.(map[string]interface{})
92 if !ok {
93 return errors.New("not an extended JSON ObjectID")
94 }
95 oid, ok := m["$oid"]
96 if !ok {
97 return errors.New("not an extended JSON ObjectID")
98 }
99 str, ok = oid.(string)
100 if !ok {
101 return errors.New("not an extended JSON ObjectID")
102 }
103 }
104
105
106 if len(str) == 0 {
107 copy(id[:], NilObjectID[:])
108 return nil
109 }
110
111 if len(str) != 24 {
112 return fmt.Errorf("cannot unmarshal into an ObjectID, the length must be 24 but it is %d", len(str))
113 }
114
115 _, err = hex.Decode(id[:], []byte(str))
116 if err != nil {
117 return err
118 }
119 }
120
121 return err
122 }
123
View as plain text