1// Copyright (C) MongoDB, Inc. 2017-present.
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may
4// not use this file except in compliance with the License. You may obtain
5// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
7// Package primitive contains types similar to Go primitives for BSON types can do not have direct
8// Go primitive representations.
9package primitive // import "go.mongodb.org/mongo-driver/bson/primitive"
10
11import (
12	"bytes"
13	"encoding/json"
14	"fmt"
15	"time"
16)
17
18// Binary represents a BSON binary value.
19type Binary struct {
20	Subtype byte
21	Data    []byte
22}
23
24// Equal compaes bp to bp2 and returns true is the are equal.
25func (bp Binary) Equal(bp2 Binary) bool {
26	if bp.Subtype != bp2.Subtype {
27		return false
28	}
29	return bytes.Equal(bp.Data, bp2.Data)
30}
31
32// Undefined represents the BSON undefined value type.
33type Undefined struct{}
34
35// DateTime represents the BSON datetime value.
36type DateTime int64
37
38// MarshalJSON marshal to time type
39func (d DateTime) MarshalJSON() ([]byte, error) {
40	return json.Marshal(time.Unix(int64(d)/1000, int64(d)%1000*1000000))
41}
42
43// Null repreesnts the BSON null value.
44type Null struct{}
45
46// Regex represents a BSON regex value.
47type Regex struct {
48	Pattern string
49	Options string
50}
51
52func (rp Regex) String() string {
53	return fmt.Sprintf(`{"pattern": "%s", "options": "%s"}`, rp.Pattern, rp.Options)
54}
55
56// Equal compaes rp to rp2 and returns true is the are equal.
57func (rp Regex) Equal(rp2 Regex) bool {
58	return rp.Pattern == rp2.Pattern && rp.Options == rp.Options
59}
60
61// DBPointer represents a BSON dbpointer value.
62type DBPointer struct {
63	DB      string
64	Pointer ObjectID
65}
66
67func (d DBPointer) String() string {
68	return fmt.Sprintf(`{"db": "%s", "pointer": "%s"}`, d.DB, d.Pointer)
69}
70
71// Equal compaes d to d2 and returns true is the are equal.
72func (d DBPointer) Equal(d2 DBPointer) bool {
73	return d.DB == d2.DB && bytes.Equal(d.Pointer[:], d2.Pointer[:])
74}
75
76// JavaScript represents a BSON JavaScript code value.
77type JavaScript string
78
79// Symbol represents a BSON symbol value.
80type Symbol string
81
82// CodeWithScope represents a BSON JavaScript code with scope value.
83type CodeWithScope struct {
84	Code  JavaScript
85	Scope interface{}
86}
87
88func (cws CodeWithScope) String() string {
89	return fmt.Sprintf(`{"code": "%s", "scope": %v}`, cws.Code, cws.Scope)
90}
91
92// Timestamp represents a BSON timestamp value.
93type Timestamp struct {
94	T uint32
95	I uint32
96}
97
98// Equal compaes tp to tp2 and returns true is the are equal.
99func (tp Timestamp) Equal(tp2 Timestamp) bool {
100	return tp.T == tp2.T && tp.I == tp2.I
101}
102
103// MinKey represents the BSON minkey value.
104type MinKey struct{}
105
106// MaxKey represents the BSON maxkey value.
107type MaxKey struct{}
108
109// D represents a BSON Document. This type can be used to represent BSON in a concise and readable
110// manner. It should generally be used when serializing to BSON. For deserializing, the Raw or
111// Document types should be used.
112//
113// Example usage:
114//
115// 		primitive.D{{"foo", "bar"}, {"hello", "world"}, {"pi", 3.14159}}
116//
117// This type should be used in situations where order matters, such as MongoDB commands. If the
118// order is not important, a map is more comfortable and concise.
119type D []E
120
121// Map creates a map from the elements of the D.
122func (d D) Map() M {
123	m := make(M, len(d))
124	for _, e := range d {
125		m[e.Key] = e.Value
126	}
127	return m
128}
129
130// E represents a BSON element for a D. It is usually used inside a D.
131type E struct {
132	Key   string
133	Value interface{}
134}
135
136// M is an unordered, concise representation of a BSON Document. It should generally be used to
137// serialize BSON when the order of the elements of a BSON document do not matter. If the element
138// order matters, use a D instead.
139//
140// Example usage:
141//
142// 		primitive.M{"foo": "bar", "hello": "world", "pi": 3.14159}
143//
144// This type is handled in the encoders as a regular map[string]interface{}. The elements will be
145// serialized in an undefined, random order, and the order will be different each time.
146type M map[string]interface{}
147
148// An A represents a BSON array. This type can be used to represent a BSON array in a concise and
149// readable manner. It should generally be used when serializing to BSON. For deserializing, the
150// RawArray or Array types should be used.
151//
152// Example usage:
153//
154// 		primitive.A{"bar", "world", 3.14159, primitive.D{{"qux", 12345}}}
155//
156type A []interface{}
157