Last active 1720890582

rootspring's Avatar rootspring revised this gist 1720890581. Go to revision

1 file changed, 151 insertions

func.ts(file created)

@@ -0,0 +1,151 @@
1 + export interface DispatchType {
2 + // The type of the input
3 + type: string;
4 + // The minimum length of the input
5 + minlength: number | undefined;
6 + // The maximum length of the input
7 + maxlength: number | undefined;
8 + // The allowed values of the input
9 + allowed_values: { [label: string]: string } | undefined;
10 + // If bitflag, then the values of the bitflag
11 + bitflag_values: { [label: string]: bigint } | undefined;
12 + }
13 +
14 + // Returns the type to be dispatched to InputDispatcher
15 + export const getDispatchType = (fields: Record<string, any>, column: CanonicalColumn): DispatchType => {
16 + const _setOnDispatchType = <T extends keyof DispatchType>(
17 + dispatchType: DispatchType,
18 + key: T,
19 + value: DispatchType[T]
20 + ) => {
21 + if (!dispatchType[key] || (Array.isArray(dispatchType[key]) && dispatchType[key].length == 0)) {
22 + dispatchType[key] = value;
23 + }
24 + return dispatchType;
25 + };
26 +
27 + // Check for __{}_displaytype
28 +
29 + /*
30 + "channel" => return format!("<#{}>", value),
31 + "role" => return format!("<@&{}>", value),
32 + "user" => return format!("<@{}>", value),
33 + */
34 +
35 + let dispatchType: DispatchType = {
36 + type: '',
37 + minlength: undefined,
38 + maxlength: undefined,
39 + allowed_values: undefined,
40 + bitflag_values: undefined
41 + };
42 +
43 + if (fields[`__${column.id}_displaytype`]) {
44 + // Set the dispatch type to string:displaytype
45 + _setOnDispatchType(dispatchType, 'type', `string:${fields[`__${column.id}_displaytype`]}`);
46 + }
47 +
48 + const handleInner = (
49 + dispatchType: DispatchType,
50 + inner: CanonicalInnerColumnType
51 + ): DispatchType => {
52 + /*
53 + #[derive(Debug, Clone, PartialEq)]
54 + #[allow(dead_code)]
55 + pub enum InnerColumnType {
56 + Uuid {},
57 + String {
58 + min_length: Option<usize>,
59 + max_length: Option<usize>,
60 + allowed_values: Vec<&'static str>, // If empty, all values are allowed
61 + kind: InnerColumnTypeStringKind,
62 + },
63 + Timestamp {},
64 + TimestampTz {},
65 + Integer {},
66 + Float {},
67 + BitFlag {
68 + /// The bit flag values
69 + values: indexmap::IndexMap<&'static str, i64>,
70 + },
71 + Boolean {},
72 + Json {},
73 + }
74 + */
75 +
76 + if (inner.String) {
77 + _setOnDispatchType(dispatchType, 'minlength', inner.String.min_length);
78 + _setOnDispatchType(dispatchType, 'maxlength', inner.String.max_length);
79 +
80 + if (inner.String.allowed_values) {
81 + // Set the allowed values
82 + let allowedValues: { [label: string]: string } = {};
83 + inner.String.allowed_values.forEach((value) => {
84 + allowedValues[value] = value;
85 + });
86 + _setOnDispatchType(dispatchType, 'allowed_values', allowedValues);
87 + }
88 +
89 + // Handle the kind
90 + if (inner.String.kind == 'Normal') {
91 + _setOnDispatchType(dispatchType, 'type', 'string');
92 + } else if (inner.String.kind == 'User') {
93 + _setOnDispatchType(dispatchType, 'type', 'string:user');
94 + } else if (inner.String.kind == 'Channel') {
95 + _setOnDispatchType(dispatchType, 'type', 'string:channel');
96 + } else if (inner.String.kind == 'Role') {
97 + _setOnDispatchType(dispatchType, 'type', 'string:role');
98 + } else if (inner.String.kind == 'Emoji') {
99 + _setOnDispatchType(dispatchType, 'type', 'string:emoji');
100 + } else if (inner.String.kind == 'Message') {
101 + _setOnDispatchType(dispatchType, 'type', 'string:message');
102 + } else if (inner.String.kind == 'Template') {
103 + _setOnDispatchType(dispatchType, 'type', 'string:template');
104 + } else {
105 + _setOnDispatchType(
106 + dispatchType,
107 + 'type',
108 + inner.String.kind ? `string:${inner.String.kind?.toLowerCase()}` : 'string'
109 + );
110 + }
111 + } else if (inner.Uuid) {
112 + _setOnDispatchType(dispatchType, 'type', 'uuid');
113 + } else if (inner.Timestamp) {
114 + _setOnDispatchType(dispatchType, 'type', 'timestamp');
115 + } else if (inner.TimestampTz) {
116 + _setOnDispatchType(dispatchType, 'type', 'timestamptz');
117 + } else if (inner.Integer) {
118 + _setOnDispatchType(dispatchType, 'type', 'integer');
119 + } else if (inner.Float) {
120 + _setOnDispatchType(dispatchType, 'type', 'float');
121 + } else if (inner.Boolean) {
122 + _setOnDispatchType(dispatchType, 'type', 'boolean');
123 + } else if (inner.BitFlag) {
124 + _setOnDispatchType(dispatchType, 'type', 'bitflag');
125 +
126 + // Until the rust server code can handle bigint correctly, convert them here ourselves
127 + let values: { [label: string]: bigint } = {};
128 +
129 + Object.keys(inner.BitFlag.values).forEach((value) => {
130 + if (!inner.BitFlag) return; // TS can't infer that inner.BitFlag is still not null here
131 + values[value] = BigInt(inner.BitFlag.values[value]);
132 + });
133 +
134 + _setOnDispatchType(dispatchType, 'bitflag_values', values);
135 + } else if (inner.Json) {
136 + _setOnDispatchType(dispatchType, 'type', 'json');
137 + } else {
138 + _setOnDispatchType(dispatchType, 'type', Object.keys(inner)[0].toLowerCase());
139 + }
140 +
141 + return dispatchType;
142 + };
143 +
144 + if (column.column_type.Scalar) {
145 + return handleInner(dispatchType, column.column_type.Scalar.column_type);
146 + } else if (column.column_type.Array) {
147 + return handleInner(dispatchType, column.column_type.Array.inner);
148 + } else {
149 + return dispatchType;
150 + }
151 + };
Newer Older