Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add bidnings to TextEncoder/TextDecoder #78

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
* `DataTransfer` bindings (#51)
* `WorkerGlobalScope`, `WindowOrWorkerGlobalScope`, `WorkerNavigator`, and `WorkerLocation` bindings (#57)
* `Response` constructors to `Fetch` bindings (#64)
* `TextEncoder` and `TextDecoder` bindings (#78)

### Fixed
* `ofElement` was incorrectly returning `Dom.htmlElement` type instead of the enclosing element type (#60)
Expand Down
24 changes: 24 additions & 0 deletions lib/js/tests/Webapi/Webapi__TextDecoder__test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use strict';

var Webapi__TextDecoder = require("../../src/Webapi/Webapi__TextDecoder.js");

var decoder1 = new TextDecoder();

var decoder2 = Webapi__TextDecoder.makeWithOptions(undefined, true, true, undefined);

var message = new Uint8Array([
72,
101,
108,
108,
111
]);

console.log(decoder1.decode(message));

console.log(Webapi__TextDecoder.decodeStream(decoder1, message));

exports.decoder1 = decoder1;
exports.decoder2 = decoder2;
exports.message = message;
/* decoder1 Not a pure module */
19 changes: 19 additions & 0 deletions lib/js/tests/Webapi/Webapi__TextEncoder__test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
'use strict';


var encoder = new TextEncoder();

console.log(encoder.encoding);

console.log(encoder.encode("Hello"));

var buffer = new Uint8Array([]);

var result = encoder.encodeInto("Hello", buffer);

console.log(result.read, result.written);

exports.encoder = encoder;
exports.buffer = buffer;
exports.result = result;
/* encoder Not a pure module */
2 changes: 2 additions & 0 deletions src/Webapi.res
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ module File = Webapi__File
module FileList = Webapi__FileList
module Fetch = Webapi__Fetch
module FormData = Webapi__FormData
module TextEncoder = Webapi__TextEncoder
module TextDecoder = Webapi__TextDecoder

module Navigator = Webapi__Navigator

Expand Down
35 changes: 35 additions & 0 deletions src/Webapi/Webapi__TextDecoder.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
type t = {
encoding: string,
fatal: bool,
ignoreBOM: bool,
}

type decoderOptions

type decodeOptions

%%private(
@new external _makeWithOptions: (string, decoderOptions) => t = "TextDecoder"

@obj
external makeDecoderOptions: (
~fatal: option<bool>=?,
~ignoreBOM: option<bool>=?,
unit,
) => decoderOptions = ""
)

@new external make: unit => t = "TextDecoder"

let makeWithOptions = (~encoding="utf-8", ~fatal=?, ~ignoreBOM=?, ()) =>
_makeWithOptions(encoding, makeDecoderOptions(~fatal, ~ignoreBOM, ()))
Comment on lines +11 to +25
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I appreciate the sentiment to make the bindings more usable, we want these bindings to be zero-cost as much as possible. In this case ReScript 10 should have a new feature that makes makeDecoderOptions unnecessary, but it will be easier to switch to the upcoming style if the exported API takes a decoderOptions.

Please remove the private wrappers and export the more difficult to use way for now; here and below.

Suggested change
%%private(
@new external _makeWithOptions: (string, decoderOptions) => t = "TextDecoder"
@obj
external makeDecoderOptions: (
~fatal: option<bool>=?,
~ignoreBOM: option<bool>=?,
unit,
) => decoderOptions = ""
)
@new external make: unit => t = "TextDecoder"
let makeWithOptions = (~encoding="utf-8", ~fatal=?, ~ignoreBOM=?, ()) =>
_makeWithOptions(encoding, makeDecoderOptions(~fatal, ~ignoreBOM, ()))
@obj
external makeDecoderOptions: (
~fatal: option<bool>=?,
~ignoreBOM: option<bool>=?,
unit,
) => decoderOptions = ""
@new external make: unit => t = "TextDecoder"
@new external makeWithOptions: (string, decoderOptions) => t = "TextDecoder"

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could still have a name argument for the encoding helps people to know that that parameter is supposed to be:
@new external makeWithOptions: (~encoding: string, decoderOptions) => t = "TextDecoder"


%%private(
@obj external makeDecodeOptions: (~stream: bool) => decodeOptions = ""

@send external _decodeWithOptions: (t, Js.TypedArray2.Uint8Array.t, decodeOptions) => t = "decode"
)

@send external decode: (t, Js.TypedArray2.Uint8Array.t) => string = "decode"

let decodeStream = (t, array) => _decodeWithOptions(t, array, makeDecodeOptions(~stream=true))
16 changes: 16 additions & 0 deletions src/Webapi/Webapi__TextEncoder.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
type t = {
// This always returns "utf-8"
encoding: string,
}

@new external make: unit => t = "TextEncoder"

@send external encode: (t, string) => Js.TypedArray2.Uint8Array.t = "encode"

type encodeIntoResult = {
read: int,
written: int,
}

@send
external encodeInto: (t, string, Js.TypedArray2.Uint8Array.t) => encodeIntoResult = "encodeInto"
9 changes: 9 additions & 0 deletions tests/Webapi/Webapi__TextDecoder__test.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
open Js.TypedArray2
open Webapi.TextDecoder

let decoder1 = make()
let decoder2 = makeWithOptions(~fatal=true, ~ignoreBOM=true, ())

let message = Uint8Array.make([72, 101, 108, 108, 111])
decoder1->decode(message)->Js.log
decoder1->decodeStream(message)->Js.log
12 changes: 12 additions & 0 deletions tests/Webapi/Webapi__TextEncoder__test.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
open Js.TypedArray2
open Webapi.TextEncoder

let encoder = make()

Js.log(encoder.encoding)

encoder->encode("Hello")->Js.log

let buffer = Uint8Array.make([])
let result = encoder->encodeInto("Hello", buffer)
Js.log2(result.read, result.written)