ulid-transform 1.0.1__cp313-cp313-musllinux_1_2_i686.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,41 @@
1
+ __version__ = "1.0.1"
2
+
3
+ try:
4
+ from ._ulid_impl import (
5
+ bytes_to_ulid,
6
+ bytes_to_ulid_or_none,
7
+ ulid_at_time,
8
+ ulid_at_time_bytes,
9
+ ulid_hex,
10
+ ulid_now,
11
+ ulid_now_bytes,
12
+ ulid_to_bytes,
13
+ ulid_to_bytes_or_none,
14
+ ulid_to_timestamp,
15
+ )
16
+ except ImportError:
17
+ from ._py_ulid_impl import (
18
+ bytes_to_ulid,
19
+ bytes_to_ulid_or_none,
20
+ ulid_at_time,
21
+ ulid_at_time_bytes,
22
+ ulid_hex,
23
+ ulid_now,
24
+ ulid_now_bytes,
25
+ ulid_to_bytes,
26
+ ulid_to_bytes_or_none,
27
+ ulid_to_timestamp,
28
+ )
29
+
30
+ __all__ = [
31
+ "bytes_to_ulid",
32
+ "bytes_to_ulid_or_none",
33
+ "ulid_at_time",
34
+ "ulid_at_time_bytes",
35
+ "ulid_hex",
36
+ "ulid_now",
37
+ "ulid_now_bytes",
38
+ "ulid_to_bytes",
39
+ "ulid_to_bytes_or_none",
40
+ "ulid_to_timestamp",
41
+ ]
@@ -0,0 +1,10 @@
1
+ def ulid_hex() -> str: ...
2
+ def ulid_at_time_bytes(timestamp: float) -> bytes: ...
3
+ def ulid_now_bytes() -> bytes: ...
4
+ def ulid_now() -> str: ...
5
+ def ulid_at_time(timestamp: float) -> str: ...
6
+ def ulid_to_bytes(value: str) -> bytes: ...
7
+ def bytes_to_ulid(value: bytes) -> str: ...
8
+ def ulid_to_bytes_or_none(ulid: str | None) -> bytes | None: ...
9
+ def bytes_to_ulid_or_none(ulid_bytes: bytes | None) -> str | None: ...
10
+ def ulid_to_timestamp(ulid: str | bytes) -> int: ...
@@ -0,0 +1,454 @@
1
+ import array
2
+ from random import getrandbits
3
+ from time import time
4
+
5
+ # From https://github.com/ahawker/ulid/blob/06289583e9de4286b4d80b4ad000d137816502ca/ulid/base32.py#L102
6
+ #: Array that maps encoded string char byte values to enable O(1) lookups.
7
+ _DECODE = array.array(
8
+ "B",
9
+ (
10
+ 0xFF,
11
+ 0xFF,
12
+ 0xFF,
13
+ 0xFF,
14
+ 0xFF,
15
+ 0xFF,
16
+ 0xFF,
17
+ 0xFF,
18
+ 0xFF,
19
+ 0xFF,
20
+ 0xFF,
21
+ 0xFF,
22
+ 0xFF,
23
+ 0xFF,
24
+ 0xFF,
25
+ 0xFF,
26
+ 0xFF,
27
+ 0xFF,
28
+ 0xFF,
29
+ 0xFF,
30
+ 0xFF,
31
+ 0xFF,
32
+ 0xFF,
33
+ 0xFF,
34
+ 0xFF,
35
+ 0xFF,
36
+ 0xFF,
37
+ 0xFF,
38
+ 0xFF,
39
+ 0xFF,
40
+ 0xFF,
41
+ 0xFF,
42
+ 0xFF,
43
+ 0xFF,
44
+ 0xFF,
45
+ 0xFF,
46
+ 0xFF,
47
+ 0xFF,
48
+ 0xFF,
49
+ 0xFF,
50
+ 0xFF,
51
+ 0xFF,
52
+ 0xFF,
53
+ 0xFF,
54
+ 0xFF,
55
+ 0xFF,
56
+ 0xFF,
57
+ 0xFF,
58
+ 0x00,
59
+ 0x01,
60
+ 0x02,
61
+ 0x03,
62
+ 0x04,
63
+ 0x05,
64
+ 0x06,
65
+ 0x07,
66
+ 0x08,
67
+ 0x09,
68
+ 0xFF,
69
+ 0xFF,
70
+ 0xFF,
71
+ 0xFF,
72
+ 0xFF,
73
+ 0xFF,
74
+ 0xFF,
75
+ 0x0A,
76
+ 0x0B,
77
+ 0x0C,
78
+ 0x0D,
79
+ 0x0E,
80
+ 0x0F,
81
+ 0x10,
82
+ 0x11,
83
+ 0x01,
84
+ 0x12,
85
+ 0x13,
86
+ 0x01,
87
+ 0x14,
88
+ 0x15,
89
+ 0x00,
90
+ 0x16,
91
+ 0x17,
92
+ 0x18,
93
+ 0x19,
94
+ 0x1A,
95
+ 0xFF,
96
+ 0x1B,
97
+ 0x1C,
98
+ 0x1D,
99
+ 0x1E,
100
+ 0x1F,
101
+ 0xFF,
102
+ 0xFF,
103
+ 0xFF,
104
+ 0xFF,
105
+ 0xFF,
106
+ 0xFF,
107
+ 0x0A,
108
+ 0x0B,
109
+ 0x0C,
110
+ 0x0D,
111
+ 0x0E,
112
+ 0x0F,
113
+ 0x10,
114
+ 0x11,
115
+ 0x01,
116
+ 0x12,
117
+ 0x13,
118
+ 0x01,
119
+ 0x14,
120
+ 0x15,
121
+ 0x00,
122
+ 0x16,
123
+ 0x17,
124
+ 0x18,
125
+ 0x19,
126
+ 0x1A,
127
+ 0xFF,
128
+ 0x1B,
129
+ 0x1C,
130
+ 0x1D,
131
+ 0x1E,
132
+ 0x1F,
133
+ 0xFF,
134
+ 0xFF,
135
+ 0xFF,
136
+ 0xFF,
137
+ 0xFF,
138
+ 0xFF,
139
+ 0xFF,
140
+ 0xFF,
141
+ 0xFF,
142
+ 0xFF,
143
+ 0xFF,
144
+ 0xFF,
145
+ 0xFF,
146
+ 0xFF,
147
+ 0xFF,
148
+ 0xFF,
149
+ 0xFF,
150
+ 0xFF,
151
+ 0xFF,
152
+ 0xFF,
153
+ 0xFF,
154
+ 0xFF,
155
+ 0xFF,
156
+ 0xFF,
157
+ 0xFF,
158
+ 0xFF,
159
+ 0xFF,
160
+ 0xFF,
161
+ 0xFF,
162
+ 0xFF,
163
+ 0xFF,
164
+ 0xFF,
165
+ 0xFF,
166
+ 0xFF,
167
+ 0xFF,
168
+ 0xFF,
169
+ 0xFF,
170
+ 0xFF,
171
+ 0xFF,
172
+ 0xFF,
173
+ 0xFF,
174
+ 0xFF,
175
+ 0xFF,
176
+ 0xFF,
177
+ 0xFF,
178
+ 0xFF,
179
+ 0xFF,
180
+ 0xFF,
181
+ 0xFF,
182
+ 0xFF,
183
+ 0xFF,
184
+ 0xFF,
185
+ 0xFF,
186
+ 0xFF,
187
+ 0xFF,
188
+ 0xFF,
189
+ 0xFF,
190
+ 0xFF,
191
+ 0xFF,
192
+ 0xFF,
193
+ 0xFF,
194
+ 0xFF,
195
+ 0xFF,
196
+ 0xFF,
197
+ 0xFF,
198
+ 0xFF,
199
+ 0xFF,
200
+ 0xFF,
201
+ 0xFF,
202
+ 0xFF,
203
+ 0xFF,
204
+ 0xFF,
205
+ 0xFF,
206
+ 0xFF,
207
+ 0xFF,
208
+ 0xFF,
209
+ 0xFF,
210
+ 0xFF,
211
+ 0xFF,
212
+ 0xFF,
213
+ 0xFF,
214
+ 0xFF,
215
+ 0xFF,
216
+ 0xFF,
217
+ 0xFF,
218
+ 0xFF,
219
+ 0xFF,
220
+ 0xFF,
221
+ 0xFF,
222
+ 0xFF,
223
+ 0xFF,
224
+ 0xFF,
225
+ 0xFF,
226
+ 0xFF,
227
+ 0xFF,
228
+ 0xFF,
229
+ 0xFF,
230
+ 0xFF,
231
+ 0xFF,
232
+ 0xFF,
233
+ 0xFF,
234
+ 0xFF,
235
+ 0xFF,
236
+ 0xFF,
237
+ 0xFF,
238
+ 0xFF,
239
+ 0xFF,
240
+ 0xFF,
241
+ 0xFF,
242
+ 0xFF,
243
+ 0xFF,
244
+ 0xFF,
245
+ 0xFF,
246
+ 0xFF,
247
+ 0xFF,
248
+ 0xFF,
249
+ 0xFF,
250
+ 0xFF,
251
+ 0xFF,
252
+ 0xFF,
253
+ 0xFF,
254
+ 0xFF,
255
+ 0xFF,
256
+ 0xFF,
257
+ 0xFF,
258
+ 0xFF,
259
+ 0xFF,
260
+ 0xFF,
261
+ 0xFF,
262
+ 0xFF,
263
+ 0xFF,
264
+ 0xFF,
265
+ 0xFF,
266
+ ),
267
+ )
268
+
269
+
270
+ def ulid_hex() -> str:
271
+ """Generate a ULID in lowercase hex that will work for a UUID.
272
+
273
+ This ulid should not be used for cryptographically secure
274
+ operations.
275
+
276
+ This string can be converted with https://github.com/ahawker/ulid
277
+
278
+ ulid.from_uuid(uuid.UUID(ulid_hex))
279
+ """
280
+ return f"{int(time()*1000):012x}{getrandbits(80):020x}"
281
+
282
+
283
+ def ulid_at_time_bytes(timestamp: float) -> bytes:
284
+ """Generate an ULID as 16 bytes that will work for a UUID.
285
+
286
+ uuid.UUID(bytes=ulid_bytes)
287
+ """
288
+ return int(timestamp * 1000).to_bytes(6, byteorder="big") + int(
289
+ getrandbits(80)
290
+ ).to_bytes(10, byteorder="big")
291
+
292
+
293
+ def ulid_now_bytes() -> bytes:
294
+ """Generate an ULID as 16 bytes that will work for a UUID."""
295
+ return ulid_at_time_bytes(time())
296
+
297
+
298
+ def ulid_now() -> str:
299
+ """Generate a ULID."""
300
+ return ulid_at_time(time())
301
+
302
+
303
+ def ulid_at_time(timestamp: float) -> str:
304
+ """Generate a ULID.
305
+
306
+ This ulid should not be used for cryptographically secure
307
+ operations.
308
+
309
+ 01AN4Z07BY 79KA1307SR9X4MV3
310
+ |----------| |----------------|
311
+ Timestamp Randomness
312
+ 48bits 80bits
313
+
314
+ This string can be loaded directly with https://github.com/ahawker/ulid
315
+
316
+ import ulid_transform as ulid_util
317
+ import ulid
318
+ ulid.parse(ulid_util.ulid())
319
+ """
320
+ return _encode(ulid_at_time_bytes(timestamp))
321
+
322
+
323
+ def _encode(ulid_bytes: bytes) -> str:
324
+ # This is base32 crockford encoding with the loop unrolled for performance
325
+ #
326
+ # This code is adapted from:
327
+ # https://github.com/ahawker/ulid/blob/06289583e9de4286b4d80b4ad000d137816502ca/ulid/base32.py#L102
328
+ #
329
+ enc = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
330
+ return (
331
+ enc[(ulid_bytes[0] & 224) >> 5]
332
+ + enc[ulid_bytes[0] & 31]
333
+ + enc[(ulid_bytes[1] & 248) >> 3]
334
+ + enc[((ulid_bytes[1] & 7) << 2) | ((ulid_bytes[2] & 192) >> 6)]
335
+ + enc[((ulid_bytes[2] & 62) >> 1)]
336
+ + enc[((ulid_bytes[2] & 1) << 4) | ((ulid_bytes[3] & 240) >> 4)]
337
+ + enc[((ulid_bytes[3] & 15) << 1) | ((ulid_bytes[4] & 128) >> 7)]
338
+ + enc[(ulid_bytes[4] & 124) >> 2]
339
+ + enc[((ulid_bytes[4] & 3) << 3) | ((ulid_bytes[5] & 224) >> 5)]
340
+ + enc[ulid_bytes[5] & 31]
341
+ + enc[(ulid_bytes[6] & 248) >> 3]
342
+ + enc[((ulid_bytes[6] & 7) << 2) | ((ulid_bytes[7] & 192) >> 6)]
343
+ + enc[(ulid_bytes[7] & 62) >> 1]
344
+ + enc[((ulid_bytes[7] & 1) << 4) | ((ulid_bytes[8] & 240) >> 4)]
345
+ + enc[((ulid_bytes[8] & 15) << 1) | ((ulid_bytes[9] & 128) >> 7)]
346
+ + enc[(ulid_bytes[9] & 124) >> 2]
347
+ + enc[((ulid_bytes[9] & 3) << 3) | ((ulid_bytes[10] & 224) >> 5)]
348
+ + enc[ulid_bytes[10] & 31]
349
+ + enc[(ulid_bytes[11] & 248) >> 3]
350
+ + enc[((ulid_bytes[11] & 7) << 2) | ((ulid_bytes[12] & 192) >> 6)]
351
+ + enc[(ulid_bytes[12] & 62) >> 1]
352
+ + enc[((ulid_bytes[12] & 1) << 4) | ((ulid_bytes[13] & 240) >> 4)]
353
+ + enc[((ulid_bytes[13] & 15) << 1) | ((ulid_bytes[14] & 128) >> 7)]
354
+ + enc[(ulid_bytes[14] & 124) >> 2]
355
+ + enc[((ulid_bytes[14] & 3) << 3) | ((ulid_bytes[15] & 224) >> 5)]
356
+ + enc[ulid_bytes[15] & 31]
357
+ )
358
+
359
+
360
+ def ulid_to_bytes(value: str) -> bytes:
361
+ """Decode a ulid to bytes."""
362
+ if len(value) != 26:
363
+ raise ValueError(f"ULID must be a 26 character string: {value}")
364
+ encoded = value.encode("ascii")
365
+ decoding = _DECODE
366
+ return bytes(
367
+ (
368
+ ((decoding[encoded[0]] << 5) | decoding[encoded[1]]) & 0xFF,
369
+ ((decoding[encoded[2]] << 3) | (decoding[encoded[3]] >> 2)) & 0xFF,
370
+ (
371
+ (decoding[encoded[3]] << 6)
372
+ | (decoding[encoded[4]] << 1)
373
+ | (decoding[encoded[5]] >> 4)
374
+ )
375
+ & 0xFF,
376
+ ((decoding[encoded[5]] << 4) | (decoding[encoded[6]] >> 1)) & 0xFF,
377
+ (
378
+ (decoding[encoded[6]] << 7)
379
+ | (decoding[encoded[7]] << 2)
380
+ | (decoding[encoded[8]] >> 3)
381
+ )
382
+ & 0xFF,
383
+ ((decoding[encoded[8]] << 5) | (decoding[encoded[9]])) & 0xFF,
384
+ ((decoding[encoded[10]] << 3) | (decoding[encoded[11]] >> 2)) & 0xFF,
385
+ (
386
+ (decoding[encoded[11]] << 6)
387
+ | (decoding[encoded[12]] << 1)
388
+ | (decoding[encoded[13]] >> 4)
389
+ )
390
+ & 0xFF,
391
+ ((decoding[encoded[13]] << 4) | (decoding[encoded[14]] >> 1)) & 0xFF,
392
+ (
393
+ (decoding[encoded[14]] << 7)
394
+ | (decoding[encoded[15]] << 2)
395
+ | (decoding[encoded[16]] >> 3)
396
+ )
397
+ & 0xFF,
398
+ ((decoding[encoded[16]] << 5) | (decoding[encoded[17]])) & 0xFF,
399
+ ((decoding[encoded[18]] << 3) | (decoding[encoded[19]] >> 2)) & 0xFF,
400
+ (
401
+ (decoding[encoded[19]] << 6)
402
+ | (decoding[encoded[20]] << 1)
403
+ | (decoding[encoded[21]] >> 4)
404
+ )
405
+ & 0xFF,
406
+ ((decoding[encoded[21]] << 4) | (decoding[encoded[22]] >> 1)) & 0xFF,
407
+ (
408
+ (decoding[encoded[22]] << 7)
409
+ | (decoding[encoded[23]] << 2)
410
+ | (decoding[encoded[24]] >> 3)
411
+ )
412
+ & 0xFF,
413
+ ((decoding[encoded[24]] << 5) | (decoding[encoded[25]])) & 0xFF,
414
+ )
415
+ )
416
+
417
+
418
+ def bytes_to_ulid(value: bytes) -> str:
419
+ """Encode bytes to a ulid."""
420
+ if len(value) != 16:
421
+ raise ValueError(f"ULID bytes must be 16 bytes: {value!r}")
422
+ return _encode(value)
423
+
424
+
425
+ def ulid_to_bytes_or_none(ulid: str | None) -> bytes | None:
426
+ """Convert an ulid to bytes."""
427
+ if ulid is None:
428
+ return None
429
+ try:
430
+ return ulid_to_bytes(ulid)
431
+ except ValueError:
432
+ return None
433
+
434
+
435
+ def bytes_to_ulid_or_none(ulid_bytes: bytes | None) -> str | None:
436
+ """Convert bytes to a ulid."""
437
+ if ulid_bytes is None:
438
+ return None
439
+ try:
440
+ return bytes_to_ulid(ulid_bytes)
441
+ except ValueError:
442
+ return None
443
+
444
+
445
+ def ulid_to_timestamp(ulid: str | bytes) -> int:
446
+ """
447
+ Get the timestamp from a ULID.
448
+ The returned value is in milliseconds since the UNIX epoch.
449
+ """
450
+ if not isinstance(ulid, bytes):
451
+ ulid_bytes = ulid_to_bytes(ulid)
452
+ else:
453
+ ulid_bytes = ulid
454
+ return int.from_bytes(b"\x00\x00" + ulid_bytes[:6], "big")
@@ -0,0 +1,136 @@
1
+ # distutils: language = c++
2
+ # cython: language_level=3, c_string_type=str, c_string_encoding=ascii
3
+
4
+ # The `<bytes>xxx[:N]` syntax is required for two reasons:
5
+ # 1. When working with "ULID bytes", the buffer may contain NULs.
6
+ # 2. When working with ULID text, the buffer is exactly 26 bytes long and not NUL-terminated.
7
+ # See https://github.com/cython/cython/issues/3234
8
+
9
+ from libc.stdint cimport uint8_t, uint64_t
10
+
11
+
12
+ cdef extern from "ulid_wrapper.h":
13
+ void _cpp_ulid(char dst[26]) nogil
14
+ void _cpp_ulid_bytes(uint8_t dst[16]) nogil
15
+ void _cpp_ulid_at_time(double epoch_time, char dst[26]) nogil
16
+ void _cpp_ulid_at_time_bytes(double epoch_time, uint8_t dst[16]) nogil
17
+ void _cpp_ulid_to_bytes(const char ulid_string[26], uint8_t dst[16]) nogil
18
+ void _cpp_bytes_to_ulid(const uint8_t b[16], char * dst) nogil
19
+ void _cpp_hexlify_16(const uint8_t b[16], char dst[32]) nogil
20
+ uint64_t _cpp_bytes_to_timestamp(const uint8_t b[16]) nogil
21
+
22
+
23
+ def ulid_hex() -> str:
24
+ """Generate a ULID in lowercase hex that will work for a UUID.
25
+
26
+ This ulid should not be used for cryptographically secure
27
+ operations.
28
+
29
+ This string can be converted with https://github.com/ahawker/ulid
30
+
31
+ ulid.from_uuid(uuid.UUID(ulid_hex))
32
+ """
33
+ cdef unsigned char ulid_bytes_buf[16]
34
+ _cpp_ulid_bytes(ulid_bytes_buf)
35
+ cdef char ulid_hex_buf[32]
36
+ _cpp_hexlify_16(ulid_bytes_buf, ulid_hex_buf)
37
+ return <str>ulid_hex_buf[:32]
38
+
39
+
40
+ def ulid_now_bytes() -> bytes:
41
+ """Generate an ULID as 16 bytes that will work for a UUID."""
42
+ cdef unsigned char ulid_bytes_buf[16]
43
+ _cpp_ulid_bytes(ulid_bytes_buf)
44
+ return <bytes>ulid_bytes_buf[:16]
45
+
46
+
47
+ def ulid_at_time_bytes(timestamp: float) -> bytes:
48
+ """Generate an ULID as 16 bytes that will work for a UUID.
49
+
50
+ uuid.UUID(bytes=ulid_bytes)
51
+ """
52
+ cdef unsigned char ulid_bytes_buf[16]
53
+ _cpp_ulid_at_time_bytes(timestamp, ulid_bytes_buf)
54
+ return <bytes>ulid_bytes_buf[:16]
55
+
56
+
57
+ def ulid_now() -> str:
58
+ """Generate a ULID."""
59
+ cdef char ulid_text_buf[26]
60
+ _cpp_ulid(ulid_text_buf)
61
+ return <str>ulid_text_buf[:26]
62
+
63
+
64
+ def ulid_at_time(timestamp: float) -> str:
65
+ """Generate a ULID.
66
+
67
+ This ulid should not be used for cryptographically secure
68
+ operations.
69
+
70
+ 01AN4Z07BY 79KA1307SR9X4MV3
71
+ |----------| |----------------|
72
+ Timestamp Randomness
73
+ 48bits 80bits
74
+
75
+ This string can be loaded directly with https://github.com/ahawker/ulid
76
+
77
+ import ulid_transform as ulid_util
78
+ import ulid
79
+ ulid.parse(ulid_util.ulid())
80
+ """
81
+ cdef char ulid_text_buf[26]
82
+ _cpp_ulid_at_time(timestamp, ulid_text_buf)
83
+ return <str>ulid_text_buf[:26]
84
+
85
+
86
+ def ulid_to_bytes(value: str) -> bytes:
87
+ """Decode a ulid to bytes."""
88
+ if len(value) != 26:
89
+ raise ValueError(f"ULID must be a 26 character string: {value}")
90
+ cdef unsigned char ulid_bytes_buf[16]
91
+ _cpp_ulid_to_bytes(value, ulid_bytes_buf)
92
+ return <bytes>ulid_bytes_buf[:16]
93
+
94
+
95
+ def bytes_to_ulid(value: bytes) -> str:
96
+ """Encode bytes to a ulid."""
97
+ if len(value) != 16:
98
+ raise ValueError(f"ULID bytes must be 16 bytes: {value!r}")
99
+ cdef char ulid_text_buf[26]
100
+ _cpp_bytes_to_ulid(value, ulid_text_buf)
101
+ return <str>ulid_text_buf[:26]
102
+
103
+
104
+ def ulid_to_bytes_or_none(ulid: str | None) -> bytes | None:
105
+ """Convert an ulid to bytes."""
106
+ if ulid is None or len(ulid) != 26:
107
+ return None
108
+ cdef unsigned char ulid_bytes_buf[16]
109
+ _cpp_ulid_to_bytes(ulid, ulid_bytes_buf)
110
+ return <bytes>ulid_bytes_buf[:16]
111
+
112
+
113
+ def bytes_to_ulid_or_none(ulid_bytes: bytes | None) -> str | None:
114
+ """Convert bytes to a ulid."""
115
+ if ulid_bytes is None or len(ulid_bytes) != 16:
116
+ return None
117
+ cdef char ulid_text_buf[26]
118
+ _cpp_bytes_to_ulid(ulid_bytes, ulid_text_buf)
119
+ return <str>ulid_text_buf[:26]
120
+
121
+
122
+ def ulid_to_timestamp(ulid: str | bytes) -> int:
123
+ """
124
+ Get the timestamp from a ULID.
125
+ The returned value is in milliseconds since the UNIX epoch.
126
+ """
127
+ cdef unsigned char ulid_bytes_buf[16]
128
+ if not isinstance(ulid, bytes):
129
+ if len(ulid) != 26:
130
+ raise ValueError(f"ULID must be a 26 character string: {ulid}")
131
+ _cpp_ulid_to_bytes(ulid, ulid_bytes_buf)
132
+ return _cpp_bytes_to_timestamp(ulid_bytes_buf)
133
+ else:
134
+ if len(ulid) != 16:
135
+ raise ValueError(f"ULID bytes must be 16 bytes: {ulid!r}")
136
+ return _cpp_bytes_to_timestamp(ulid)
File without changes
ulid_transform/ulid.hh ADDED
@@ -0,0 +1,17 @@
1
+ // Originally from https://github.com/suyash/ulid
2
+
3
+ #ifndef ULID_HH
4
+ #define ULID_HH
5
+
6
+ // http://stackoverflow.com/a/23981011
7
+ #ifdef __SIZEOF_INT128__
8
+ #define ULIDUINT128
9
+ #endif
10
+
11
+ #ifdef ULIDUINT128
12
+ #include "ulid_uint128.hh"
13
+ #else
14
+ #include "ulid_struct.hh"
15
+ #endif // ULIDUINT128
16
+
17
+ #endif // ULID_HH