-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathtypes.go
More file actions
186 lines (164 loc) · 4.45 KB
/
types.go
File metadata and controls
186 lines (164 loc) · 4.45 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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
// Copyright: Jonathan Hall
// License: GNU AGPL, Version 3 or later; http://www.gnu.org/licenses/agpl.html
package anki
import (
"encoding/json"
"errors"
"fmt"
"strconv"
"time"
)
// ID represents an Anki object ID (deck, card, note, etc) as an int64.
type ID int64
// Scan implements the sql.Scanner interface for the ID type.
func (i *ID) Scan(src interface{}) error {
var id int64
switch x := src.(type) {
case float64:
id = int64(src.(float64))
case int64:
id = src.(int64)
case string:
var err error
id, err = strconv.ParseInt(src.(string), 10, 64)
if err != nil {
return err
}
case nil:
return nil
default:
return fmt.Errorf("Incompatible type for ID: %s", x)
}
*i = ID(id)
return nil
}
// UnmarshalJSON implements the json.Unmarshaler interface for the ID type.
func (i *ID) UnmarshalJSON(src []byte) error {
var id interface{}
if err := json.Unmarshal(src, &id); err != nil {
return err
}
return i.Scan(id)
}
// TimestampSeconds represents a time.Time value stored as seconds.
type TimestampSeconds time.Time
// TimestampMilliseconds represents a time.Time value stored as milliseconds.
type TimestampMilliseconds time.Time
// Scan implements the sql.Scanner interface for the TimestampSeconds type.
func (t *TimestampSeconds) Scan(src interface{}) error {
var seconds int64
switch x := src.(type) {
case float64:
seconds = int64(src.(float64))
case int64:
seconds = src.(int64)
case nil:
return nil
default:
return fmt.Errorf("Incompatible type for TimestampSeconds: %s", x)
}
*t = TimestampSeconds(time.Unix(seconds, 0).UTC())
return nil
}
// UnmarshalJSON implements the json.Unmarshaler interface for the
// TimestampSeconds type.
func (t *TimestampSeconds) UnmarshalJSON(src []byte) error {
var ts interface{}
if err := json.Unmarshal(src, &ts); err != nil {
return err
}
return t.Scan(ts)
}
// Scan implements the sql.Scanner interface for the TimestampMilliseconds
// type.
func (t *TimestampMilliseconds) Scan(src interface{}) error {
var ms int64
switch src.(type) {
case float64:
ms = int64(src.(float64))
case int64:
ms = src.(int64)
case nil:
return nil
default:
return errors.New("Incompatible type for TimestampMillieconds")
}
*t = TimestampMilliseconds(time.Unix(ms/1000, ms%1000).UTC())
return nil
}
func scanInt64(src interface{}) (int64, error) {
var num int64
switch src.(type) {
case float64:
num = int64(src.(float64))
case int64:
num = src.(int64)
default:
return 0, errors.New("Incompatible type for int64")
}
return num, nil
}
// DurationMilliseconds represents a time.Duration value stored as
// milliseconds.
type DurationMilliseconds time.Duration
// Scan implements the sql.Scanner interface for the DurationMilliseconds type.
func (d *DurationMilliseconds) Scan(src interface{}) error {
ms, err := scanInt64(src)
*d = DurationMilliseconds(time.Duration(ms) * time.Millisecond)
return err
}
// DurationSeconds represents a time.Duration value stored as seconds.
type DurationSeconds time.Duration
// Scan implements the sql.Scanner interface for the DurationSeconds type.
func (d *DurationSeconds) Scan(src interface{}) error {
seconds, err := scanInt64(src)
*d = DurationSeconds(time.Duration(seconds) * time.Second)
return err
}
// DurationMinutes represents a time.Duration value stored as minutes.
type DurationMinutes time.Duration
// Scan implements the sql.Scanner interface for the DurationMinutes type.
func (d *DurationMinutes) Scan(src interface{}) error {
min, err := scanInt64(src)
*d = DurationMinutes(time.Duration(min) * time.Minute)
return err
}
// DurationDays represents a duration in days.
type DurationDays int
func (d *DurationDays) Scan(src interface{}) error {
days, err := scanInt64(src)
*d = DurationDays(int(days))
return err
}
// BoolInt represents a boolean value stored as an int
type BoolInt bool
// Scan implements the sql.Scanner interface for the BoolInt type.
func (b *BoolInt) Scan(src interface{}) error {
var tf bool
switch t := src.(type) {
case bool:
tf = t
case float64:
// Only 0 is false
tf = t != 0
case int64:
// Only 0 is false
tf = t != 0
case nil:
// Nil is false
tf = false
default:
return fmt.Errorf("Incompatible type '%T' for BoolInt", src)
}
*b = BoolInt(tf)
return nil
}
// UnmarshalJSON implements the json.Unmarshaler interface for the BoolInt
// type.
func (b *BoolInt) UnmarshalJSON(src []byte) error {
var tmp interface{}
if err := json.Unmarshal(src, &tmp); err != nil {
return err
}
return b.Scan(tmp)
}