|
1 | 1 | import { TaggedValue, encode as encode_cbor, decode as decode_cbor } from "cbor-redux";
|
2 | 2 | import { RecordId } from "./recordid.ts";
|
3 | 3 | import { Uuid } from "./uuid.ts";
|
4 |
| -import { Duration } from "./duration.ts"; |
| 4 | +import { Duration, cborCustomDurationToDuration, durationToCborCustomDuration } from "./duration.ts"; |
5 | 5 | import { Decimal } from "./decimal.ts"
|
| 6 | +import { |
| 7 | + GeometryCollection, |
| 8 | + GeometryLine, |
| 9 | + GeometryMultiLine, |
| 10 | + GeometryMultiPoint, |
| 11 | + GeometryMultiPolygon, |
| 12 | + GeometryPoint, |
| 13 | + GeometryPolygon |
| 14 | +} from "./geometry.ts"; |
| 15 | +import { Table } from "./table.ts"; |
| 16 | +import { cborCustomDateToDate, dateToCborCustomDate } from "./datetime.ts"; |
| 17 | + |
| 18 | +// Tags from the spec - https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml |
| 19 | +const TAG_SPEC_DATETIME = 0; |
| 20 | +const TAG_SPEC_UUID = 37; |
| 21 | + |
| 22 | +// Custom tags |
| 23 | +const TAG_NONE = 6; |
| 24 | +const TAG_TABLE = 7; |
| 25 | +const TAG_RECORDID = 8; |
| 26 | +const TAG_STRING_UUID = 9; |
| 27 | +const TAG_STRING_DECIMAL = 10; |
| 28 | +// const TAG_BINARY_DECIMAL = 11; |
| 29 | +const TAG_CUSTOM_DATETIME = 12; |
| 30 | +const TAG_STRING_DURATION = 13; |
| 31 | +const TAG_CUSTOM_DURATION = 14; |
| 32 | + |
| 33 | +// Custom Geometries |
| 34 | +const TAG_GEOMETRY_POINT = 88; |
| 35 | +const TAG_GEOMETRY_LINE = 89; |
| 36 | +const TAG_GEOMETRY_POLYGON = 90; |
| 37 | +const TAG_GEOMETRY_MULTIPOINT = 91; |
| 38 | +const TAG_GEOMETRY_MULTILINE = 92; |
| 39 | +const TAG_GEOMETRY_MULTIPOLYGON = 93; |
| 40 | +const TAG_GEOMETRY_COLLECTION = 94; |
6 | 41 |
|
7 | 42 | export function encode<T extends unknown>(data: T) {
|
8 | 43 | return encode_cbor<T>(data, (_, v) => {
|
9 |
| - if (v instanceof Date) return new TaggedValue(v.toISOString(), 0); |
10 |
| - if (v === undefined) return new TaggedValue(null, 6); |
11 |
| - if (v instanceof Uuid) return new TaggedValue(v.uuid, 7); |
12 |
| - if (v instanceof Decimal) return new TaggedValue(v.toString(), 8); |
13 |
| - if (v instanceof Duration) return new TaggedValue(v.toString(), 9); |
14 |
| - if (v instanceof RecordId) return new TaggedValue([v.tb, v.id], 10); |
| 44 | + if (v instanceof Date) return new TaggedValue(dateToCborCustomDate(v), TAG_CUSTOM_DATETIME); |
| 45 | + if (v === undefined) return new TaggedValue(null, TAG_NONE); |
| 46 | + if (v instanceof Uuid) return new TaggedValue(v.uuid, TAG_STRING_UUID); |
| 47 | + if (v instanceof Decimal) return new TaggedValue(v.toString(), TAG_STRING_DECIMAL); |
| 48 | + if (v instanceof Duration) return new TaggedValue(durationToCborCustomDuration(v), TAG_CUSTOM_DURATION); |
| 49 | + if (v instanceof RecordId) return new TaggedValue([v.tb, v.id], TAG_RECORDID); |
| 50 | + if (v instanceof Table) return new TaggedValue(v.tb, TAG_TABLE); |
| 51 | + if (v instanceof GeometryPoint) return new TaggedValue(v.point, TAG_GEOMETRY_POINT); |
| 52 | + if (v instanceof GeometryLine) return new TaggedValue(v.line, TAG_GEOMETRY_LINE); |
| 53 | + if (v instanceof GeometryPolygon) return new TaggedValue(v.polygon, TAG_GEOMETRY_POLYGON); |
| 54 | + if (v instanceof GeometryMultiPoint) return new TaggedValue(v.points, TAG_GEOMETRY_MULTIPOINT); |
| 55 | + if (v instanceof GeometryMultiLine) return new TaggedValue(v.lines, TAG_GEOMETRY_MULTILINE); |
| 56 | + if (v instanceof GeometryMultiPolygon) return new TaggedValue(v.polygons, TAG_GEOMETRY_MULTIPOLYGON); |
| 57 | + if (v instanceof GeometryCollection) return new TaggedValue(v.collection, TAG_GEOMETRY_COLLECTION); |
15 | 58 | return v;
|
16 | 59 | });
|
17 | 60 | }
|
18 | 61 |
|
19 | 62 | export function decode(data: ArrayBuffer) {
|
20 | 63 | return decode_cbor(data, (_, v) => {
|
21 |
| - if (v instanceof TaggedValue) { |
22 |
| - if (v.tag === 0) return new Date(v.value); |
23 |
| - if (v.tag === 6) return undefined; |
24 |
| - if (v.tag === 7) return new Uuid(v.value); |
25 |
| - if (v.tag === 8) return new Decimal(v.value); |
26 |
| - if (v.tag === 9) return new Duration(v.value); |
27 |
| - if (v.tag === 10) return new RecordId(v.value[0], v.value[1]); |
| 64 | + if (!(v instanceof TaggedValue)) return v; |
| 65 | + |
| 66 | + switch (v.tag) { |
| 67 | + case TAG_SPEC_DATETIME: return new Date(v.value); |
| 68 | + case TAG_CUSTOM_DATETIME: return cborCustomDateToDate(v.value); |
| 69 | + case TAG_NONE: return undefined; |
| 70 | + case TAG_STRING_UUID: return new Uuid(v.value); |
| 71 | + case TAG_STRING_DECIMAL: return new Decimal(v.value); |
| 72 | + case TAG_STRING_DURATION: return new Duration(v.value); |
| 73 | + case TAG_CUSTOM_DURATION: return cborCustomDurationToDuration(v.value); |
| 74 | + case TAG_RECORDID: return new RecordId(v.value[0], v.value[1]); |
| 75 | + case TAG_GEOMETRY_POINT: return new GeometryPoint(v.value); |
| 76 | + case TAG_GEOMETRY_LINE: return new GeometryLine(v.value); |
| 77 | + case TAG_GEOMETRY_POLYGON: return new GeometryPolygon(v.value); |
| 78 | + case TAG_GEOMETRY_MULTIPOINT: return new GeometryMultiPoint(v.value); |
| 79 | + case TAG_GEOMETRY_MULTILINE: return new GeometryMultiLine(v.value); |
| 80 | + case TAG_GEOMETRY_MULTIPOLYGON: return new GeometryMultiPolygon(v.value); |
| 81 | + case TAG_GEOMETRY_COLLECTION: return new GeometryCollection(v.value); |
28 | 82 | }
|
29 |
| - return v; |
30 | 83 | });
|
31 | 84 | }
|
0 commit comments