Skip to content

Commit b106cb0

Browse files
committed
Enabling Byte over ports in the compiler.
Injecting _Json_encodeBytes and _Json_decodeBytes kernel functions directly, not through a customized Json package.
1 parent 922b635 commit b106cb0

File tree

8 files changed

+109
-4
lines changed

8 files changed

+109
-4
lines changed

scripts/replacements.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,32 @@ var string = '';
9494
\t\t);
9595
\t}
9696
\treturn _Utils_Tuple2(offset, string.join(''));
97-
});`);
97+
});`)
98+
99+
/* Add Bytes encoder/decoder for ports support.
100+
Allows Bytes.Bytes to be sent through ports, mapping to Uint8Array on the JS side.
101+
*/
102+
.replace(
103+
`var _Json_encodeNull = _Json_wrap(null);`,
104+
`var _Json_encodeNull = _Json_wrap(null);
105+
106+
// BYTES FOR PORTS
107+
var _Json_decodeBytes = _Json_decodePrim(function(value) {
108+
\tif (value instanceof Uint8Array) {
109+
\t\treturn $elm$core$Result$Ok(new DataView(value.buffer, value.byteOffset, value.byteLength));
110+
\t}
111+
\tif (value instanceof ArrayBuffer) {
112+
\t\treturn $elm$core$Result$Ok(new DataView(value));
113+
\t}
114+
\tif (value instanceof DataView) {
115+
\t\treturn $elm$core$Result$Ok(value);
116+
\t}
117+
\treturn _Json_expecting('a BYTES value (Uint8Array, ArrayBuffer, or DataView)', value);
118+
});
119+
120+
var _Json_encodeBytes = function(bytes) {
121+
\treturn _Json_wrap(new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength));
122+
};`
123+
);
98124

99125
fs.writeFileSync(path, data, { encoding: 'utf8', flag: 'w' });

src/Compiler/Canonicalize/Effects.elm

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ checkPayload tipe =
207207
Can.TType home name args ->
208208
case args of
209209
[] ->
210-
if isJson home name || isString home name || isIntFloatBool home name then
210+
if isJson home name || isString home name || isIntFloatBool home name || isBytes home name then
211211
Ok ()
212212

213213
else
@@ -306,3 +306,11 @@ isArray home name =
306306
== ModuleName.array
307307
&& name
308308
== Name.array
309+
310+
311+
isBytes : IO.Canonical -> Name.Name -> Bool
312+
isBytes home name =
313+
home
314+
== ModuleName.bytes
315+
&& name
316+
== Name.bytes

src/Compiler/Data/Name.elm

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ module Compiler.Data.Name exposing
44
, basics
55
, bitwise
66
, bool
7+
, bytes
78
, char
89
, cmd
910
, debug
@@ -356,6 +357,11 @@ dict =
356357
"Dict"
357358

358359

360+
bytes : Name
361+
bytes =
362+
"Bytes"
363+
364+
359365
tuple : Name
360366
tuple =
361367
"Tuple"

src/Compiler/Generate/JavaScript.elm

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,30 @@ emptyState startingLine =
267267

268268
stateToBuilder : State -> String
269269
stateToBuilder (State (JS.Builder revKernels code _ _ _) _) =
270-
prependBuilders revKernels code
270+
prependBuilders revKernels (bytesForPorts ++ code)
271+
272+
273+
bytesForPorts : String
274+
bytesForPorts =
275+
"""
276+
// BYTES FOR PORTS
277+
var _Json_decodeBytes = _Json_decodePrim(function(value) {
278+
if (value instanceof Uint8Array) {
279+
return $elm$core$Result$Ok(new DataView(value.buffer, value.byteOffset, value.byteLength));
280+
}
281+
if (value instanceof ArrayBuffer) {
282+
return $elm$core$Result$Ok(new DataView(value));
283+
}
284+
if (value instanceof DataView) {
285+
return $elm$core$Result$Ok(value);
286+
}
287+
return _Json_expecting('a BYTES value (Uint8Array, ArrayBuffer, or DataView)', value);
288+
});
289+
290+
var _Json_encodeBytes = function(bytes) {
291+
return _Json_wrap(new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength));
292+
};
293+
"""
271294

272295

273296
prependBuilders : List String -> String -> String

src/Compiler/Guida/ModuleName.elm

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ module Compiler.Guida.ModuleName exposing
22
( Raw
33
, array
44
, basics
5+
, bytes
56
, canonicalDecoder
67
, canonicalEncoder
78
, char
@@ -283,6 +284,15 @@ jsonEncode =
283284

284285

285286

287+
-- BYTES
288+
289+
290+
bytes : Canonical
291+
bytes =
292+
Canonical Pkg.bytes "Bytes"
293+
294+
295+
286296
-- WEBGL
287297

288298

src/Compiler/Guida/Package.elm

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module Compiler.Guida.Package exposing
33
, Name
44
, Project
55
, browser
6+
, bytes
67
, compareName
78
, core
89
, decoder
@@ -144,6 +145,11 @@ json =
144145
toName elm "json"
145146

146147

148+
bytes : Name
149+
bytes =
150+
toName elm "bytes"
151+
152+
147153
http : Name
148154
http =
149155
toName elm "http"

src/Compiler/Optimize/Port.elm

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ toEncoder tipe =
5858
else if name == Name.value then
5959
Names.registerGlobal A.zero ModuleName.basics Name.identity_
6060

61+
else if name == Name.bytes then
62+
encode "bytes"
63+
64+
else if name == Name.bytes then
65+
encodeBytes
66+
6167
else
6268
crash "toEncoder: bad custom type"
6369

@@ -271,6 +277,12 @@ toDecoder tipe =
271277
( "Value", [] ) ->
272278
decode "value"
273279

280+
( "Bytes", [] ) ->
281+
decode "bytes"
282+
283+
( "Bytes", [] ) ->
284+
decodeBytes
285+
274286
( "Maybe", [ arg ] ) ->
275287
decodeMaybe arg
276288

@@ -478,3 +490,17 @@ encode name =
478490
decode : Name -> Names.Tracker Opt.Expr
479491
decode name =
480492
Names.registerGlobal A.zero ModuleName.jsonDecode name
493+
494+
495+
496+
-- BYTES HELPERS
497+
498+
499+
encodeBytes : Names.Tracker Opt.Expr
500+
encodeBytes =
501+
Names.registerKernel Name.json (Opt.VarKernel A.zero Name.json "encodeBytes")
502+
503+
504+
decodeBytes : Names.Tracker Opt.Expr
505+
decodeBytes =
506+
Names.registerKernel Name.json (Opt.VarKernel A.zero Name.json "decodeBytes")

src/Compiler/Reporting/Error/Canonicalize.elm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,7 @@ toReport source err =
704704
[ D.reflow "I cannot handle that. The types that CAN flow in and out of Guida include:"
705705
, D.indent 4 <|
706706
D.reflow
707-
"Ints, Floats, Bools, Strings, Maybes, Lists, Arrays, tuples, records, and JSON values."
707+
"Ints, Floats, Bools, Strings, Maybes, Lists, Arrays, tuples, records, JSON values, and Bytes."
708708
, D.reflow
709709
"Since JSON values can flow through, you can use JSON encoders and decoders to allow other types through as well. More advanced users often just do everything with encoders and decoders for more control and better errors."
710710
]

0 commit comments

Comments
 (0)