From 1d16f0920819ecb99c01badec2b8b2d2ddbfb3f5 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sat, 9 Jul 2022 11:58:37 +0100 Subject: [PATCH 01/45] Start working on Http.roc --- examples/interactive/cli-platform/Effect.roc | 2 + examples/interactive/cli-platform/Http.roc | 93 +++++++++++++ .../interactive/cli-platform/HttpStatus.roc | 125 ++++++++++++++++++ 3 files changed, 220 insertions(+) create mode 100644 examples/interactive/cli-platform/Http.roc create mode 100644 examples/interactive/cli-platform/HttpStatus.roc diff --git a/examples/interactive/cli-platform/Effect.roc b/examples/interactive/cli-platform/Effect.roc index a7ebc51d8c..3a635346e9 100644 --- a/examples/interactive/cli-platform/Effect.roc +++ b/examples/interactive/cli-platform/Effect.roc @@ -6,3 +6,5 @@ hosted Effect putLine : Str -> Effect {} getLine : Effect Str + +sendRequest : Request response -> Effect response diff --git a/examples/interactive/cli-platform/Http.roc b/examples/interactive/cli-platform/Http.roc new file mode 100644 index 0000000000..ee069b1672 --- /dev/null +++ b/examples/interactive/cli-platform/Http.roc @@ -0,0 +1,93 @@ +interface Http + exposes [ + Error, + Request, + Header, + header, + Body, + emptyBody, + bytesBody, + stringBody, + jsonBody, + multiPartBody, + ] + imports [pf.Effect, Task.{ Task }, Encode.Encoding, Json] + +Error : [ + BadUrl Str, + Timeout, + NetworkError, + BadStatus U16, + BadBody Str, +] + +Request a : { + method : Str, + headers : List Header, + url : Str, + body : Body, + expect : Expect a, # TODO: rename this, it clashes with the test thingy + timeout : Maybe Float, + tracker : Maybe Str, + allowCookiesFromOtherDomains : Bool +} + + + +Header : [Header Str Str] + +## An HTTP header for configuring requests. See a bunch of common headers +## [here](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields). +## +header : Str, Str -> Header +header = Header + + + +Body : [ + Body [MimeType Str] (List U8), + EmptyBody +] + +emptyBody : Body +emptyBody = + EmptyBody + +bytesBody : [MimeType Str], List U8 -> Body +bytesBody = + Body + +stringBody : [MimeType Str], Str -> Body +stringBody = \mimeType, str -> + Body mimeType (Str.toUtf8 str) + +jsonBody : a -> Body | a has Encoding +jsonBody = \val -> + Body (MimeType "application/json") (Encode.toBytes val Json.format) + +multiPartBody : List Part -> Body +multiPartBody parts = + boundary = "7MA4YWxkTrZu0gW" # TODO, what's this exactly? + beforeName = Str.toUtf8 "-- \(boundary)\r\nContent-Disposition: form-data; name=\"" + afterName = Str.toUtf8 "\"\r\n" + bytes = List.walk parts [] \acc, (Part name bytes) -> + acc + |> List.concat beforeName + |> List.concat name + |> List.concat afterName + |> List.concat bytes + + Body (MimeType "multipart/form-data;boundary=\"\(boundary)\"") bytes + + +Part : [Part Str (List U8)] + +bytesPart : Str, List U8 -> Part +bytesPart = + Part + +stringPart : Str, Str -> Part +stringPart = \name, str -> + Part name (Str.toUtf8 str) + + diff --git a/examples/interactive/cli-platform/HttpStatus.roc b/examples/interactive/cli-platform/HttpStatus.roc new file mode 100644 index 0000000000..29cbce7619 --- /dev/null +++ b/examples/interactive/cli-platform/HttpStatus.roc @@ -0,0 +1,125 @@ +interface Stdout + exposes [line] + imports [pf.Effect, Task.{ Task }] + +Error : [ + BadUrl Str, + Timeout, + NetworkError, + BadStatus U16, + BadBody Str, +] + +# https://datatracker.ietf.org/doc/html/rfc7231#section-6 +# statusTo +# | 100 | Continue | Section 6.2.1 | +# | 101 | Switching Protocols | Section 6.2.2 | +# | 200 | OK | Section 6.3.1 | +# | 201 | Created | Section 6.3.2 | +# | 202 | Accepted | Section 6.3.3 | +# | 203 | Non-Authoritative Information | Section 6.3.4 | +# | 204 | No Content | Section 6.3.5 | +# | 205 | Reset Content | Section 6.3.6 | +# | 206 | Partial Content | Section 4.1 of [RFC7233] | +# | 300 | Multiple Choices | Section 6.4.1 | +# | 301 | Moved Permanently | Section 6.4.2 | +# | 302 | Found | Section 6.4.3 | +# | 303 | See Other | Section 6.4.4 | +# | 304 | Not Modified | Section 4.1 of [RFC7232] | +# | 305 | Use Proxy | Section 6.4.5 | +# | 307 | Temporary Redirect | Section 6.4.7 | +# | 400 | Bad Request | Section 6.5.1 | +# | 401 | Unauthorized | Section 3.1 of [RFC7235] | +# | 402 | Payment Required | Section 6.5.2 | +# | 403 | Forbidden | Section 6.5.3 | +# | 404 | Not Found | Section 6.5.4 | +# | 405 | Method Not Allowed | Section 6.5.5 | +# | 406 | Not Acceptable | Section 6.5.6 | +# | 407 | Proxy Authentication Required | Section 3.2 of [RFC7235] | +# | 408 | Request Timeout | Section 6.5.7 | +# | 409 | Conflict | Section 6.5.8 | +# | 410 | Gone | Section 6.5.9 | +# | 411 | Length Required | Section 6.5.10 | +# | 412 | Precondition Failed | Section 4.2 of [RFC7232] | +# | 413 | Payload Too Large | Section 6.5.11 | +# | 414 | URI Too Long | Section 6.5.12 | +# | 415 | Unsupported Media Type | Section 6.5.13 | +# | 416 | Range Not Satisfiable | Section 4.4 of [RFC7233] | +# | 417 | Expectation Failed | Section 6.5.14 | +# | 426 | Upgrade Required | Section 6.5.15 | +# | 500 | Internal Server Error | Section 6.6.1 | +# | 501 | Not Implemented | Section 6.6.2 | +# | 502 | Bad Gateway | Section 6.6.3 | +# | 503 | Service Unavailable | Section 6.6.4 | +# | 504 | Gateway Timeout | Section 6.6.5 | +# | 505 | HTTP Version Not Supported | Section 6.6.6 | +StatusCode : [ + Continue, + SwitchingProtocols, + OK, + Created, + Accepted, + NonAuthoritativeInformation, + NoContent, + ResetContent, + PartialContent, + MultipleChoices, + MovedPermanently, + Found, + SeeOther, + NotModified, + UseProxy, + TemporaryRedirect, + BadRequest, + Unauthorized, + PaymentRequired, + Forbidden, + NotFound, + MethodNotAllowed, + NotAcceptable, + ProxyAuthenticationRequired, + RequestTimeout, + Conflict, + Gone, + LengthRequired, + PreconditionFailed, + PayloadTooLarge, + URITooLong, + UnsupportedMediaType, + RangeNotSatisfiable, + ExpectationFailed, + UpgradeRequired, + InternalServerError, + NotImplemented, + BadGateway, + ServiceUnavailable, + GatewayTimeout, + HTTPVersionNotSupported, + CustomStatus U16, +] + +StatusCategory : [ + Informational, + Successful, + Redirection, + ClientError, + ServerError, + UnknownStatusCategory, +] + +statusCategory : U16 -> StatusCategory +statusCategory = \code -> + if code >= 600 then + UnknownStatusCategory + else if code >= 500 then + ServerError + else if code >= 400 then + ClientError + else if code >= 300 then + Redirection + else if code >= 200 then + Successful + else if code >= 100 then + Informational + else + UnknownStatusCategory From b10343380efe3897e8c45d9f0171d0fcf8995367 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sat, 9 Jul 2022 19:46:41 +0100 Subject: [PATCH 02/45] Handle http responses --- examples/interactive/cli-platform/Http.roc | 101 +++++++++++++++------ 1 file changed, 71 insertions(+), 30 deletions(-) diff --git a/examples/interactive/cli-platform/Http.roc b/examples/interactive/cli-platform/Http.roc index ee069b1672..b6bd7db7db 100644 --- a/examples/interactive/cli-platform/Http.roc +++ b/examples/interactive/cli-platform/Http.roc @@ -10,43 +10,36 @@ interface Http stringBody, jsonBody, multiPartBody, + stringPart, + bytesPart, + handleStringResponse, + handleEncodedResponse, ] - imports [pf.Effect, Task.{ Task }, Encode.Encoding, Json] - -Error : [ - BadUrl Str, - Timeout, - NetworkError, - BadStatus U16, - BadBody Str, -] + imports [Encode.{ Encoding }, Json] Request a : { method : Str, headers : List Header, url : Str, body : Body, - expect : Expect a, # TODO: rename this, it clashes with the test thingy - timeout : Maybe Float, - tracker : Maybe Str, - allowCookiesFromOtherDomains : Bool + responseHandler : ResponseHandler a, + timeout : Result F64 {}, + tracker : Result Str {}, + allowCookiesFromOtherDomains : Bool, } - - -Header : [Header Str Str] +Header : { name : Str, value : Str } ## An HTTP header for configuring requests. See a bunch of common headers ## [here](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields). ## header : Str, Str -> Header -header = Header - - +header = \name, value -> + { name, value } Body : [ Body [MimeType Str] (List U8), - EmptyBody + EmptyBody, ] emptyBody : Body @@ -66,19 +59,19 @@ jsonBody = \val -> Body (MimeType "application/json") (Encode.toBytes val Json.format) multiPartBody : List Part -> Body -multiPartBody parts = - boundary = "7MA4YWxkTrZu0gW" # TODO, what's this exactly? +multiPartBody = \parts -> + boundary = "7MA4YWxkTrZu0gW" # TODO: what's this exactly? a hash of all the part bodies? beforeName = Str.toUtf8 "-- \(boundary)\r\nContent-Disposition: form-data; name=\"" afterName = Str.toUtf8 "\"\r\n" - bytes = List.walk parts [] \acc, (Part name bytes) -> - acc - |> List.concat beforeName - |> List.concat name - |> List.concat afterName - |> List.concat bytes - - Body (MimeType "multipart/form-data;boundary=\"\(boundary)\"") bytes + appendPart = \buffer, Part name partBytes -> + buffer + |> List.concat beforeName + |> List.concat (Str.toUtf8 name) + |> List.concat afterName + |> List.concat partBytes + bodyBytes = List.walk parts [] appendPart + Body (MimeType "multipart/form-data;boundary=\"\(boundary)\"") bodyBytes Part : [Part Str (List U8)] @@ -90,4 +83,52 @@ stringPart : Str, Str -> Part stringPart = \name, str -> Part name (Str.toUtf8 str) +Error : [ + BadUrl Str, + Timeout, + NetworkError, + BadStatus U16, + BadBody Str, +] +Response body : [ + BadUrl Str, + Timeout, + NetworkError, + BadStatus Metadata body, + GoodStatus Metadata body, +] + +Metadata : { + url : Str, + statusCode : U16, + statusText : Str, + headers : List Header, +} + +ResponseHandler a : Response (List U8) -> Result a Error + +handleEncodedResponse : (List U8 -> Result a Str) -> ResponseHandler a +handleEncodedResponse = \decoder -> + \response -> + when response is + BadUrl url -> Err (BadUrl url) + Timeout -> Err Timeout + NetworkError -> Err NetworkError + BadStatus metadata _ -> Err (BadStatus metadata.statusCode) + GoodStatus _ bodyBytes -> decoder bodyBytes |> Result.mapErr BadBody + +handleStringResponse : ResponseHandler Str +handleStringResponse = \response -> + when response is + BadUrl url -> Err (BadUrl url) + Timeout -> Err Timeout + NetworkError -> Err NetworkError + BadStatus metadata _ -> Err (BadStatus metadata.statusCode) + GoodStatus _ bodyBytes -> + Str.fromUtf8 bodyBytes + |> Result.mapErr + \BadUtf8 _ pos -> + position = Num.toStr pos + + BadBody "Invalid UTF-8 at byte offset \(position)" From bf37023578084f20ebb3e9d93e18f85de43948b0 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Wed, 13 Jul 2022 20:07:06 +0100 Subject: [PATCH 03/45] Install reqwest in http example, hack bindgen --- Cargo.lock | 130 +-- crates/bindgen/src/types.rs | 2 +- examples/interactive/cli-platform/.gitignore | 1 + examples/interactive/cli-platform/Cargo.lock | 912 ++++++++++++++++++- examples/interactive/cli-platform/Cargo.toml | 1 + examples/interactive/cli-platform/src/lib.rs | 65 +- 6 files changed, 1041 insertions(+), 70 deletions(-) create mode 100644 examples/interactive/cli-platform/.gitignore diff --git a/Cargo.lock b/Cargo.lock index e8da71cc88..02d6153877 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -146,16 +146,16 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.65" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11a17d453482a265fd5f8479f2a3f405566e6ca627837aaddb85af8b1ab8ef61" +checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" dependencies = [ "addr2line", "cc", "cfg-if 1.0.0", "libc", "miniz_oxide", - "object 0.28.4", + "object 0.29.0", "rustc-demangle", ] @@ -237,9 +237,9 @@ dependencies = [ [[package]] name = "bitvec" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1489fcb93a5bb47da0462ca93ad252ad6af2145cce58d10d46a83931ba9f016b" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" dependencies = [ "funty 2.0.0", "radium 0.7.0", @@ -330,9 +330,9 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.9.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdead85bdec19c194affaeeb670c0e41fe23de31459efd1c174d049269cf02cc" +checksum = "c53dfa917ec274df8ed3c572698f381a24eef2efba9492d797301b72b6db408a" dependencies = [ "bytemuck_derive", ] @@ -475,9 +475,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.8" +version = "3.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190814073e85d238f31ff738fcb0bf6910cedeb73376c87cd69291028966fd83" +checksum = "d646c7ade5eb07c4aa20e907a922750df0c448892513714fd3e4acbc7130829f" dependencies = [ "atty", "bitflags", @@ -660,9 +660,9 @@ checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935" [[package]] name = "const_format" -version = "0.2.25" +version = "0.2.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2906f2480cdc015e998deac388331a0f1c1cd88744948c749513020c83c370bc" +checksum = "939dc9e2eb9077e0679d2ce32de1ded8531779360b003b4a972a7a39ec263495" dependencies = [ "const_format_proc_macros", ] @@ -801,9 +801,9 @@ dependencies = [ [[package]] name = "corosensei" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab4b310cff9117ec16d05970743c20df3eaddafd461829f2758e76a8de2863a9" +checksum = "9847f90f32a50b0dcbd68bc23ff242798b13080b97b0569f6ed96a45ce4cf2cd" dependencies = [ "autocfg", "cfg-if 1.0.0", @@ -1019,9 +1019,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +checksum = "2ccfd8c0ee4cce11e45b3fd6f9d5e69e0cc62912aa6a0cb1bf4617b0eba5a12f" dependencies = [ "generic-array 0.14.5", "typenum", @@ -1246,7 +1246,7 @@ checksum = "64fba5a42bd76a17cad4bfa00de168ee1cbfa06a5e8ce992ae880218c05641a9" dependencies = [ "byteorder", "dynasm", - "memmap2 0.5.4", + "memmap2 0.5.5", ] [[package]] @@ -1713,9 +1713,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" +checksum = "607c8a29735385251a339424dd462993c0fed8fa09d378f259377df08c126022" dependencies = [ "ahash", "bumpalo", @@ -1805,7 +1805,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" dependencies = [ "autocfg", - "hashbrown 0.12.1", + "hashbrown 0.12.2", "serde", ] @@ -2153,9 +2153,9 @@ dependencies = [ [[package]] name = "memmap2" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5172b50c23043ff43dd53e51392f36519d9b35a8f3a410d30ece5d1aedd58ae" +checksum = "3a79b39c93a7a5a27eeaf9a23b5ff43f1b9e0ad6b1cdd441140ae53c35613fc7" dependencies = [ "libc", ] @@ -2556,7 +2556,7 @@ checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" dependencies = [ "crc32fast", "flate2", - "hashbrown 0.12.1", + "hashbrown 0.12.2", "indexmap", "memchr", ] @@ -2595,9 +2595,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" +checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" [[package]] name = "oorandom" @@ -2906,15 +2906,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c" +checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" [[package]] name = "plotters-svg" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9" +checksum = "e0918736323d1baff32ee0eade54984f6f201ad7e97d5cfb5d6ab4a358529615" dependencies = [ "plotters-backend", ] @@ -3196,9 +3196,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.5.6" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" +checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" dependencies = [ "aho-corasick", "memchr", @@ -3213,9 +3213,9 @@ checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" [[package]] name = "regex-syntax" -version = "0.6.26" +version = "0.6.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" +checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" [[package]] name = "region" @@ -3287,7 +3287,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cec2b3485b07d96ddfd3134767b8a447b45ea4eb91448d0a35180ec0ffd5ed15" dependencies = [ "bytecheck", - "hashbrown 0.12.1", + "hashbrown 0.12.2", "ptr_meta", "rend", "rkyv_derive", @@ -3319,7 +3319,7 @@ name = "roc-bindgen" version = "0.1.0" dependencies = [ "bumpalo", - "clap 3.2.8", + "clap 3.2.11", "cli_utils", "ctor", "dircpy", @@ -3435,7 +3435,7 @@ dependencies = [ name = "roc_can" version = "0.1.0" dependencies = [ - "bitvec 1.0.0", + "bitvec 1.0.1", "bumpalo", "indoc", "pretty_assertions", @@ -3455,7 +3455,7 @@ name = "roc_cli" version = "0.1.0" dependencies = [ "bumpalo", - "clap 3.2.8", + "clap 3.2.11", "cli_utils", "const_format", "criterion", @@ -3515,9 +3515,9 @@ dependencies = [ name = "roc_collections" version = "0.1.0" dependencies = [ - "bitvec 1.0.0", + "bitvec 1.0.1", "bumpalo", - "hashbrown 0.12.1", + "hashbrown 0.12.2", "im", "im-rc", "wyhash", @@ -3596,7 +3596,7 @@ dependencies = [ name = "roc_docs_cli" version = "0.1.0" dependencies = [ - "clap 3.2.8", + "clap 3.2.11", "roc_docs", ] @@ -3725,7 +3725,7 @@ dependencies = [ name = "roc_gen_wasm" version = "0.1.0" dependencies = [ - "bitvec 1.0.0", + "bitvec 1.0.1", "bumpalo", "roc_builtins", "roc_collections", @@ -3769,7 +3769,7 @@ version = "0.1.0" dependencies = [ "bincode", "bumpalo", - "clap 3.2.8", + "clap 3.2.11", "iced-x86", "mach_object", "memmap2 0.5.4", @@ -3850,7 +3850,7 @@ name = "roc_mono" version = "0.1.0" dependencies = [ "bumpalo", - "hashbrown 0.12.1", + "hashbrown 0.12.2", "roc_builtins", "roc_can", "roc_collections", @@ -4147,14 +4147,14 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.11", + "semver 1.0.12", ] [[package]] name = "rustix" -version = "0.35.6" +version = "0.35.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef258c11e17f5c01979a10543a30a4e12faef6aab217a74266e747eefa3aed88" +checksum = "d51cc38aa10f6bbb377ed28197aa052aa4e2b762c22be9d3153d01822587e787" dependencies = [ "bitflags", "errno", @@ -4255,9 +4255,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d92beeab217753479be2f74e54187a6aed4c125ff0703a866c3147a02f0c6dd" +checksum = "a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1" [[package]] name = "semver-parser" @@ -4276,9 +4276,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.137" +version = "1.0.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" +checksum = "0171ebb889e45aa68b44aee0859b3eede84c6f5f5c228e6f140c0b2a0a46cad6" dependencies = [ "serde_derive", ] @@ -4316,9 +4316,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.137" +version = "1.0.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" +checksum = "dc1d3230c1de7932af58ad8ffbe1d784bd55efd5a9d84ac24f69c72d83543dfb" dependencies = [ "proc-macro2", "quote", @@ -4338,9 +4338,9 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.8.24" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707d15895415db6628332b737c838b88c598522e4dc70647e59b72312924aebc" +checksum = "1ec0091e1f5aa338283ce049bd9dfefd55e1f168ac233e85c1ffe0038fb48cbe" dependencies = [ "indexmap", "ryu", @@ -4526,7 +4526,7 @@ dependencies = [ "dlib", "lazy_static", "log", - "memmap2 0.5.4", + "memmap2 0.5.5", "nix 0.24.1", "pkg-config", "wayland-client", @@ -4987,9 +4987,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c" +checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2" dependencies = [ "proc-macro2", "quote", @@ -5036,9 +5036,9 @@ checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "ucd-trie" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" +checksum = "89570599c4fe5585de2b388aab47e99f7fa4e9238a1399f707a02e356058141c" [[package]] name = "unicase" @@ -5220,9 +5220,9 @@ checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be" [[package]] name = "wasm-encoder" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f0c17267a5ffd6ae3d897589460e21db1673c84fb7016b909c9691369a75ea" +checksum = "f76068e87fe9b837a6bc2ccded66784173eadb828c4168643e9fddf6f9ed2e61" dependencies = [ "leb128", ] @@ -5368,7 +5368,7 @@ dependencies = [ "enumset", "lazy_static", "loupe", - "memmap2 0.5.4", + "memmap2 0.5.5", "more-asserts", "rustc-demangle", "serde", @@ -5548,9 +5548,9 @@ checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" [[package]] name = "wast" -version = "42.0.0" +version = "44.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "badcb03f976f983ff0daf294da9697be659442f61e6b0942bb37a2b6cbfe9dd4" +checksum = "5f474d1b1cb7d92e5360b293f28e8bc9b2d115197a5bbf76bdbfba9161cf9cdc" dependencies = [ "leb128", "memchr", @@ -5560,9 +5560,9 @@ dependencies = [ [[package]] name = "wat" -version = "1.0.44" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b92f20b742ac527066c8414bc0637352661b68cab07ef42586cefaba71c965cf" +checksum = "82d002ce2eca0730c6df2c21719e9c4d8d0cafe74fb0cb8ff137c0774b8e4ed1" dependencies = [ "wast", ] diff --git a/crates/bindgen/src/types.rs b/crates/bindgen/src/types.rs index 4bfd853b13..b2ddccc77b 100644 --- a/crates/bindgen/src/types.rs +++ b/crates/bindgen/src/types.rs @@ -10,7 +10,7 @@ use roc_collections::VecMap; use roc_module::symbol::{Interns, Symbol}; use roc_mono::layout::{ cmp_fields, ext_var_is_empty_tag_union, round_up_to_alignment, Builtin, Layout, LayoutCache, - UnionLayout, + UnionLayout, FieldOrderHash, }; use roc_target::TargetInfo; use roc_types::{ diff --git a/examples/interactive/cli-platform/.gitignore b/examples/interactive/cli-platform/.gitignore new file mode 100644 index 0000000000..b22743bb1e --- /dev/null +++ b/examples/interactive/cli-platform/.gitignore @@ -0,0 +1 @@ +src/glue.rs diff --git a/examples/interactive/cli-platform/Cargo.lock b/examples/interactive/cli-platform/Cargo.lock index 285570ef1c..f8093a1c63 100644 --- a/examples/interactive/cli-platform/Cargo.lock +++ b/examples/interactive/cli-platform/Cargo.lock @@ -8,19 +8,524 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bumpalo" +version = "3.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" + +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + +[[package]] +name = "cc" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "encoding_rs" +version = "0.8.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "fastrand" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +dependencies = [ + "instant", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +dependencies = [ + "matches", + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" + +[[package]] +name = "futures-sink" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" + +[[package]] +name = "futures-task" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" + +[[package]] +name = "futures-util" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "h2" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "607c8a29735385251a339424dd462993c0fed8fa09d378f259377df08c126022" + [[package]] name = "host" version = "0.1.0" dependencies = [ "libc", + "reqwest", "roc_std", ] [[package]] -name = "libc" -version = "0.2.106" +name = "http" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a60553f9a9e039a333b4e9b20573b9e9b9c0bb3a11e201ccc48ef4283456d673" +checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "hyper" +version = "0.14.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ipnet" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" + +[[package]] +name = "itoa" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" + +[[package]] +name = "js-sys" +version = "0.3.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "matches" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + +[[package]] +name = "mio" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys", +] + +[[package]] +name = "native-tls" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "once_cell" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" + +[[package]] +name = "openssl" +version = "0.10.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "618febf65336490dfcf20b73f885f5651a0c89c64c2d4a8c3662585a70bf5bd0" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5f9bd0c2710541a3cda73d6f9ac4f1b240de4ae261065d309dbe73d9dceb42f" +dependencies = [ + "autocfg", + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" + +[[package]] +name = "proc-macro2" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +dependencies = [ + "bitflags", +] + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "reqwest" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b75aa69a3f06bbcc66ede33af2af253c6f7a86b1ca0033f60c580a27074fbf92" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "lazy_static", + "log", + "mime", + "native-tls", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] [[package]] name = "roc_std" @@ -30,8 +535,409 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "ryu" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" + +[[package]] +name = "schannel" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" +dependencies = [ + "lazy_static", + "windows-sys", +] + +[[package]] +name = "security-framework" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.139" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0171ebb889e45aa68b44aee0859b3eede84c6f5f5c228e6f140c0b2a0a46cad6" + +[[package]] +name = "serde_json" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "slab" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" + +[[package]] +name = "socket2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "static_assertions" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "syn" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +dependencies = [ + "cfg-if", + "fastrand", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "tokio" +version = "1.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439" +dependencies = [ + "bytes", + "libc", + "memchr", + "mio", + "once_cell", + "pin-project-lite", + "socket2", + "winapi", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" + +[[package]] +name = "unicode-bidi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" + +[[package]] +name = "unicode-ident" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" + +[[package]] +name = "unicode-normalization" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "url" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +dependencies = [ + "form_urlencoded", + "idna", + "matches", + "percent-encoding", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de9a9cec1733468a8c657e57fa2413d2ae2c0129b95e87c5b72b8ace4d13f31f" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be" + +[[package]] +name = "web-sys" +version = "0.3.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] diff --git a/examples/interactive/cli-platform/Cargo.toml b/examples/interactive/cli-platform/Cargo.toml index 85cdec4c34..8f5e4ac288 100644 --- a/examples/interactive/cli-platform/Cargo.toml +++ b/examples/interactive/cli-platform/Cargo.toml @@ -19,5 +19,6 @@ path = "src/main.rs" [dependencies] roc_std = { path = "../../../crates/roc_std" } libc = "0.2" +reqwest = "0.11.11" [workspace] diff --git a/examples/interactive/cli-platform/src/lib.rs b/examples/interactive/cli-platform/src/lib.rs index 47e6e62424..525a730659 100644 --- a/examples/interactive/cli-platform/src/lib.rs +++ b/examples/interactive/cli-platform/src/lib.rs @@ -4,7 +4,8 @@ use core::alloc::Layout; use core::ffi::c_void; use core::mem::{ManuallyDrop, MaybeUninit}; use libc; -use roc_std::RocStr; +use reqwest::{Client, ClientBuilder, Request}; +use roc_std::{RocResult, RocList, RocStr}; use std::ffi::CStr; use std::os::raw::c_char; @@ -123,3 +124,65 @@ pub extern "C" fn roc_fx_putLine(line: &RocStr) { let string = line.as_str(); println!("{}", string); } + +// We just provide just one Client to the Roc program for simplicity, so it must be static in the host. +// `thread_local!` avoids contention between threads, should that ever arise +// `lazy_static` & `Mutex` might have easier-to-understand semantics for resources like cookies +use std::cell::RefCell; +std::thread_local! { + static HTTP_CLIENT: RefCell> = RefCell::new(None); +} + +struct RocHeader { + name: RocStr, + value: RocStr, +} + +// This is not the right Rust translation, it's something more complicated... +enum RocBody { + Body(RocStr, RocList), + EmptyBody +} + +#[repr(C)] +struct RocRequest { + method : RocStr, + headers : RocList, + url : RocStr, + body : RocBody, + responseHandler : *const u8, // Response (List U8) -> Result a Error + timeout : RocResult, + tracker : RocResult, + allowCookiesFromOtherDomains : bool, +} + +#[repr(C)] +struct RocMetadata { + url : RocStr, + statusCode : u16, + statusText : RocStr, + headers : RocList, +} + +enum RocResponseOfListU8 { + BadUrl(RocStr), + Timeout, + NetworkError, + BadStatus(RocMetadata, RocList), + GoodStatus(RocMetadata, RocList), +} + +#[no_mangle] +pub extern "C" fn roc_fx_send_request(req: RocRequest) { + + /* + + */ + + let rust_body_bytes: Vec = vec![]; + let roc_body_bytes = RocList::from_slice(&rust_body_bytes); + + let roc_response: RocResponseOfListU8 = todo!(); + + // call_the_closure +} From 15c5b6fcfe8b54cc5d7a6472f4ddc8dfe7d17efb Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Wed, 13 Jul 2022 22:35:01 +0100 Subject: [PATCH 04/45] Fix import error --- examples/interactive/cli-platform/Effect.roc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/interactive/cli-platform/Effect.roc b/examples/interactive/cli-platform/Effect.roc index 3a635346e9..76e41873e3 100644 --- a/examples/interactive/cli-platform/Effect.roc +++ b/examples/interactive/cli-platform/Effect.roc @@ -1,6 +1,6 @@ hosted Effect - exposes [Effect, after, map, always, forever, loop, putLine, getLine] - imports [] + exposes [Effect, after, map, always, forever, loop, putLine, getLine, sendRequest] + imports [Http.{ Request }] generates Effect with [after, map, always, forever, loop] putLine : Str -> Effect {} From 06eb45741bb5f57357f6eb7fda7ecb5f285fefef Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Wed, 13 Jul 2022 23:22:26 +0100 Subject: [PATCH 05/45] Http working with check and bindgen (but no effects) --- examples/interactive/cli-platform/Http.roc | 7 +++-- examples/interactive/cli-platform/main.roc | 35 +++++++++++++++++++--- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/examples/interactive/cli-platform/Http.roc b/examples/interactive/cli-platform/Http.roc index b6bd7db7db..2adb36cf4b 100644 --- a/examples/interactive/cli-platform/Http.roc +++ b/examples/interactive/cli-platform/Http.roc @@ -17,14 +17,17 @@ interface Http ] imports [Encode.{ Encoding }, Json] +TimeoutConfig : [WithTimeout F64, WithoutTimeout] +TrackerConfig : [WithTracker F64, WithoutTracker] + Request a : { method : Str, headers : List Header, url : Str, body : Body, responseHandler : ResponseHandler a, - timeout : Result F64 {}, - tracker : Result Str {}, + timeout : TimeoutConfig, + tracker : TrackerConfig, allowCookiesFromOtherDomains : Bool, } diff --git a/examples/interactive/cli-platform/main.roc b/examples/interactive/cli-platform/main.roc index 6d3d42a6d5..c4cf8938da 100644 --- a/examples/interactive/cli-platform/main.roc +++ b/examples/interactive/cli-platform/main.roc @@ -1,9 +1,36 @@ platform "cli" - requires {} { main : Task {} [] * } + requires {} { main : _ } exposes [] packages {} - imports [Task.{ Task }, InternalTask, Effect.{ Effect }] + imports [Http.{ + Error, + Request, + Header, + header, + Body, + emptyBody, + bytesBody, + stringBody, + jsonBody, + multiPartBody, + stringPart, + bytesPart, + handleStringResponse, + handleEncodedResponse, + }] provides [mainForHost] -mainForHost : Effect (Result {} []) as Fx -mainForHost = InternalTask.toEffect main +mainForHost : Request Str +mainForHost = { + method: "GET", + headers: [{ name: "Expires", value: "0" }], + url: "https://www.google.com", + body: stringBody (MimeType "text") "banana", + responseHandler: handleStringResponse, + timeout: WithoutTimeout, + tracker: WithoutTracker, + allowCookiesFromOtherDomains: False, +} + +# Mistakes I make: +# square brackets for tags body : stringBody [MimeType "text"] "banana", From 0e9d2086a4f748aebc26ed4b509d3973ff8cb1d7 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Thu, 14 Jul 2022 00:01:02 +0100 Subject: [PATCH 06/45] bindgen for Response --- examples/interactive/cli-platform/Http.roc | 2 ++ examples/interactive/cli-platform/main.roc | 25 ++++++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/examples/interactive/cli-platform/Http.roc b/examples/interactive/cli-platform/Http.roc index 2adb36cf4b..0bbf2d5eca 100644 --- a/examples/interactive/cli-platform/Http.roc +++ b/examples/interactive/cli-platform/Http.roc @@ -12,6 +12,8 @@ interface Http multiPartBody, stringPart, bytesPart, + Response, + Metadata, handleStringResponse, handleEncodedResponse, ] diff --git a/examples/interactive/cli-platform/main.roc b/examples/interactive/cli-platform/main.roc index c4cf8938da..2a2a3e32b6 100644 --- a/examples/interactive/cli-platform/main.roc +++ b/examples/interactive/cli-platform/main.roc @@ -15,13 +15,23 @@ platform "cli" multiPartBody, stringPart, bytesPart, + Response, + Metadata, handleStringResponse, handleEncodedResponse, }] provides [mainForHost] -mainForHost : Request Str -mainForHost = { +BindGenTypes : { + req : Request Str, + res : Response (List U8), +} + +mainForHost : BindGenTypes +mainForHost = { req, res } + +req : Request Str +req = { method: "GET", headers: [{ name: "Expires", value: "0" }], url: "https://www.google.com", @@ -32,5 +42,16 @@ mainForHost = { allowCookiesFromOtherDomains: False, } +metadata : Metadata +metadata = { + url: "https://www.google.com/redirect", + statusCode: 200, + statusText: "OK", + headers: [{ name: "All", value: "Good" }], +} + +res : Response (List U8) +res = GoodStatus metadata [0x48, 0x69] + # Mistakes I make: # square brackets for tags body : stringBody [MimeType "text"] "banana", From 2791326a944614b68ecd059cf6199f30d1303659 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Thu, 14 Jul 2022 07:36:19 +0100 Subject: [PATCH 07/45] Tracker should be Str, not F64 --- examples/interactive/cli-platform/Http.roc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/interactive/cli-platform/Http.roc b/examples/interactive/cli-platform/Http.roc index 0bbf2d5eca..ee6e6c9d6c 100644 --- a/examples/interactive/cli-platform/Http.roc +++ b/examples/interactive/cli-platform/Http.roc @@ -20,7 +20,7 @@ interface Http imports [Encode.{ Encoding }, Json] TimeoutConfig : [WithTimeout F64, WithoutTimeout] -TrackerConfig : [WithTracker F64, WithoutTracker] +TrackerConfig : [WithTracker Str, WithoutTracker] Request a : { method : Str, From 664ee1f0dc8b32ff3883370ce70133c3459c44a5 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Thu, 14 Jul 2022 09:31:16 +0100 Subject: [PATCH 08/45] WIP: sending the Request --- examples/interactive/cli-platform/Cargo.lock | 1 + examples/interactive/cli-platform/Cargo.toml | 1 + examples/interactive/cli-platform/src/lib.rs | 88 +++++++++----------- 3 files changed, 42 insertions(+), 48 deletions(-) diff --git a/examples/interactive/cli-platform/Cargo.lock b/examples/interactive/cli-platform/Cargo.lock index f8093a1c63..f2d1c9cc67 100644 --- a/examples/interactive/cli-platform/Cargo.lock +++ b/examples/interactive/cli-platform/Cargo.lock @@ -183,6 +183,7 @@ checksum = "607c8a29735385251a339424dd462993c0fed8fa09d378f259377df08c126022" name = "host" version = "0.1.0" dependencies = [ + "lazy_static", "libc", "reqwest", "roc_std", diff --git a/examples/interactive/cli-platform/Cargo.toml b/examples/interactive/cli-platform/Cargo.toml index 8f5e4ac288..c994e82d9d 100644 --- a/examples/interactive/cli-platform/Cargo.toml +++ b/examples/interactive/cli-platform/Cargo.toml @@ -20,5 +20,6 @@ path = "src/main.rs" roc_std = { path = "../../../crates/roc_std" } libc = "0.2" reqwest = "0.11.11" +lazy_static = "1.4.0" [workspace] diff --git a/examples/interactive/cli-platform/src/lib.rs b/examples/interactive/cli-platform/src/lib.rs index 525a730659..6aac4a0e4d 100644 --- a/examples/interactive/cli-platform/src/lib.rs +++ b/examples/interactive/cli-platform/src/lib.rs @@ -1,11 +1,13 @@ #![allow(non_snake_case)] +mod glue; + use core::alloc::Layout; use core::ffi::c_void; use core::mem::{ManuallyDrop, MaybeUninit}; use libc; -use reqwest::{Client, ClientBuilder, Request}; -use roc_std::{RocResult, RocList, RocStr}; +use reqwest::{Client, Method}; +use roc_std::{RocList, RocResult, RocStr}; use std::ffi::CStr; use std::os::raw::c_char; @@ -133,56 +135,46 @@ std::thread_local! { static HTTP_CLIENT: RefCell> = RefCell::new(None); } -struct RocHeader { - name: RocStr, - value: RocStr, -} - -// This is not the right Rust translation, it's something more complicated... -enum RocBody { - Body(RocStr, RocList), - EmptyBody -} - -#[repr(C)] -struct RocRequest { - method : RocStr, - headers : RocList, - url : RocStr, - body : RocBody, - responseHandler : *const u8, // Response (List U8) -> Result a Error - timeout : RocResult, - tracker : RocResult, - allowCookiesFromOtherDomains : bool, -} - -#[repr(C)] -struct RocMetadata { - url : RocStr, - statusCode : u16, - statusText : RocStr, - headers : RocList, -} - -enum RocResponseOfListU8 { - BadUrl(RocStr), - Timeout, - NetworkError, - BadStatus(RocMetadata, RocList), - GoodStatus(RocMetadata, RocList), -} - #[no_mangle] -pub extern "C" fn roc_fx_send_request(req: RocRequest) { +pub extern "C" fn roc_fx_send_request(roc_request: &glue::Request, /* should I borrow or not? */) { + HTTP_CLIENT.with(|refcell| { + let client = match refcell.take() { + Some(c) => c, + None => { + // Lazily create the client, the first time the Roc program decides to send a request + let builder = Client::builder(); + let c = builder.build().expect("Failed to create HTTP client"); + refcell.replace(Some(c.clone())); // cheap to clone, has internal refcount + c + } + }; - /* + let (mimetype, body_bytes_slice): (String, Vec) = match roc_request.body.discriminant() { + glue::discriminant_Body::EmptyBody => ("".into(), vec![]), + glue::discriminant_Body::Body => { + let (mimetype_union, body_roclist) = unsafe { roc_request.body.as_Body() }; + let mimetype_string: String = unsafe { mimetype_union.as_MimeType() }.as_str().into(); + let body_bytes: &[u8] = body_roclist.as_slice(); + (mimetype_string, Vec::from(body_bytes)) + } + }; - */ + let url = match reqwest::Url::parse(roc_request.url.as_str()) { + Ok(u) => u, + Err(_) => todo!("return a Future that immediately resolves to BadUrl"), + }; - let rust_body_bytes: Vec = vec![]; - let roc_body_bytes = RocList::from_slice(&rust_body_bytes); + let request = client + .request(Method::GET /* TODO */, url) + .body(Vec::from(body_bytes_slice)) + .build(); - let roc_response: RocResponseOfListU8 = todo!(); - // call_the_closure + // let rust_body_bytes: Vec = vec![]; // reqwest something something + // let roc_body_bytes = RocList::from_slice(&rust_body_bytes); + + // let roc_response: glue::Response = todo!(); + + // call_the_closure + }); } From 26ff3ebc0edfac0fe83bd185e61e72c82b24978a Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Thu, 14 Jul 2022 21:07:59 +0100 Subject: [PATCH 09/45] make a sync version of Http --- examples/interactive/cli-platform/Cargo.lock | 707 +++--------------- examples/interactive/cli-platform/Cargo.toml | 3 +- examples/interactive/cli-platform/Effect.roc | 4 +- examples/interactive/cli-platform/Http.roc | 18 +- .../interactive/cli-platform/HttpStatus.roc | 125 ---- examples/interactive/cli-platform/main.roc | 6 +- examples/interactive/cli-platform/src/lib.rs | 102 +-- 7 files changed, 151 insertions(+), 814 deletions(-) delete mode 100644 examples/interactive/cli-platform/HttpStatus.roc diff --git a/examples/interactive/cli-platform/Cargo.lock b/examples/interactive/cli-platform/Cargo.lock index f2d1c9cc67..7b9ea88d05 100644 --- a/examples/interactive/cli-platform/Cargo.lock +++ b/examples/interactive/cli-platform/Cargo.lock @@ -2,42 +2,30 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "arrayvec" version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - [[package]] name = "base64" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "bumpalo" version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" -[[package]] -name = "bytes" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" - [[package]] name = "cc" version = "1.0.73" @@ -51,60 +39,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "core-foundation" -version = "0.9.3" +name = "chunked_transfer" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" -dependencies = [ - "core-foundation-sys", - "libc", -] +checksum = "fff857943da45f546682664a79488be82e69e43c1a7a2307679ab9afb3a66d2e" [[package]] -name = "core-foundation-sys" -version = "0.8.3" +name = "crc32fast" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" - -[[package]] -name = "encoding_rs" -version = "0.8.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if", ] [[package]] -name = "fastrand" -version = "1.7.0" +name = "flate2" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" dependencies = [ - "instant", + "crc32fast", + "miniz_oxide", ] -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.0.1" @@ -115,149 +73,13 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "futures-channel" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" -dependencies = [ - "futures-core", -] - -[[package]] -name = "futures-core" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" - -[[package]] -name = "futures-sink" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" - -[[package]] -name = "futures-task" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" - -[[package]] -name = "futures-util" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" -dependencies = [ - "futures-core", - "futures-task", - "pin-project-lite", - "pin-utils", -] - -[[package]] -name = "h2" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "607c8a29735385251a339424dd462993c0fed8fa09d378f259377df08c126022" - [[package]] name = "host" version = "0.1.0" dependencies = [ - "lazy_static", "libc", - "reqwest", "roc_std", -] - -[[package]] -name = "http" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" - -[[package]] -name = "httpdate" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" - -[[package]] -name = "hyper" -version = "0.14.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "hyper", - "native-tls", - "tokio", - "tokio-native-tls", + "ureq", ] [[package]] @@ -271,37 +93,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "indexmap" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" -dependencies = [ - "autocfg", - "hashbrown", -] - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "ipnet" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" - -[[package]] -name = "itoa" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" - [[package]] name = "js-sys" version = "0.3.58" @@ -339,45 +130,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] -name = "memchr" -version = "2.5.0" +name = "miniz_oxide" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "mime" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" - -[[package]] -name = "mio" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" +checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" dependencies = [ - "libc", - "log", - "wasi", - "windows-sys", -] - -[[package]] -name = "native-tls" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", + "adler", ] [[package]] @@ -386,75 +144,12 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" -[[package]] -name = "openssl" -version = "0.10.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "618febf65336490dfcf20b73f885f5651a0c89c64c2d4a8c3662585a70bf5bd0" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "openssl-sys" -version = "0.9.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5f9bd0c2710541a3cda73d6f9ac4f1b240de4ae261065d309dbe73d9dceb42f" -dependencies = [ - "autocfg", - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" -[[package]] -name = "pin-project-lite" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" - [[package]] name = "proc-macro2" version = "1.0.40" @@ -474,58 +169,18 @@ dependencies = [ ] [[package]] -name = "redox_syscall" -version = "0.2.13" +name = "ring" +version = "0.16.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" dependencies = [ - "bitflags", -] - -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - -[[package]] -name = "reqwest" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75aa69a3f06bbcc66ede33af2af253c6f7a86b1ca0033f60c580a27074fbf92" -dependencies = [ - "base64", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-tls", - "ipnet", - "js-sys", - "lazy_static", - "log", - "mime", - "native-tls", - "percent-encoding", - "pin-project-lite", - "serde", - "serde_json", - "serde_urlencoded", - "tokio", - "tokio-native-tls", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", + "cc", + "libc", + "once_cell", + "spin", + "untrusted", "web-sys", - "winreg", + "winapi", ] [[package]] @@ -537,88 +192,32 @@ dependencies = [ ] [[package]] -name = "ryu" -version = "1.0.10" +name = "rustls" +version = "0.20.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" - -[[package]] -name = "schannel" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" +checksum = "5aab8ee6c7097ed6057f43c187a62418d0c05a4bd5f18b3571db50ee0f9ce033" dependencies = [ - "lazy_static", - "windows-sys", + "log", + "ring", + "sct", + "webpki", ] [[package]] -name = "security-framework" -version = "2.6.1" +name = "sct" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", + "ring", + "untrusted", ] [[package]] -name = "security-framework-sys" -version = "2.6.1" +name = "spin" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "serde" -version = "1.0.139" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0171ebb889e45aa68b44aee0859b3eede84c6f5f5c228e6f140c0b2a0a46cad6" - -[[package]] -name = "serde_json" -version = "1.0.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "slab" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" - -[[package]] -name = "socket2" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" -dependencies = [ - "libc", - "winapi", -] +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "static_assertions" @@ -637,20 +236,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "tempfile" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", -] - [[package]] name = "tinyvec" version = "1.6.0" @@ -666,78 +251,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" -[[package]] -name = "tokio" -version = "1.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439" -dependencies = [ - "bytes", - "libc", - "memchr", - "mio", - "once_cell", - "pin-project-lite", - "socket2", - "winapi", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", - "tracing", -] - -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - -[[package]] -name = "tracing" -version = "0.1.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160" -dependencies = [ - "cfg-if", - "pin-project-lite", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7" -dependencies = [ - "once_cell", -] - -[[package]] -name = "try-lock" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" - [[package]] name = "unicode-bidi" version = "0.3.8" @@ -759,6 +272,29 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "ureq" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97acb4c28a254fd7a4aeec976c46a7fa404eac4d7c134b30c75144846d7cb8f" +dependencies = [ + "base64", + "chunked_transfer", + "flate2", + "log", + "once_cell", + "rustls", + "url", + "webpki", + "webpki-roots", +] + [[package]] name = "url" version = "2.2.2" @@ -771,28 +307,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "want" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" -dependencies = [ - "log", - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - [[package]] name = "wasm-bindgen" version = "0.2.81" @@ -818,18 +332,6 @@ dependencies = [ "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de9a9cec1733468a8c657e57fa2413d2ae2c0129b95e87c5b72b8ace4d13f31f" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "wasm-bindgen-macro" version = "0.2.81" @@ -869,6 +371,25 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1c760f0d366a6c24a02ed7816e23e691f5d92291f94d15e836006fd11b04daf" +dependencies = [ + "webpki", +] + [[package]] name = "winapi" version = "0.3.9" @@ -890,55 +411,3 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" -dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" - -[[package]] -name = "windows_i686_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" - -[[package]] -name = "windows_i686_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" - -[[package]] -name = "winreg" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" -dependencies = [ - "winapi", -] diff --git a/examples/interactive/cli-platform/Cargo.toml b/examples/interactive/cli-platform/Cargo.toml index c994e82d9d..e4100ac485 100644 --- a/examples/interactive/cli-platform/Cargo.toml +++ b/examples/interactive/cli-platform/Cargo.toml @@ -19,7 +19,6 @@ path = "src/main.rs" [dependencies] roc_std = { path = "../../../crates/roc_std" } libc = "0.2" -reqwest = "0.11.11" -lazy_static = "1.4.0" +ureq = "2.5.0" [workspace] diff --git a/examples/interactive/cli-platform/Effect.roc b/examples/interactive/cli-platform/Effect.roc index 76e41873e3..7eb36cae38 100644 --- a/examples/interactive/cli-platform/Effect.roc +++ b/examples/interactive/cli-platform/Effect.roc @@ -1,10 +1,10 @@ hosted Effect exposes [Effect, after, map, always, forever, loop, putLine, getLine, sendRequest] - imports [Http.{ Request }] + imports [Http.{ Request, Reponse }] generates Effect with [after, map, always, forever, loop] putLine : Str -> Effect {} getLine : Effect Str -sendRequest : Request response -> Effect response +sendRequest : Request -> Effect Reponse diff --git a/examples/interactive/cli-platform/Http.roc b/examples/interactive/cli-platform/Http.roc index ee6e6c9d6c..f078c7e7be 100644 --- a/examples/interactive/cli-platform/Http.roc +++ b/examples/interactive/cli-platform/Http.roc @@ -15,19 +15,17 @@ interface Http Response, Metadata, handleStringResponse, - handleEncodedResponse, ] imports [Encode.{ Encoding }, Json] TimeoutConfig : [WithTimeout F64, WithoutTimeout] TrackerConfig : [WithTracker Str, WithoutTracker] -Request a : { +Request : { method : Str, headers : List Header, url : Str, body : Body, - responseHandler : ResponseHandler a, timeout : TimeoutConfig, tracker : TrackerConfig, allowCookiesFromOtherDomains : Bool, @@ -111,19 +109,7 @@ Metadata : { headers : List Header, } -ResponseHandler a : Response (List U8) -> Result a Error - -handleEncodedResponse : (List U8 -> Result a Str) -> ResponseHandler a -handleEncodedResponse = \decoder -> - \response -> - when response is - BadUrl url -> Err (BadUrl url) - Timeout -> Err Timeout - NetworkError -> Err NetworkError - BadStatus metadata _ -> Err (BadStatus metadata.statusCode) - GoodStatus _ bodyBytes -> decoder bodyBytes |> Result.mapErr BadBody - -handleStringResponse : ResponseHandler Str +handleStringResponse : Response (List U8) -> Result Str Error handleStringResponse = \response -> when response is BadUrl url -> Err (BadUrl url) diff --git a/examples/interactive/cli-platform/HttpStatus.roc b/examples/interactive/cli-platform/HttpStatus.roc deleted file mode 100644 index 29cbce7619..0000000000 --- a/examples/interactive/cli-platform/HttpStatus.roc +++ /dev/null @@ -1,125 +0,0 @@ -interface Stdout - exposes [line] - imports [pf.Effect, Task.{ Task }] - -Error : [ - BadUrl Str, - Timeout, - NetworkError, - BadStatus U16, - BadBody Str, -] - -# https://datatracker.ietf.org/doc/html/rfc7231#section-6 -# statusTo -# | 100 | Continue | Section 6.2.1 | -# | 101 | Switching Protocols | Section 6.2.2 | -# | 200 | OK | Section 6.3.1 | -# | 201 | Created | Section 6.3.2 | -# | 202 | Accepted | Section 6.3.3 | -# | 203 | Non-Authoritative Information | Section 6.3.4 | -# | 204 | No Content | Section 6.3.5 | -# | 205 | Reset Content | Section 6.3.6 | -# | 206 | Partial Content | Section 4.1 of [RFC7233] | -# | 300 | Multiple Choices | Section 6.4.1 | -# | 301 | Moved Permanently | Section 6.4.2 | -# | 302 | Found | Section 6.4.3 | -# | 303 | See Other | Section 6.4.4 | -# | 304 | Not Modified | Section 4.1 of [RFC7232] | -# | 305 | Use Proxy | Section 6.4.5 | -# | 307 | Temporary Redirect | Section 6.4.7 | -# | 400 | Bad Request | Section 6.5.1 | -# | 401 | Unauthorized | Section 3.1 of [RFC7235] | -# | 402 | Payment Required | Section 6.5.2 | -# | 403 | Forbidden | Section 6.5.3 | -# | 404 | Not Found | Section 6.5.4 | -# | 405 | Method Not Allowed | Section 6.5.5 | -# | 406 | Not Acceptable | Section 6.5.6 | -# | 407 | Proxy Authentication Required | Section 3.2 of [RFC7235] | -# | 408 | Request Timeout | Section 6.5.7 | -# | 409 | Conflict | Section 6.5.8 | -# | 410 | Gone | Section 6.5.9 | -# | 411 | Length Required | Section 6.5.10 | -# | 412 | Precondition Failed | Section 4.2 of [RFC7232] | -# | 413 | Payload Too Large | Section 6.5.11 | -# | 414 | URI Too Long | Section 6.5.12 | -# | 415 | Unsupported Media Type | Section 6.5.13 | -# | 416 | Range Not Satisfiable | Section 4.4 of [RFC7233] | -# | 417 | Expectation Failed | Section 6.5.14 | -# | 426 | Upgrade Required | Section 6.5.15 | -# | 500 | Internal Server Error | Section 6.6.1 | -# | 501 | Not Implemented | Section 6.6.2 | -# | 502 | Bad Gateway | Section 6.6.3 | -# | 503 | Service Unavailable | Section 6.6.4 | -# | 504 | Gateway Timeout | Section 6.6.5 | -# | 505 | HTTP Version Not Supported | Section 6.6.6 | -StatusCode : [ - Continue, - SwitchingProtocols, - OK, - Created, - Accepted, - NonAuthoritativeInformation, - NoContent, - ResetContent, - PartialContent, - MultipleChoices, - MovedPermanently, - Found, - SeeOther, - NotModified, - UseProxy, - TemporaryRedirect, - BadRequest, - Unauthorized, - PaymentRequired, - Forbidden, - NotFound, - MethodNotAllowed, - NotAcceptable, - ProxyAuthenticationRequired, - RequestTimeout, - Conflict, - Gone, - LengthRequired, - PreconditionFailed, - PayloadTooLarge, - URITooLong, - UnsupportedMediaType, - RangeNotSatisfiable, - ExpectationFailed, - UpgradeRequired, - InternalServerError, - NotImplemented, - BadGateway, - ServiceUnavailable, - GatewayTimeout, - HTTPVersionNotSupported, - CustomStatus U16, -] - -StatusCategory : [ - Informational, - Successful, - Redirection, - ClientError, - ServerError, - UnknownStatusCategory, -] - -statusCategory : U16 -> StatusCategory -statusCategory = \code -> - if code >= 600 then - UnknownStatusCategory - else if code >= 500 then - ServerError - else if code >= 400 then - ClientError - else if code >= 300 then - Redirection - else if code >= 200 then - Successful - else if code >= 100 then - Informational - else - UnknownStatusCategory diff --git a/examples/interactive/cli-platform/main.roc b/examples/interactive/cli-platform/main.roc index 2a2a3e32b6..aa1db15f83 100644 --- a/examples/interactive/cli-platform/main.roc +++ b/examples/interactive/cli-platform/main.roc @@ -18,25 +18,23 @@ platform "cli" Response, Metadata, handleStringResponse, - handleEncodedResponse, }] provides [mainForHost] BindGenTypes : { - req : Request Str, + req : Request, res : Response (List U8), } mainForHost : BindGenTypes mainForHost = { req, res } -req : Request Str +req : Request req = { method: "GET", headers: [{ name: "Expires", value: "0" }], url: "https://www.google.com", body: stringBody (MimeType "text") "banana", - responseHandler: handleStringResponse, timeout: WithoutTimeout, tracker: WithoutTracker, allowCookiesFromOtherDomains: False, diff --git a/examples/interactive/cli-platform/src/lib.rs b/examples/interactive/cli-platform/src/lib.rs index 6aac4a0e4d..96641810fb 100644 --- a/examples/interactive/cli-platform/src/lib.rs +++ b/examples/interactive/cli-platform/src/lib.rs @@ -6,10 +6,10 @@ use core::alloc::Layout; use core::ffi::c_void; use core::mem::{ManuallyDrop, MaybeUninit}; use libc; -use reqwest::{Client, Method}; use roc_std::{RocList, RocResult, RocStr}; use std::ffi::CStr; use std::os::raw::c_char; +use ureq::Error; extern "C" { #[link_name = "roc__mainForHost_1_exposed_generic"] @@ -127,54 +127,64 @@ pub extern "C" fn roc_fx_putLine(line: &RocStr) { println!("{}", string); } -// We just provide just one Client to the Roc program for simplicity, so it must be static in the host. -// `thread_local!` avoids contention between threads, should that ever arise -// `lazy_static` & `Mutex` might have easier-to-understand semantics for resources like cookies -use std::cell::RefCell; -std::thread_local! { - static HTTP_CLIENT: RefCell> = RefCell::new(None); -} - #[no_mangle] pub extern "C" fn roc_fx_send_request(roc_request: &glue::Request, /* should I borrow or not? */) { - HTTP_CLIENT.with(|refcell| { - let client = match refcell.take() { - Some(c) => c, - None => { - // Lazily create the client, the first time the Roc program decides to send a request - let builder = Client::builder(); - let c = builder.build().expect("Failed to create HTTP client"); - refcell.replace(Some(c.clone())); // cheap to clone, has internal refcount - c - } - }; + let (mimetype, body_bytes_slice): (String, Vec) = match roc_request.body.discriminant() { + glue::discriminant_Body::EmptyBody => ("".into(), vec![]), + glue::discriminant_Body::Body => { + let (mimetype_union, body_roclist) = unsafe { roc_request.body.as_Body() }; + let mimetype_string: String = unsafe { mimetype_union.as_MimeType() }.as_str().into(); + let body_bytes: &[u8] = body_roclist.as_slice(); + (mimetype_string, Vec::from(body_bytes)) + } + }; - let (mimetype, body_bytes_slice): (String, Vec) = match roc_request.body.discriminant() { - glue::discriminant_Body::EmptyBody => ("".into(), vec![]), - glue::discriminant_Body::Body => { - let (mimetype_union, body_roclist) = unsafe { roc_request.body.as_Body() }; - let mimetype_string: String = unsafe { mimetype_union.as_MimeType() }.as_str().into(); - let body_bytes: &[u8] = body_roclist.as_slice(); - (mimetype_string, Vec::from(body_bytes)) - } - }; + let url = roc_request.url.as_str(); + match ureq::get(url).call() { + Ok(response) => { + let mut buffer: Vec = vec![]; + let reader = response.into_reader(); + reader.read(&mut buffer); + } + Err(_) => todo!(), + } + // let rust_body_bytes: Vec = vec![]; // reqwest something something + // let roc_body_bytes = RocList::from_slice(&rust_body_bytes); - let url = match reqwest::Url::parse(roc_request.url.as_str()) { - Ok(u) => u, - Err(_) => todo!("return a Future that immediately resolves to BadUrl"), - }; + // let roc_response: glue::Response = todo!(); - let request = client - .request(Method::GET /* TODO */, url) - .body(Vec::from(body_bytes_slice)) - .build(); - - - // let rust_body_bytes: Vec = vec![]; // reqwest something something - // let roc_body_bytes = RocList::from_slice(&rust_body_bytes); - - // let roc_response: glue::Response = todo!(); - - // call_the_closure - }); + // call_the_closure } + + + +/* +pub enum Error { + Status(u16, Response), + Transport(Transport), +} +match ureq::get("http://mypage.example.com/").call() { + Ok(response) => { /* it worked */}, + Err(Error::Status(code, response)) => { + /* the server returned an unexpected status + code (such as 400, 500 etc) */ + } + Err(_) => { /* some kind of io/transport error */ } +} + +enum ErrorKind { + InvalidUrl, + UnknownScheme, + Dns, + InsecureRequestHttpsOnly, + ConnectionFailed, + TooManyRedirects, + BadStatus, + BadHeader, + Io, + InvalidProxyUrl, + ProxyConnect, + ProxyUnauthorized, + HTTP, +} +*/ \ No newline at end of file From 807988aee61d1e25c7b1428e35d87da780ac987c Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Thu, 14 Jul 2022 21:32:10 +0100 Subject: [PATCH 10/45] Very simplistic http effect --- examples/interactive/cli-platform/src/lib.rs | 74 +++++++++++++------- 1 file changed, 50 insertions(+), 24 deletions(-) diff --git a/examples/interactive/cli-platform/src/lib.rs b/examples/interactive/cli-platform/src/lib.rs index 96641810fb..eb163df187 100644 --- a/examples/interactive/cli-platform/src/lib.rs +++ b/examples/interactive/cli-platform/src/lib.rs @@ -4,9 +4,10 @@ mod glue; use core::alloc::Layout; use core::ffi::c_void; -use core::mem::{ManuallyDrop, MaybeUninit}; +use core::mem::MaybeUninit; +use glue::Metadata; use libc; -use roc_std::{RocList, RocResult, RocStr}; +use roc_std::{RocList, RocStr}; use std::ffi::CStr; use std::os::raw::c_char; use ureq::Error; @@ -128,36 +129,61 @@ pub extern "C" fn roc_fx_putLine(line: &RocStr) { } #[no_mangle] -pub extern "C" fn roc_fx_send_request(roc_request: &glue::Request, /* should I borrow or not? */) { - let (mimetype, body_bytes_slice): (String, Vec) = match roc_request.body.discriminant() { - glue::discriminant_Body::EmptyBody => ("".into(), vec![]), - glue::discriminant_Body::Body => { - let (mimetype_union, body_roclist) = unsafe { roc_request.body.as_Body() }; - let mimetype_string: String = unsafe { mimetype_union.as_MimeType() }.as_str().into(); - let body_bytes: &[u8] = body_roclist.as_slice(); - (mimetype_string, Vec::from(body_bytes)) - } - }; +pub extern "C" fn roc_fx_send_request(roc_request: &glue::Request) -> glue::Response { + // let (mimetype, body_bytes_slice): (String, Vec) = match roc_request.body.discriminant() { + // glue::discriminant_Body::EmptyBody => ("".into(), vec![]), + // glue::discriminant_Body::Body => { + // let (mimetype_union, body_roclist) = unsafe { roc_request.body.as_Body() }; + // let mimetype_string: String = unsafe { mimetype_union.as_MimeType() }.as_str().into(); + // let body_bytes: &[u8] = body_roclist.as_slice(); + // (mimetype_string, Vec::from(body_bytes)) + // } + // }; let url = roc_request.url.as_str(); match ureq::get(url).call() { Ok(response) => { + let statusCode = response.status(); + let mut buffer: Vec = vec![]; - let reader = response.into_reader(); - reader.read(&mut buffer); + let mut reader = response.into_reader(); + reader.read(&mut buffer).expect("can't read response"); + let body = RocList::from_slice(&buffer); + + let metadata = Metadata { + headers: RocList::empty(), + statusText: RocStr::empty(), + url: RocStr::empty(), + statusCode, + }; + + glue::Response::GoodStatus(metadata, body) + } + Err(Error::Status(statusCode, response)) => { + let mut buffer: Vec = vec![]; + let mut reader = response.into_reader(); + reader.read(&mut buffer).expect("can't read response"); + let body = RocList::from_slice(&buffer); + + let metadata = Metadata { + headers: RocList::empty(), + statusText: RocStr::empty(), + url: RocStr::empty(), + statusCode, + }; + + glue::Response::BadStatus(metadata, body) + } + Err(transortError) => { + use ureq::ErrorKind::*; + match transortError.kind() { + InvalidUrl | UnknownScheme => glue::Response::BadUrl(RocStr::from(url)), + _ => glue::Response::NetworkError, + } } - Err(_) => todo!(), } - // let rust_body_bytes: Vec = vec![]; // reqwest something something - // let roc_body_bytes = RocList::from_slice(&rust_body_bytes); - - // let roc_response: glue::Response = todo!(); - - // call_the_closure } - - /* pub enum Error { Status(u16, Response), @@ -187,4 +213,4 @@ enum ErrorKind { ProxyUnauthorized, HTTP, } -*/ \ No newline at end of file +*/ From f4019306cdfe6966f9c399373671ae845fac3497 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Thu, 14 Jul 2022 23:18:07 +0100 Subject: [PATCH 11/45] BUG REPRO: roc check hangs forever --- examples/interactive/cli-platform/.gitignore | 2 +- examples/interactive/cli-platform/Http.roc | 37 ++++++++++++-- examples/interactive/cli-platform/main.roc | 54 ++------------------ examples/interactive/fetch.roc | 16 ++++++ 4 files changed, 54 insertions(+), 55 deletions(-) create mode 100644 examples/interactive/fetch.roc diff --git a/examples/interactive/cli-platform/.gitignore b/examples/interactive/cli-platform/.gitignore index b22743bb1e..c79c8b696e 100644 --- a/examples/interactive/cli-platform/.gitignore +++ b/examples/interactive/cli-platform/.gitignore @@ -1 +1 @@ -src/glue.rs +src/glue*.rs diff --git a/examples/interactive/cli-platform/Http.roc b/examples/interactive/cli-platform/Http.roc index f078c7e7be..89dddf6676 100644 --- a/examples/interactive/cli-platform/Http.roc +++ b/examples/interactive/cli-platform/Http.roc @@ -15,6 +15,9 @@ interface Http Response, Metadata, handleStringResponse, + defaultRequest, + errorToString, + send, ] imports [Encode.{ Encoding }, Json] @@ -31,6 +34,17 @@ Request : { allowCookiesFromOtherDomains : Bool, } +defaultRequest : Request +defaultRequest = { + method: "GET", + headers: [], + url: "", + body: Http.emptyBody, + timeout: Http.WithoutTimeout, + tracker: Http.WithoutTracker, + allowCookiesFromOtherDomains: False, +} + Header : { name : Str, value : Str } ## An HTTP header for configuring requests. See a bunch of common headers @@ -94,12 +108,12 @@ Error : [ BadBody Str, ] -Response body : [ +Response : [ BadUrl Str, Timeout, NetworkError, - BadStatus Metadata body, - GoodStatus Metadata body, + BadStatus Metadata (List U8), + GoodStatus Metadata (List U8), ] Metadata : { @@ -109,7 +123,7 @@ Metadata : { headers : List Header, } -handleStringResponse : Response (List U8) -> Result Str Error +handleStringResponse : Response -> Result Str Error handleStringResponse = \response -> when response is BadUrl url -> Err (BadUrl url) @@ -123,3 +137,18 @@ handleStringResponse = \response -> position = Num.toStr pos BadBody "Invalid UTF-8 at byte offset \(position)" + +errorToString : Error -> Str +errorToString = \err -> + when err is + BadUrl url -> "\(url) is not a valid URL" + Timeout -> "Request timed out" + NetworkError -> "Network error" + BadStatus code -> Str.concat "Request failed with status " (Num.toStr code) + BadBody details -> Str.concat "Request failed. Invalid body. " details + +send : Request -> Task Str Error [Network [Http]*]* +send = \req -> + Effect.sendRequest req + |> Effect.map handleStringResponse + |> InternalTask.fromEffect diff --git a/examples/interactive/cli-platform/main.roc b/examples/interactive/cli-platform/main.roc index aa1db15f83..6d3d42a6d5 100644 --- a/examples/interactive/cli-platform/main.roc +++ b/examples/interactive/cli-platform/main.roc @@ -1,55 +1,9 @@ platform "cli" - requires {} { main : _ } + requires {} { main : Task {} [] * } exposes [] packages {} - imports [Http.{ - Error, - Request, - Header, - header, - Body, - emptyBody, - bytesBody, - stringBody, - jsonBody, - multiPartBody, - stringPart, - bytesPart, - Response, - Metadata, - handleStringResponse, - }] + imports [Task.{ Task }, InternalTask, Effect.{ Effect }] provides [mainForHost] -BindGenTypes : { - req : Request, - res : Response (List U8), -} - -mainForHost : BindGenTypes -mainForHost = { req, res } - -req : Request -req = { - method: "GET", - headers: [{ name: "Expires", value: "0" }], - url: "https://www.google.com", - body: stringBody (MimeType "text") "banana", - timeout: WithoutTimeout, - tracker: WithoutTracker, - allowCookiesFromOtherDomains: False, -} - -metadata : Metadata -metadata = { - url: "https://www.google.com/redirect", - statusCode: 200, - statusText: "OK", - headers: [{ name: "All", value: "Good" }], -} - -res : Response (List U8) -res = GoodStatus metadata [0x48, 0x69] - -# Mistakes I make: -# square brackets for tags body : stringBody [MimeType "text"] "banana", +mainForHost : Effect (Result {} []) as Fx +mainForHost = InternalTask.toEffect main diff --git a/examples/interactive/fetch.roc b/examples/interactive/fetch.roc new file mode 100644 index 0000000000..c2165e37d8 --- /dev/null +++ b/examples/interactive/fetch.roc @@ -0,0 +1,16 @@ +app "network" + packages { pf: "cli-platform/main.roc" } + imports [pf.Http, pf.Task] + provides [main] to pf + +main : Task.Task {} [] [Write [Stdout], Network [Http]] +main = + request : Request + request = { defaultRequest & url: "https://httpbin.org/get" } + + result <- Http.send request |> Task.await + output = + when result is + Ok payload -> payload + Err httpError -> Http.errorToString httpError + Stdout.line output From 63a2e663647b05085f1d1a8464dcb020f05078b0 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Thu, 14 Jul 2022 23:31:14 +0100 Subject: [PATCH 12/45] BUG REPRO roc check hangs forever on Http.roc --- examples/interactive/cli-platform/Effect.roc | 4 +- examples/interactive/cli-platform/Http.roc | 65 +++---------------- .../interactive/cli-platform/HttpTypes.roc | 48 ++++++++++++++ examples/interactive/fetch.roc | 15 +++-- 4 files changed, 68 insertions(+), 64 deletions(-) create mode 100644 examples/interactive/cli-platform/HttpTypes.roc diff --git a/examples/interactive/cli-platform/Effect.roc b/examples/interactive/cli-platform/Effect.roc index 7eb36cae38..8a3e89e675 100644 --- a/examples/interactive/cli-platform/Effect.roc +++ b/examples/interactive/cli-platform/Effect.roc @@ -1,10 +1,10 @@ hosted Effect exposes [Effect, after, map, always, forever, loop, putLine, getLine, sendRequest] - imports [Http.{ Request, Reponse }] + imports [Http.{ Request, Response }] generates Effect with [after, map, always, forever, loop] putLine : Str -> Effect {} getLine : Effect Str -sendRequest : Request -> Effect Reponse +sendRequest : Request -> Effect Response diff --git a/examples/interactive/cli-platform/Http.roc b/examples/interactive/cli-platform/Http.roc index 89dddf6676..aacc579d98 100644 --- a/examples/interactive/cli-platform/Http.roc +++ b/examples/interactive/cli-platform/Http.roc @@ -1,10 +1,6 @@ interface Http exposes [ - Error, - Request, - Header, header, - Body, emptyBody, bytesBody, stringBody, @@ -12,27 +8,18 @@ interface Http multiPartBody, stringPart, bytesPart, - Response, - Metadata, handleStringResponse, defaultRequest, errorToString, send, ] - imports [Encode.{ Encoding }, Json] - -TimeoutConfig : [WithTimeout F64, WithoutTimeout] -TrackerConfig : [WithTracker Str, WithoutTracker] - -Request : { - method : Str, - headers : List Header, - url : Str, - body : Body, - timeout : TimeoutConfig, - tracker : TrackerConfig, - allowCookiesFromOtherDomains : Bool, -} + imports [ + pf.Effect, + InternalTask, + Task, + Encode.{ Encoding }, + HttpTypes.{ Request, Header, TimeoutConfig, TrackerConfig, Part, Body, Response, Metadata, Error }, + ] defaultRequest : Request defaultRequest = { @@ -40,13 +27,11 @@ defaultRequest = { headers: [], url: "", body: Http.emptyBody, - timeout: Http.WithoutTimeout, - tracker: Http.WithoutTracker, + timeout: NoTimeout, + tracker: NoTracker, allowCookiesFromOtherDomains: False, } -Header : { name : Str, value : Str } - ## An HTTP header for configuring requests. See a bunch of common headers ## [here](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields). ## @@ -54,11 +39,6 @@ header : Str, Str -> Header header = \name, value -> { name, value } -Body : [ - Body [MimeType Str] (List U8), - EmptyBody, -] - emptyBody : Body emptyBody = EmptyBody @@ -90,8 +70,6 @@ multiPartBody = \parts -> Body (MimeType "multipart/form-data;boundary=\"\(boundary)\"") bodyBytes -Part : [Part Str (List U8)] - bytesPart : Str, List U8 -> Part bytesPart = Part @@ -100,29 +78,6 @@ stringPart : Str, Str -> Part stringPart = \name, str -> Part name (Str.toUtf8 str) -Error : [ - BadUrl Str, - Timeout, - NetworkError, - BadStatus U16, - BadBody Str, -] - -Response : [ - BadUrl Str, - Timeout, - NetworkError, - BadStatus Metadata (List U8), - GoodStatus Metadata (List U8), -] - -Metadata : { - url : Str, - statusCode : U16, - statusText : Str, - headers : List Header, -} - handleStringResponse : Response -> Result Str Error handleStringResponse = \response -> when response is @@ -145,7 +100,7 @@ errorToString = \err -> Timeout -> "Request timed out" NetworkError -> "Network error" BadStatus code -> Str.concat "Request failed with status " (Num.toStr code) - BadBody details -> Str.concat "Request failed. Invalid body. " details + BadBody details -> Str.concat "Request failed. Invalid body. " details send : Request -> Task Str Error [Network [Http]*]* send = \req -> diff --git a/examples/interactive/cli-platform/HttpTypes.roc b/examples/interactive/cli-platform/HttpTypes.roc new file mode 100644 index 0000000000..dee449d263 --- /dev/null +++ b/examples/interactive/cli-platform/HttpTypes.roc @@ -0,0 +1,48 @@ +interface HttpTypes + exposes [Request, Header, TimeoutConfig, TrackerConfig, Part, Body, Response, Metadata, Error] + imports [] + +Request : { + method : Str, + headers : List Header, + url : Str, + body : Body, + timeout : TimeoutConfig, + tracker : TrackerConfig, + allowCookiesFromOtherDomains : Bool, +} + +Header : { name : Str, value : Str } + +TimeoutConfig : [Timeout F64, NoTimeout] +TrackerConfig : [Tracker Str, NoTracker] + +Part : [Part Str (List U8)] + +Body : [ + Body [MimeType Str] (List U8), + EmptyBody, +] + +Response : [ + BadUrl Str, + Timeout, + NetworkError, + BadStatus Metadata (List U8), + GoodStatus Metadata (List U8), +] + +Metadata : { + url : Str, + statusCode : U16, + statusText : Str, + headers : List Header, +} + +Error : [ + BadUrl Str, + Timeout, + NetworkError, + BadStatus U16, + BadBody Str, +] diff --git a/examples/interactive/fetch.roc b/examples/interactive/fetch.roc index c2165e37d8..df0d9f9a2a 100644 --- a/examples/interactive/fetch.roc +++ b/examples/interactive/fetch.roc @@ -5,12 +5,13 @@ app "network" main : Task.Task {} [] [Write [Stdout], Network [Http]] main = - request : Request - request = { defaultRequest & url: "https://httpbin.org/get" } + # request : Request + # request = { defaultRequest & url: "https://httpbin.org/get" } - result <- Http.send request |> Task.await - output = - when result is - Ok payload -> payload - Err httpError -> Http.errorToString httpError + # result <- Http.send request |> Task.await + # output = + # when result is + # Ok payload -> payload + # Err httpError -> Http.errorToString httpError + output = "Hello" Stdout.line output From 13f5f27c9b2911c2128530a7a16df99b42cb7d7a Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 14 Jul 2022 20:19:30 -0400 Subject: [PATCH 13/45] Remove 'pf' in pf.Effect in platform import --- examples/interactive/cli-platform/Http.roc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/interactive/cli-platform/Http.roc b/examples/interactive/cli-platform/Http.roc index aacc579d98..1211521185 100644 --- a/examples/interactive/cli-platform/Http.roc +++ b/examples/interactive/cli-platform/Http.roc @@ -14,7 +14,7 @@ interface Http send, ] imports [ - pf.Effect, + Effect, InternalTask, Task, Encode.{ Encoding }, From 1ee5d79fcf0b2d8228262942b8015908a4a1d2fd Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 14 Jul 2022 20:19:39 -0400 Subject: [PATCH 14/45] Fix an import in Effect.roc --- examples/interactive/cli-platform/Effect.roc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/interactive/cli-platform/Effect.roc b/examples/interactive/cli-platform/Effect.roc index 8a3e89e675..e29fd147a3 100644 --- a/examples/interactive/cli-platform/Effect.roc +++ b/examples/interactive/cli-platform/Effect.roc @@ -1,6 +1,6 @@ hosted Effect exposes [Effect, after, map, always, forever, loop, putLine, getLine, sendRequest] - imports [Http.{ Request, Response }] + imports [HttpTypes.{ Request, Response }] generates Effect with [after, map, always, forever, loop] putLine : Str -> Effect {} From e77b2bf8b120cb533c8114fc73500f1cff41d502 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 14 Jul 2022 20:20:34 -0400 Subject: [PATCH 15/45] Reproduce confusing error message To reproduce: `cargo run -- check examples/interactive/cli-platform/main.roc` --- examples/interactive/cli-platform/Effect.roc | 2 +- examples/interactive/cli-platform/Http.roc | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/examples/interactive/cli-platform/Effect.roc b/examples/interactive/cli-platform/Effect.roc index e29fd147a3..8a3e89e675 100644 --- a/examples/interactive/cli-platform/Effect.roc +++ b/examples/interactive/cli-platform/Effect.roc @@ -1,6 +1,6 @@ hosted Effect exposes [Effect, after, map, always, forever, loop, putLine, getLine, sendRequest] - imports [HttpTypes.{ Request, Response }] + imports [Http.{ Request, Response }] generates Effect with [after, map, always, forever, loop] putLine : Str -> Effect {} diff --git a/examples/interactive/cli-platform/Http.roc b/examples/interactive/cli-platform/Http.roc index 1211521185..5c5d615b19 100644 --- a/examples/interactive/cli-platform/Http.roc +++ b/examples/interactive/cli-platform/Http.roc @@ -14,9 +14,6 @@ interface Http send, ] imports [ - Effect, - InternalTask, - Task, Encode.{ Encoding }, HttpTypes.{ Request, Header, TimeoutConfig, TrackerConfig, Part, Body, Response, Metadata, Error }, ] From 18cf29f6e95bb86d8e04de39718048e26244634d Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 14 Jul 2022 20:21:18 -0400 Subject: [PATCH 16/45] Revert "Reproduce confusing error message" This reverts commit 6c62f72489de68f92493eeda9584c3879dedbd84. --- examples/interactive/cli-platform/Effect.roc | 2 +- examples/interactive/cli-platform/Http.roc | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/interactive/cli-platform/Effect.roc b/examples/interactive/cli-platform/Effect.roc index 8a3e89e675..e29fd147a3 100644 --- a/examples/interactive/cli-platform/Effect.roc +++ b/examples/interactive/cli-platform/Effect.roc @@ -1,6 +1,6 @@ hosted Effect exposes [Effect, after, map, always, forever, loop, putLine, getLine, sendRequest] - imports [Http.{ Request, Response }] + imports [HttpTypes.{ Request, Response }] generates Effect with [after, map, always, forever, loop] putLine : Str -> Effect {} diff --git a/examples/interactive/cli-platform/Http.roc b/examples/interactive/cli-platform/Http.roc index 5c5d615b19..1211521185 100644 --- a/examples/interactive/cli-platform/Http.roc +++ b/examples/interactive/cli-platform/Http.roc @@ -14,6 +14,9 @@ interface Http send, ] imports [ + Effect, + InternalTask, + Task, Encode.{ Encoding }, HttpTypes.{ Request, Header, TimeoutConfig, TrackerConfig, Part, Body, Response, Metadata, Error }, ] From 5fe5a8e8d5ca2b86ef6a1316d656fe5e79549b39 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Fri, 15 Jul 2022 08:15:17 +0100 Subject: [PATCH 17/45] BUG REPRO: bad error message for missing Json import --- examples/interactive/cli-platform/Http.roc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/interactive/cli-platform/Http.roc b/examples/interactive/cli-platform/Http.roc index 1211521185..13364f712c 100644 --- a/examples/interactive/cli-platform/Http.roc +++ b/examples/interactive/cli-platform/Http.roc @@ -16,7 +16,7 @@ interface Http imports [ Effect, InternalTask, - Task, + Task.{ Task }, Encode.{ Encoding }, HttpTypes.{ Request, Header, TimeoutConfig, TrackerConfig, Part, Body, Response, Metadata, Error }, ] From 1c9becc252a2e9871f0f330a8497adb2367ed198 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Fri, 15 Jul 2022 08:48:48 +0100 Subject: [PATCH 18/45] Fix missing import --- examples/interactive/cli-platform/Http.roc | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/interactive/cli-platform/Http.roc b/examples/interactive/cli-platform/Http.roc index 13364f712c..eaa7eb6691 100644 --- a/examples/interactive/cli-platform/Http.roc +++ b/examples/interactive/cli-platform/Http.roc @@ -16,6 +16,7 @@ interface Http imports [ Effect, InternalTask, + Json, Task.{ Task }, Encode.{ Encoding }, HttpTypes.{ Request, Header, TimeoutConfig, TrackerConfig, Part, Body, Response, Metadata, Error }, From c1bc30cf900cfaaac6ea2b13e3db0873603c3d40 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sat, 16 Jul 2022 08:09:12 +0100 Subject: [PATCH 19/45] Undo last remnants of bindgen hacking --- crates/bindgen/src/types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bindgen/src/types.rs b/crates/bindgen/src/types.rs index b2ddccc77b..4bfd853b13 100644 --- a/crates/bindgen/src/types.rs +++ b/crates/bindgen/src/types.rs @@ -10,7 +10,7 @@ use roc_collections::VecMap; use roc_module::symbol::{Interns, Symbol}; use roc_mono::layout::{ cmp_fields, ext_var_is_empty_tag_union, round_up_to_alignment, Builtin, Layout, LayoutCache, - UnionLayout, FieldOrderHash, + UnionLayout, }; use roc_target::TargetInfo; use roc_types::{ From 0e13c875c4eaa9760fd27fffd7acadf5c426f726 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sat, 16 Jul 2022 08:41:03 +0100 Subject: [PATCH 20/45] rename http example app --- examples/interactive/{fetch.roc => http-get.roc} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename examples/interactive/{fetch.roc => http-get.roc} (97%) diff --git a/examples/interactive/fetch.roc b/examples/interactive/http-get.roc similarity index 97% rename from examples/interactive/fetch.roc rename to examples/interactive/http-get.roc index df0d9f9a2a..63de7c39ae 100644 --- a/examples/interactive/fetch.roc +++ b/examples/interactive/http-get.roc @@ -1,4 +1,4 @@ -app "network" +app "http-get" packages { pf: "cli-platform/main.roc" } imports [pf.Http, pf.Task] provides [main] to pf From 4be19ed32016465ac4641016faff24c87c56b4be Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sat, 16 Jul 2022 08:54:28 +0100 Subject: [PATCH 21/45] Import Stdout --- examples/interactive/http-get.roc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/interactive/http-get.roc b/examples/interactive/http-get.roc index 63de7c39ae..c2ee4b9dbb 100644 --- a/examples/interactive/http-get.roc +++ b/examples/interactive/http-get.roc @@ -1,6 +1,6 @@ app "http-get" packages { pf: "cli-platform/main.roc" } - imports [pf.Http, pf.Task] + imports [pf.Http, pf.Task, pf.Stdout] provides [main] to pf main : Task.Task {} [] [Write [Stdout], Network [Http]] From bee6f2f833a792e65373a1efa4efb05cb3b568ed Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sat, 16 Jul 2022 11:51:46 +0100 Subject: [PATCH 22/45] Http example passes `roc check` --- examples/interactive/cli-platform/Http.roc | 12 ++++++------ examples/interactive/http-get.roc | 16 +++++++--------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/examples/interactive/cli-platform/Http.roc b/examples/interactive/cli-platform/Http.roc index eaa7eb6691..fe4933c311 100644 --- a/examples/interactive/cli-platform/Http.roc +++ b/examples/interactive/cli-platform/Http.roc @@ -4,7 +4,7 @@ interface Http emptyBody, bytesBody, stringBody, - jsonBody, + # jsonBody, multiPartBody, stringPart, bytesPart, @@ -16,9 +16,9 @@ interface Http imports [ Effect, InternalTask, - Json, + # Json, Task.{ Task }, - Encode.{ Encoding }, + # Encode.{ Encoding }, HttpTypes.{ Request, Header, TimeoutConfig, TrackerConfig, Part, Body, Response, Metadata, Error }, ] @@ -52,9 +52,9 @@ stringBody : [MimeType Str], Str -> Body stringBody = \mimeType, str -> Body mimeType (Str.toUtf8 str) -jsonBody : a -> Body | a has Encoding -jsonBody = \val -> - Body (MimeType "application/json") (Encode.toBytes val Json.format) +# jsonBody : a -> Body | a has Encoding +# jsonBody = \val -> +# Body (MimeType "application/json") (Encode.toBytes val Json.format) multiPartBody : List Part -> Body multiPartBody = \parts -> diff --git a/examples/interactive/http-get.roc b/examples/interactive/http-get.roc index c2ee4b9dbb..dd21f2806e 100644 --- a/examples/interactive/http-get.roc +++ b/examples/interactive/http-get.roc @@ -1,17 +1,15 @@ app "http-get" packages { pf: "cli-platform/main.roc" } - imports [pf.Http, pf.Task, pf.Stdout] + imports [pf.Http, pf.HttpTypes, pf.Task, pf.Stdout] provides [main] to pf main : Task.Task {} [] [Write [Stdout], Network [Http]] main = - # request : Request - # request = { defaultRequest & url: "https://httpbin.org/get" } + request : HttpTypes.Request + request = { Http.defaultRequest & url: "https://httpbin.org/get" } + + output <- Http.send request + |> Task.onFail (\err -> err |> Http.errorToString |> Task.succeed) + |> Task.await - # result <- Http.send request |> Task.await - # output = - # when result is - # Ok payload -> payload - # Err httpError -> Http.errorToString httpError - output = "Hello" Stdout.line output From 85bd8c54f206b17fb2cf2d6a5cd7fc2463aa6b64 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sat, 16 Jul 2022 12:16:53 +0100 Subject: [PATCH 23/45] Tidy up Http example --- examples/interactive/cli-platform/Http.roc | 1 - examples/interactive/http-get.roc | 12 ++++-------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/examples/interactive/cli-platform/Http.roc b/examples/interactive/cli-platform/Http.roc index fe4933c311..d7d09e2ba0 100644 --- a/examples/interactive/cli-platform/Http.roc +++ b/examples/interactive/cli-platform/Http.roc @@ -55,7 +55,6 @@ stringBody = \mimeType, str -> # jsonBody : a -> Body | a has Encoding # jsonBody = \val -> # Body (MimeType "application/json") (Encode.toBytes val Json.format) - multiPartBody : List Part -> Body multiPartBody = \parts -> boundary = "7MA4YWxkTrZu0gW" # TODO: what's this exactly? a hash of all the part bodies? diff --git a/examples/interactive/http-get.roc b/examples/interactive/http-get.roc index dd21f2806e..22444c14dd 100644 --- a/examples/interactive/http-get.roc +++ b/examples/interactive/http-get.roc @@ -5,11 +5,7 @@ app "http-get" main : Task.Task {} [] [Write [Stdout], Network [Http]] main = - request : HttpTypes.Request - request = { Http.defaultRequest & url: "https://httpbin.org/get" } - - output <- Http.send request - |> Task.onFail (\err -> err |> Http.errorToString |> Task.succeed) - |> Task.await - - Stdout.line output + Http.send { Http.defaultRequest & url: "https://httpbin.org/get" } + |> Task.onFail (\err -> err |> Http.errorToString |> Task.succeed) + |> Task.await + |> Stdout.line From a0ac1ff98150320e895b9126561a83d870bf83e6 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sat, 16 Jul 2022 22:30:39 +0100 Subject: [PATCH 24/45] For now, commit bindgen generated code so we can record edits needed --- examples/interactive/cli-platform/.gitignore | 1 - examples/interactive/cli-platform/src/glue.rs | 4696 +++++++++++++++++ 2 files changed, 4696 insertions(+), 1 deletion(-) delete mode 100644 examples/interactive/cli-platform/.gitignore create mode 100644 examples/interactive/cli-platform/src/glue.rs diff --git a/examples/interactive/cli-platform/.gitignore b/examples/interactive/cli-platform/.gitignore deleted file mode 100644 index c79c8b696e..0000000000 --- a/examples/interactive/cli-platform/.gitignore +++ /dev/null @@ -1 +0,0 @@ -src/glue*.rs diff --git a/examples/interactive/cli-platform/src/glue.rs b/examples/interactive/cli-platform/src/glue.rs new file mode 100644 index 0000000000..3d76796a62 --- /dev/null +++ b/examples/interactive/cli-platform/src/glue.rs @@ -0,0 +1,4696 @@ +// ⚠️ GENERATED CODE ⚠️ - this entire file was generated by the `roc-bindgen` CLI + +#![allow(dead_code)] +#![allow(unused_mut)] +#![allow(non_snake_case)] +#![allow(non_camel_case_types)] +#![allow(non_upper_case_globals)] +#![allow(clippy::undocumented_unsafe_blocks)] + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[derive(Clone, Copy, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[repr(u8)] +pub enum discriminant_Error { + BadBody = 0, + BadStatus = 1, + BadUrl = 2, + NetworkError = 3, + Timeout = 4, +} + +impl core::fmt::Debug for discriminant_Error { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::BadBody => f.write_str("discriminant_Error::BadBody"), + Self::BadStatus => f.write_str("discriminant_Error::BadStatus"), + Self::BadUrl => f.write_str("discriminant_Error::BadUrl"), + Self::NetworkError => f.write_str("discriminant_Error::NetworkError"), + Self::Timeout => f.write_str("discriminant_Error::Timeout"), + } + } +} + +#[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] +#[repr(C)] +pub union Error { + BadBody: core::mem::ManuallyDrop, + BadStatus: u16, + BadUrl: core::mem::ManuallyDrop, + _sizer: [u8; 16], +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[derive(Clone, Copy, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[repr(u8)] +pub enum discriminant_Part { + Part = 0, +} + +impl core::fmt::Debug for discriminant_Part { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::Part => f.write_str("discriminant_Part::Part"), + } + } +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[repr(C)] +pub union Part { + Part: core::mem::ManuallyDrop, +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[derive(Clone, Debug, Default, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[repr(C)] +pub struct Header { + pub name: roc_std::RocStr, + pub value: roc_std::RocStr, +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[derive(Clone, Copy, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[repr(u8)] +pub enum discriminant_U5 { + MimeType = 0, +} + +impl core::fmt::Debug for discriminant_U5 { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::MimeType => f.write_str("discriminant_U5::MimeType"), + } + } +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[repr(C)] +pub union U5 { + MimeType: core::mem::ManuallyDrop, +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[derive(Clone, Copy, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[repr(u8)] +pub enum discriminant_Body { + Body = 0, + EmptyBody = 1, +} + +impl core::fmt::Debug for discriminant_Body { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::Body => f.write_str("discriminant_Body::Body"), + Self::EmptyBody => f.write_str("discriminant_Body::EmptyBody"), + } + } +} + +#[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] +#[repr(C)] +pub union Body { + Body: core::mem::ManuallyDrop, + _sizer: [u8; 28], +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[derive(Clone, Copy, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[repr(u8)] +pub enum discriminant_U3 { + MimeType = 0, +} + +impl core::fmt::Debug for discriminant_U3 { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::MimeType => f.write_str("discriminant_U3::MimeType"), + } + } +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[repr(C)] +pub union U3 { + MimeType: core::mem::ManuallyDrop, +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[derive(Clone, Copy, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[repr(u8)] +pub enum discriminant_Response { + BadStatus = 0, + BadUrl = 1, + GoodStatus = 2, + NetworkError = 3, + Timeout = 4, +} + +impl core::fmt::Debug for discriminant_Response { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::BadStatus => f.write_str("discriminant_Response::BadStatus"), + Self::BadUrl => f.write_str("discriminant_Response::BadUrl"), + Self::GoodStatus => f.write_str("discriminant_Response::GoodStatus"), + Self::NetworkError => f.write_str("discriminant_Response::NetworkError"), + Self::Timeout => f.write_str("discriminant_Response::Timeout"), + } + } +} + +#[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] +#[repr(C)] +pub union Response { + BadStatus: core::mem::ManuallyDrop, + BadUrl: core::mem::ManuallyDrop, + GoodStatus: core::mem::ManuallyDrop, + _sizer: [u8; 56], +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "x86", + target_arch = "x86_64" +))] +#[derive(Clone, Debug, PartialEq, PartialOrd)] +#[repr(C)] +pub struct Request { + pub body: Body, + pub headers: roc_std::RocList
, + pub method: roc_std::RocStr, + pub timeout: TimeoutConfig, + pub tracker: TrackerConfig, + pub url: roc_std::RocStr, + pub allowCookiesFromOtherDomains: bool, +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[derive(Clone, Copy, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[repr(u8)] +pub enum discriminant_U8 { + MimeType = 0, +} + +impl core::fmt::Debug for discriminant_U8 { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::MimeType => f.write_str("discriminant_U8::MimeType"), + } + } +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[repr(C)] +pub union U8 { + MimeType: core::mem::ManuallyDrop, +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[derive(Clone, Copy, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[repr(u8)] +pub enum discriminant_U7 { + MimeType = 0, +} + +impl core::fmt::Debug for discriminant_U7 { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::MimeType => f.write_str("discriminant_U7::MimeType"), + } + } +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[repr(C)] +pub union U7 { + MimeType: core::mem::ManuallyDrop, +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[derive(Clone, Copy, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[repr(u8)] +pub enum discriminant_U6 { + MimeType = 0, +} + +impl core::fmt::Debug for discriminant_U6 { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::MimeType => f.write_str("discriminant_U6::MimeType"), + } + } +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[repr(C)] +pub union U6 { + MimeType: core::mem::ManuallyDrop, +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[derive(Clone, Copy, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[repr(u8)] +pub enum discriminant_U4 { + MimeType = 0, +} + +impl core::fmt::Debug for discriminant_U4 { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::MimeType => f.write_str("discriminant_U4::MimeType"), + } + } +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[repr(C)] +pub union U4 { + MimeType: core::mem::ManuallyDrop, +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[derive(Clone, Copy, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[repr(u8)] +pub enum discriminant_U2 { + MimeType = 0, +} + +impl core::fmt::Debug for discriminant_U2 { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::MimeType => f.write_str("discriminant_U2::MimeType"), + } + } +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[repr(C)] +pub union U2 { + MimeType: core::mem::ManuallyDrop, +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[derive(Clone, Debug, Default, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[repr(C)] +struct Part_Part { + pub f0: roc_std::RocStr, + pub f1: roc_std::RocList, +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[derive(Clone, Debug, Default, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[repr(C)] +struct Response_GoodStatus { + pub f0: Metadata, + pub f1: roc_std::RocList, +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[derive(Clone, Debug, Default, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[repr(C)] +struct Response_BadStatus { + pub f0: Metadata, + pub f1: roc_std::RocList, +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[derive(Clone, Debug, Default, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[repr(C)] +pub struct Metadata { + pub headers: roc_std::RocList
, + pub statusText: roc_std::RocStr, + pub url: roc_std::RocStr, + pub statusCode: u16, +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[derive(Clone, Copy, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[repr(u8)] +pub enum discriminant_TrackerConfig { + NoTracker = 0, + Tracker = 1, +} + +impl core::fmt::Debug for discriminant_TrackerConfig { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::NoTracker => f.write_str("discriminant_TrackerConfig::NoTracker"), + Self::Tracker => f.write_str("discriminant_TrackerConfig::Tracker"), + } + } +} + +#[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] +#[repr(C)] +pub union TrackerConfig { + Tracker: core::mem::ManuallyDrop, + _sizer: [u8; 16], +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[derive(Clone, Copy, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[repr(u8)] +pub enum discriminant_TimeoutConfig { + NoTimeout = 0, + Timeout = 1, +} + +impl core::fmt::Debug for discriminant_TimeoutConfig { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::NoTimeout => f.write_str("discriminant_TimeoutConfig::NoTimeout"), + Self::Timeout => f.write_str("discriminant_TimeoutConfig::Timeout"), + } + } +} + +#[cfg(any(target_arch = "arm", target_arch = "x86"))] +#[repr(C)] +pub union TimeoutConfig { + Timeout: f64, + _sizer: [u8; 12], +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[derive(Clone, Debug, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[repr(C)] +struct Body_Body { + pub f0: U1, + pub f1: roc_std::RocList, +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[derive(Clone, Copy, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[repr(u8)] +pub enum discriminant_U1 { + MimeType = 0, +} + +impl core::fmt::Debug for discriminant_U1 { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::MimeType => f.write_str("discriminant_U1::MimeType"), + } + } +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[repr(C)] +pub union U1 { + MimeType: core::mem::ManuallyDrop, +} + +#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] +#[repr(C)] +pub union Error { + BadBody: core::mem::ManuallyDrop, + BadStatus: u16, + BadUrl: core::mem::ManuallyDrop, + _sizer: [u8; 32], +} + +#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] +#[repr(C)] +pub union Body { + Body: core::mem::ManuallyDrop, + _sizer: [u8; 56], +} + +#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] +#[repr(C)] +pub union Response { + BadStatus: core::mem::ManuallyDrop, + BadUrl: core::mem::ManuallyDrop, + GoodStatus: core::mem::ManuallyDrop, + _sizer: [u8; 112], +} + +#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] +#[repr(C)] +pub union TrackerConfig { + Tracker: core::mem::ManuallyDrop, + _sizer: [u8; 32], +} + +#[cfg(any( + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86_64" +))] +#[repr(C)] +pub union TimeoutConfig { + Timeout: f64, + _sizer: [u8; 16], +} + +#[cfg(target_arch = "wasm32")] +#[derive(Clone, Debug, PartialEq, PartialOrd)] +#[repr(C)] +pub struct Request { + pub timeout: TimeoutConfig, + pub body: Body, + pub headers: roc_std::RocList
, + pub method: roc_std::RocStr, + pub tracker: TrackerConfig, + pub url: roc_std::RocStr, + pub allowCookiesFromOtherDomains: bool, +} + +impl Error { + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_Error { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(12)) + } + } + + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_Error) { + let discriminant_ptr: *mut discriminant_Error = (self as *mut Error).cast(); + + unsafe { + *(discriminant_ptr.add(12)) = discriminant; + } + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Construct a tag named `BadBody`, with the appropriate payload + pub fn BadBody(arg: roc_std::RocStr) -> Self { + let mut answer = Self { + BadBody: core::mem::ManuallyDrop::new(arg), + }; + + answer.set_discriminant(discriminant_Error::BadBody); + + answer + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `Error` has a `.discriminant()` of `BadBody` and convert it to `BadBody`'s payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `BadBody`. + pub unsafe fn into_BadBody(mut self) -> roc_std::RocStr { + debug_assert_eq!(self.discriminant(), discriminant_Error::BadBody); + + let payload = core::mem::ManuallyDrop::take(&mut self.BadBody); + + payload + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `Error` has a `.discriminant()` of `BadBody` and return its payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `BadBody`. + pub unsafe fn as_BadBody(&self) -> &roc_std::RocStr { + debug_assert_eq!(self.discriminant(), discriminant_Error::BadBody); + + let payload = &self.BadBody; + + &payload + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Construct a tag named `BadStatus`, with the appropriate payload + pub fn BadStatus(arg: u16) -> Self { + let mut answer = Self { BadStatus: arg }; + + answer.set_discriminant(discriminant_Error::BadStatus); + + answer + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `Error` has a `.discriminant()` of `BadStatus` and convert it to `BadStatus`'s payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `BadStatus`. + pub unsafe fn into_BadStatus(self) -> u16 { + debug_assert_eq!(self.discriminant(), discriminant_Error::BadStatus); + + let payload = self.BadStatus; + + payload + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `Error` has a `.discriminant()` of `BadStatus` and return its payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `BadStatus`. + pub unsafe fn as_BadStatus(&self) -> &u16 { + debug_assert_eq!(self.discriminant(), discriminant_Error::BadStatus); + + let payload = &self.BadStatus; + + &payload + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Construct a tag named `BadUrl`, with the appropriate payload + pub fn BadUrl(arg: roc_std::RocStr) -> Self { + let mut answer = Self { + BadUrl: core::mem::ManuallyDrop::new(arg), + }; + + answer.set_discriminant(discriminant_Error::BadUrl); + + answer + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `Error` has a `.discriminant()` of `BadUrl` and convert it to `BadUrl`'s payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `BadUrl`. + pub unsafe fn into_BadUrl(mut self) -> roc_std::RocStr { + debug_assert_eq!(self.discriminant(), discriminant_Error::BadUrl); + + let payload = core::mem::ManuallyDrop::take(&mut self.BadUrl); + + payload + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `Error` has a `.discriminant()` of `BadUrl` and return its payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `BadUrl`. + pub unsafe fn as_BadUrl(&self) -> &roc_std::RocStr { + debug_assert_eq!(self.discriminant(), discriminant_Error::BadUrl); + + let payload = &self.BadUrl; + + &payload + } + + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// A tag named NetworkError, which has no payload. + pub const NetworkError: Self = unsafe { + let mut bytes = [0; core::mem::size_of::()]; + + bytes[12] = discriminant_Error::NetworkError as u8; + + core::mem::transmute::<[u8; core::mem::size_of::()], Error>(bytes) + }; + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Other `into_` methods return a payload, but since the NetworkError tag + /// has no payload, this does nothing and is only here for completeness. + pub fn into_NetworkError(self) { + () + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Other `as` methods return a payload, but since the NetworkError tag + /// has no payload, this does nothing and is only here for completeness. + pub unsafe fn as_NetworkError(&self) { + () + } + + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// A tag named Timeout, which has no payload. + pub const Timeout: Self = unsafe { + let mut bytes = [0; core::mem::size_of::()]; + + bytes[12] = discriminant_Error::Timeout as u8; + + core::mem::transmute::<[u8; core::mem::size_of::()], Error>(bytes) + }; + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Other `into_` methods return a payload, but since the Timeout tag + /// has no payload, this does nothing and is only here for completeness. + pub fn into_Timeout(self) { + () + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Other `as` methods return a payload, but since the Timeout tag + /// has no payload, this does nothing and is only here for completeness. + pub unsafe fn as_Timeout(&self) { + () + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_Error { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(24)) + } + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_Error) { + let discriminant_ptr: *mut discriminant_Error = (self as *mut Error).cast(); + + unsafe { + *(discriminant_ptr.add(24)) = discriminant; + } + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// A tag named NetworkError, which has no payload. + pub const NetworkError: Self = unsafe { + let mut bytes = [0; core::mem::size_of::()]; + + bytes[24] = discriminant_Error::NetworkError as u8; + + core::mem::transmute::<[u8; core::mem::size_of::()], Error>(bytes) + }; + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// A tag named Timeout, which has no payload. + pub const Timeout: Self = unsafe { + let mut bytes = [0; core::mem::size_of::()]; + + bytes[24] = discriminant_Error::Timeout as u8; + + core::mem::transmute::<[u8; core::mem::size_of::()], Error>(bytes) + }; +} + +impl Drop for Error { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn drop(&mut self) { + // Drop the payloads + match self.discriminant() { + discriminant_Error::BadBody => unsafe { + core::mem::ManuallyDrop::drop(&mut self.BadBody) + }, + discriminant_Error::BadStatus => {} + discriminant_Error::BadUrl => unsafe { + core::mem::ManuallyDrop::drop(&mut self.BadUrl) + }, + discriminant_Error::NetworkError => {} + discriminant_Error::Timeout => {} + } + } +} + +impl Eq for Error {} + +impl PartialEq for Error { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn eq(&self, other: &Self) -> bool { + if self.discriminant() != other.discriminant() { + return false; + } + + unsafe { + match self.discriminant() { + discriminant_Error::BadBody => self.BadBody == other.BadBody, + discriminant_Error::BadStatus => self.BadStatus == other.BadStatus, + discriminant_Error::BadUrl => self.BadUrl == other.BadUrl, + discriminant_Error::NetworkError => true, + discriminant_Error::Timeout => true, + } + } + } +} + +impl PartialOrd for Error { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn partial_cmp(&self, other: &Self) -> Option { + match self.discriminant().partial_cmp(&other.discriminant()) { + Some(core::cmp::Ordering::Equal) => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_Error::BadBody => self.BadBody.partial_cmp(&other.BadBody), + discriminant_Error::BadStatus => self.BadStatus.partial_cmp(&other.BadStatus), + discriminant_Error::BadUrl => self.BadUrl.partial_cmp(&other.BadUrl), + discriminant_Error::NetworkError => Some(core::cmp::Ordering::Equal), + discriminant_Error::Timeout => Some(core::cmp::Ordering::Equal), + } + } + } +} + +impl Ord for Error { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + match self.discriminant().cmp(&other.discriminant()) { + core::cmp::Ordering::Equal => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_Error::BadBody => self.BadBody.cmp(&other.BadBody), + discriminant_Error::BadStatus => self.BadStatus.cmp(&other.BadStatus), + discriminant_Error::BadUrl => self.BadUrl.cmp(&other.BadUrl), + discriminant_Error::NetworkError => core::cmp::Ordering::Equal, + discriminant_Error::Timeout => core::cmp::Ordering::Equal, + } + } + } +} + +impl Clone for Error { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn clone(&self) -> Self { + let mut answer = unsafe { + match self.discriminant() { + discriminant_Error::BadBody => Self { + BadBody: self.BadBody.clone(), + }, + discriminant_Error::BadStatus => Self { + BadStatus: self.BadStatus.clone(), + }, + discriminant_Error::BadUrl => Self { + BadUrl: self.BadUrl.clone(), + }, + discriminant_Error::NetworkError => { + core::mem::transmute::, Error>( + core::mem::MaybeUninit::uninit(), + ) + } + discriminant_Error::Timeout => core::mem::transmute::< + core::mem::MaybeUninit, + Error, + >(core::mem::MaybeUninit::uninit()), + } + }; + + answer.set_discriminant(self.discriminant()); + + answer + } +} + +impl core::hash::Hash for Error { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn hash(&self, state: &mut H) { + match self.discriminant() { + discriminant_Error::BadBody => unsafe { + discriminant_Error::BadBody.hash(state); + self.BadBody.hash(state); + }, + discriminant_Error::BadStatus => unsafe { + discriminant_Error::BadStatus.hash(state); + self.BadStatus.hash(state); + }, + discriminant_Error::BadUrl => unsafe { + discriminant_Error::BadUrl.hash(state); + self.BadUrl.hash(state); + }, + discriminant_Error::NetworkError => discriminant_Error::NetworkError.hash(state), + discriminant_Error::Timeout => discriminant_Error::Timeout.hash(state), + } + } +} + +impl core::fmt::Debug for Error { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str("Error::")?; + + unsafe { + match self.discriminant() { + discriminant_Error::BadBody => { + f.debug_tuple("BadBody").field(&*self.BadBody).finish() + } + discriminant_Error::BadStatus => { + f.debug_tuple("BadStatus").field(&self.BadStatus).finish() + } + discriminant_Error::BadUrl => f.debug_tuple("BadUrl").field(&*self.BadUrl).finish(), + discriminant_Error::NetworkError => f.write_str("NetworkError"), + discriminant_Error::Timeout => f.write_str("Timeout"), + } + } + } +} + +impl Part { + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_Part { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(23)) + } + } + + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_Part) { + let discriminant_ptr: *mut discriminant_Part = (self as *mut Part).cast(); + + unsafe { + *(discriminant_ptr.add(23)) = discriminant; + } + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Construct a tag named `Part`, with the appropriate payload + pub fn Part(arg0: roc_std::RocStr, arg1: roc_std::RocList) -> Self { + let mut answer = Self { + Part: core::mem::ManuallyDrop::new(Part_Part { f0: arg0, f1: arg1 }), + }; + + answer.set_discriminant(discriminant_Part::Part); + + answer + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `Part` has a `.discriminant()` of `Part` and convert it to `Part`'s payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `Part`. + pub unsafe fn into_Part(mut self) -> (roc_std::RocStr, roc_std::RocList) { + debug_assert_eq!(self.discriminant(), discriminant_Part::Part); + + let payload = core::mem::ManuallyDrop::take(&mut self.Part); + + (payload.f0, payload.f1) + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `Part` has a `.discriminant()` of `Part` and return its payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `Part`. + pub unsafe fn as_Part(&self) -> (&roc_std::RocStr, &roc_std::RocList) { + debug_assert_eq!(self.discriminant(), discriminant_Part::Part); + + let payload = &self.Part; + + (&payload.f0, &payload.f1) + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_Part { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(47)) + } + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_Part) { + let discriminant_ptr: *mut discriminant_Part = (self as *mut Part).cast(); + + unsafe { + *(discriminant_ptr.add(47)) = discriminant; + } + } +} + +impl Drop for Part { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn drop(&mut self) { + // Drop the payloads + match self.discriminant() { + discriminant_Part::Part => unsafe { core::mem::ManuallyDrop::drop(&mut self.Part) }, + } + } +} + +impl Eq for Part {} + +impl PartialEq for Part { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn eq(&self, other: &Self) -> bool { + if self.discriminant() != other.discriminant() { + return false; + } + + unsafe { + match self.discriminant() { + discriminant_Part::Part => self.Part == other.Part, + } + } + } +} + +impl PartialOrd for Part { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn partial_cmp(&self, other: &Self) -> Option { + match self.discriminant().partial_cmp(&other.discriminant()) { + Some(core::cmp::Ordering::Equal) => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_Part::Part => self.Part.partial_cmp(&other.Part), + } + } + } +} + +impl Ord for Part { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + match self.discriminant().cmp(&other.discriminant()) { + core::cmp::Ordering::Equal => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_Part::Part => self.Part.cmp(&other.Part), + } + } + } +} + +impl Clone for Part { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn clone(&self) -> Self { + let mut answer = unsafe { + match self.discriminant() { + discriminant_Part::Part => Self { + Part: self.Part.clone(), + }, + } + }; + + answer.set_discriminant(self.discriminant()); + + answer + } +} + +impl core::hash::Hash for Part { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn hash(&self, state: &mut H) { + match self.discriminant() { + discriminant_Part::Part => unsafe { + discriminant_Part::Part.hash(state); + self.Part.hash(state); + }, + } + } +} + +impl core::fmt::Debug for Part { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str("Part::")?; + + unsafe { + match self.discriminant() { + discriminant_Part::Part => f + .debug_tuple("Part") + .field(&(&*self.Part).f0) + .field(&(&*self.Part).f1) + .finish(), + } + } + } +} + +impl U5 { + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_U5 { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(11)) + } + } + + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_U5) { + let discriminant_ptr: *mut discriminant_U5 = (self as *mut U5).cast(); + + unsafe { + *(discriminant_ptr.add(11)) = discriminant; + } + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Construct a tag named `MimeType`, with the appropriate payload + pub fn MimeType(arg: roc_std::RocStr) -> Self { + let mut answer = Self { + MimeType: core::mem::ManuallyDrop::new(arg), + }; + + answer.set_discriminant(discriminant_U5::MimeType); + + answer + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `U5` has a `.discriminant()` of `MimeType` and convert it to `MimeType`'s payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `MimeType`. + pub unsafe fn into_MimeType(mut self) -> roc_std::RocStr { + debug_assert_eq!(self.discriminant(), discriminant_U5::MimeType); + + let payload = core::mem::ManuallyDrop::take(&mut self.MimeType); + + payload + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `U5` has a `.discriminant()` of `MimeType` and return its payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `MimeType`. + pub unsafe fn as_MimeType(&self) -> &roc_std::RocStr { + debug_assert_eq!(self.discriminant(), discriminant_U5::MimeType); + + let payload = &self.MimeType; + + &payload + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_U5 { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(23)) + } + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_U5) { + let discriminant_ptr: *mut discriminant_U5 = (self as *mut U5).cast(); + + unsafe { + *(discriminant_ptr.add(23)) = discriminant; + } + } +} + +impl Drop for U5 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn drop(&mut self) { + // Drop the payloads + match self.discriminant() { + discriminant_U5::MimeType => unsafe { + core::mem::ManuallyDrop::drop(&mut self.MimeType) + }, + } + } +} + +impl Eq for U5 {} + +impl PartialEq for U5 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn eq(&self, other: &Self) -> bool { + if self.discriminant() != other.discriminant() { + return false; + } + + unsafe { + match self.discriminant() { + discriminant_U5::MimeType => self.MimeType == other.MimeType, + } + } + } +} + +impl PartialOrd for U5 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn partial_cmp(&self, other: &Self) -> Option { + match self.discriminant().partial_cmp(&other.discriminant()) { + Some(core::cmp::Ordering::Equal) => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_U5::MimeType => self.MimeType.partial_cmp(&other.MimeType), + } + } + } +} + +impl Ord for U5 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + match self.discriminant().cmp(&other.discriminant()) { + core::cmp::Ordering::Equal => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_U5::MimeType => self.MimeType.cmp(&other.MimeType), + } + } + } +} + +impl Clone for U5 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn clone(&self) -> Self { + let mut answer = unsafe { + match self.discriminant() { + discriminant_U5::MimeType => Self { + MimeType: self.MimeType.clone(), + }, + } + }; + + answer.set_discriminant(self.discriminant()); + + answer + } +} + +impl core::hash::Hash for U5 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn hash(&self, state: &mut H) { + match self.discriminant() { + discriminant_U5::MimeType => unsafe { + discriminant_U5::MimeType.hash(state); + self.MimeType.hash(state); + }, + } + } +} + +impl core::fmt::Debug for U5 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str("U5::")?; + + unsafe { + match self.discriminant() { + discriminant_U5::MimeType => { + f.debug_tuple("MimeType").field(&*self.MimeType).finish() + } + } + } + } +} + +impl Body { + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_Body { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(24)) + } + } + + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_Body) { + let discriminant_ptr: *mut discriminant_Body = (self as *mut Body).cast(); + + unsafe { + *(discriminant_ptr.add(24)) = discriminant; + } + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Construct a tag named `Body`, with the appropriate payload + pub fn Body(arg0: U1, arg1: roc_std::RocList) -> Self { + let mut answer = Self { + Body: core::mem::ManuallyDrop::new(Body_Body { f0: arg0, f1: arg1 }), + }; + + answer.set_discriminant(discriminant_Body::Body); + + answer + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `Body` has a `.discriminant()` of `Body` and convert it to `Body`'s payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `Body`. + pub unsafe fn into_Body(mut self) -> (U1, roc_std::RocList) { + debug_assert_eq!(self.discriminant(), discriminant_Body::Body); + + let payload = core::mem::ManuallyDrop::take(&mut self.Body); + + (payload.f0, payload.f1) + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `Body` has a `.discriminant()` of `Body` and return its payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `Body`. + pub unsafe fn as_Body(&self) -> (&U1, &roc_std::RocList) { + debug_assert_eq!(self.discriminant(), discriminant_Body::Body); + + let payload = &self.Body; + + (&payload.f0, &payload.f1) + } + + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// A tag named EmptyBody, which has no payload. + pub const EmptyBody: Self = unsafe { + let mut bytes = [0; core::mem::size_of::()]; + + bytes[24] = discriminant_Body::EmptyBody as u8; + + core::mem::transmute::<[u8; core::mem::size_of::()], Body>(bytes) + }; + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Other `into_` methods return a payload, but since the EmptyBody tag + /// has no payload, this does nothing and is only here for completeness. + pub fn into_EmptyBody(self) { + () + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Other `as` methods return a payload, but since the EmptyBody tag + /// has no payload, this does nothing and is only here for completeness. + pub unsafe fn as_EmptyBody(&self) { + () + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_Body { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(48)) + } + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_Body) { + let discriminant_ptr: *mut discriminant_Body = (self as *mut Body).cast(); + + unsafe { + *(discriminant_ptr.add(48)) = discriminant; + } + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// A tag named EmptyBody, which has no payload. + pub const EmptyBody: Self = unsafe { + let mut bytes = [0; core::mem::size_of::()]; + + bytes[48] = discriminant_Body::EmptyBody as u8; + + core::mem::transmute::<[u8; core::mem::size_of::()], Body>(bytes) + }; +} + +impl Drop for Body { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn drop(&mut self) { + // Drop the payloads + match self.discriminant() { + discriminant_Body::Body => unsafe { core::mem::ManuallyDrop::drop(&mut self.Body) }, + discriminant_Body::EmptyBody => {} + } + } +} + +impl Eq for Body {} + +impl PartialEq for Body { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn eq(&self, other: &Self) -> bool { + if self.discriminant() != other.discriminant() { + return false; + } + + unsafe { + match self.discriminant() { + discriminant_Body::Body => self.Body == other.Body, + discriminant_Body::EmptyBody => true, + } + } + } +} + +impl PartialOrd for Body { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn partial_cmp(&self, other: &Self) -> Option { + match self.discriminant().partial_cmp(&other.discriminant()) { + Some(core::cmp::Ordering::Equal) => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_Body::Body => self.Body.partial_cmp(&other.Body), + discriminant_Body::EmptyBody => Some(core::cmp::Ordering::Equal), + } + } + } +} + +impl Ord for Body { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + match self.discriminant().cmp(&other.discriminant()) { + core::cmp::Ordering::Equal => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_Body::Body => self.Body.cmp(&other.Body), + discriminant_Body::EmptyBody => core::cmp::Ordering::Equal, + } + } + } +} + +impl Clone for Body { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn clone(&self) -> Self { + let mut answer = unsafe { + match self.discriminant() { + discriminant_Body::Body => Self { + Body: self.Body.clone(), + }, + discriminant_Body::EmptyBody => core::mem::transmute::< + core::mem::MaybeUninit, + Body, + >(core::mem::MaybeUninit::uninit()), + } + }; + + answer.set_discriminant(self.discriminant()); + + answer + } +} + +impl core::hash::Hash for Body { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn hash(&self, state: &mut H) { + match self.discriminant() { + discriminant_Body::Body => unsafe { + discriminant_Body::Body.hash(state); + self.Body.hash(state); + }, + discriminant_Body::EmptyBody => discriminant_Body::EmptyBody.hash(state), + } + } +} + +impl core::fmt::Debug for Body { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str("Body::")?; + + unsafe { + match self.discriminant() { + discriminant_Body::Body => f + .debug_tuple("Body") + .field(&(&*self.Body).f0) + .field(&(&*self.Body).f1) + .finish(), + discriminant_Body::EmptyBody => f.write_str("EmptyBody"), + } + } + } +} + +impl U3 { + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_U3 { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(11)) + } + } + + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_U3) { + let discriminant_ptr: *mut discriminant_U3 = (self as *mut U3).cast(); + + unsafe { + *(discriminant_ptr.add(11)) = discriminant; + } + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Construct a tag named `MimeType`, with the appropriate payload + pub fn MimeType(arg: roc_std::RocStr) -> Self { + let mut answer = Self { + MimeType: core::mem::ManuallyDrop::new(arg), + }; + + answer.set_discriminant(discriminant_U3::MimeType); + + answer + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `U3` has a `.discriminant()` of `MimeType` and convert it to `MimeType`'s payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `MimeType`. + pub unsafe fn into_MimeType(mut self) -> roc_std::RocStr { + debug_assert_eq!(self.discriminant(), discriminant_U3::MimeType); + + let payload = core::mem::ManuallyDrop::take(&mut self.MimeType); + + payload + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `U3` has a `.discriminant()` of `MimeType` and return its payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `MimeType`. + pub unsafe fn as_MimeType(&self) -> &roc_std::RocStr { + debug_assert_eq!(self.discriminant(), discriminant_U3::MimeType); + + let payload = &self.MimeType; + + &payload + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_U3 { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(23)) + } + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_U3) { + let discriminant_ptr: *mut discriminant_U3 = (self as *mut U3).cast(); + + unsafe { + *(discriminant_ptr.add(23)) = discriminant; + } + } +} + +impl Drop for U3 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn drop(&mut self) { + // Drop the payloads + match self.discriminant() { + discriminant_U3::MimeType => unsafe { + core::mem::ManuallyDrop::drop(&mut self.MimeType) + }, + } + } +} + +impl Eq for U3 {} + +impl PartialEq for U3 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn eq(&self, other: &Self) -> bool { + if self.discriminant() != other.discriminant() { + return false; + } + + unsafe { + match self.discriminant() { + discriminant_U3::MimeType => self.MimeType == other.MimeType, + } + } + } +} + +impl PartialOrd for U3 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn partial_cmp(&self, other: &Self) -> Option { + match self.discriminant().partial_cmp(&other.discriminant()) { + Some(core::cmp::Ordering::Equal) => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_U3::MimeType => self.MimeType.partial_cmp(&other.MimeType), + } + } + } +} + +impl Ord for U3 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + match self.discriminant().cmp(&other.discriminant()) { + core::cmp::Ordering::Equal => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_U3::MimeType => self.MimeType.cmp(&other.MimeType), + } + } + } +} + +impl Clone for U3 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn clone(&self) -> Self { + let mut answer = unsafe { + match self.discriminant() { + discriminant_U3::MimeType => Self { + MimeType: self.MimeType.clone(), + }, + } + }; + + answer.set_discriminant(self.discriminant()); + + answer + } +} + +impl core::hash::Hash for U3 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn hash(&self, state: &mut H) { + match self.discriminant() { + discriminant_U3::MimeType => unsafe { + discriminant_U3::MimeType.hash(state); + self.MimeType.hash(state); + }, + } + } +} + +impl core::fmt::Debug for U3 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str("U3::")?; + + unsafe { + match self.discriminant() { + discriminant_U3::MimeType => { + f.debug_tuple("MimeType").field(&*self.MimeType).finish() + } + } + } + } +} + +impl Response { + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_Response { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(52)) + } + } + + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_Response) { + let discriminant_ptr: *mut discriminant_Response = (self as *mut Response).cast(); + + unsafe { + *(discriminant_ptr.add(52)) = discriminant; + } + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Construct a tag named `BadStatus`, with the appropriate payload + pub fn BadStatus(arg0: Metadata, arg1: roc_std::RocList) -> Self { + let mut answer = Self { + BadStatus: core::mem::ManuallyDrop::new(Response_BadStatus { f0: arg0, f1: arg1 }), + }; + + answer.set_discriminant(discriminant_Response::BadStatus); + + answer + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `Response` has a `.discriminant()` of `BadStatus` and convert it to `BadStatus`'s payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `BadStatus`. + pub unsafe fn into_BadStatus(mut self) -> (Metadata, roc_std::RocList) { + debug_assert_eq!(self.discriminant(), discriminant_Response::BadStatus); + + let payload = core::mem::ManuallyDrop::take(&mut self.BadStatus); + + (payload.f0, payload.f1) + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `Response` has a `.discriminant()` of `BadStatus` and return its payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `BadStatus`. + pub unsafe fn as_BadStatus(&self) -> (&Metadata, &roc_std::RocList) { + debug_assert_eq!(self.discriminant(), discriminant_Response::BadStatus); + + let payload = &self.BadStatus; + + (&payload.f0, &payload.f1) + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Construct a tag named `BadUrl`, with the appropriate payload + pub fn BadUrl(arg: roc_std::RocStr) -> Self { + let mut answer = Self { + BadUrl: core::mem::ManuallyDrop::new(arg), + }; + + answer.set_discriminant(discriminant_Response::BadUrl); + + answer + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `Response` has a `.discriminant()` of `BadUrl` and convert it to `BadUrl`'s payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `BadUrl`. + pub unsafe fn into_BadUrl(mut self) -> roc_std::RocStr { + debug_assert_eq!(self.discriminant(), discriminant_Response::BadUrl); + + let payload = core::mem::ManuallyDrop::take(&mut self.BadUrl); + + payload + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `Response` has a `.discriminant()` of `BadUrl` and return its payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `BadUrl`. + pub unsafe fn as_BadUrl(&self) -> &roc_std::RocStr { + debug_assert_eq!(self.discriminant(), discriminant_Response::BadUrl); + + let payload = &self.BadUrl; + + &payload + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Construct a tag named `GoodStatus`, with the appropriate payload + pub fn GoodStatus(arg0: Metadata, arg1: roc_std::RocList) -> Self { + let mut answer = Self { + GoodStatus: core::mem::ManuallyDrop::new(Response_GoodStatus { f0: arg0, f1: arg1 }), + }; + + answer.set_discriminant(discriminant_Response::GoodStatus); + + answer + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `Response` has a `.discriminant()` of `GoodStatus` and convert it to `GoodStatus`'s payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `GoodStatus`. + pub unsafe fn into_GoodStatus(mut self) -> (Metadata, roc_std::RocList) { + debug_assert_eq!(self.discriminant(), discriminant_Response::GoodStatus); + + let payload = core::mem::ManuallyDrop::take(&mut self.GoodStatus); + + (payload.f0, payload.f1) + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `Response` has a `.discriminant()` of `GoodStatus` and return its payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `GoodStatus`. + pub unsafe fn as_GoodStatus(&self) -> (&Metadata, &roc_std::RocList) { + debug_assert_eq!(self.discriminant(), discriminant_Response::GoodStatus); + + let payload = &self.GoodStatus; + + (&payload.f0, &payload.f1) + } + + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// A tag named NetworkError, which has no payload. + pub const NetworkError: Self = unsafe { + let mut bytes = [0; core::mem::size_of::()]; + + bytes[52] = discriminant_Response::NetworkError as u8; + + core::mem::transmute::<[u8; core::mem::size_of::()], Response>(bytes) + }; + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Other `into_` methods return a payload, but since the NetworkError tag + /// has no payload, this does nothing and is only here for completeness. + pub fn into_NetworkError(self) { + () + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Other `as` methods return a payload, but since the NetworkError tag + /// has no payload, this does nothing and is only here for completeness. + pub unsafe fn as_NetworkError(&self) { + () + } + + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// A tag named Timeout, which has no payload. + pub const Timeout: Self = unsafe { + let mut bytes = [0; core::mem::size_of::()]; + + bytes[52] = discriminant_Response::Timeout as u8; + + core::mem::transmute::<[u8; core::mem::size_of::()], Response>(bytes) + }; + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Other `into_` methods return a payload, but since the Timeout tag + /// has no payload, this does nothing and is only here for completeness. + pub fn into_Timeout(self) { + () + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Other `as` methods return a payload, but since the Timeout tag + /// has no payload, this does nothing and is only here for completeness. + pub unsafe fn as_Timeout(&self) { + () + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_Response { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(104)) + } + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_Response) { + let discriminant_ptr: *mut discriminant_Response = (self as *mut Response).cast(); + + unsafe { + *(discriminant_ptr.add(104)) = discriminant; + } + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// A tag named NetworkError, which has no payload. + pub const NetworkError: Self = unsafe { + let mut bytes = [0; core::mem::size_of::()]; + + bytes[104] = discriminant_Response::NetworkError as u8; + + core::mem::transmute::<[u8; core::mem::size_of::()], Response>(bytes) + }; + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// A tag named Timeout, which has no payload. + pub const Timeout: Self = unsafe { + let mut bytes = [0; core::mem::size_of::()]; + + bytes[104] = discriminant_Response::Timeout as u8; + + core::mem::transmute::<[u8; core::mem::size_of::()], Response>(bytes) + }; +} + +impl Drop for Response { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn drop(&mut self) { + // Drop the payloads + match self.discriminant() { + discriminant_Response::BadStatus => unsafe { + core::mem::ManuallyDrop::drop(&mut self.BadStatus) + }, + discriminant_Response::BadUrl => unsafe { + core::mem::ManuallyDrop::drop(&mut self.BadUrl) + }, + discriminant_Response::GoodStatus => unsafe { + core::mem::ManuallyDrop::drop(&mut self.GoodStatus) + }, + discriminant_Response::NetworkError => {} + discriminant_Response::Timeout => {} + } + } +} + +impl Eq for Response {} + +impl PartialEq for Response { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn eq(&self, other: &Self) -> bool { + if self.discriminant() != other.discriminant() { + return false; + } + + unsafe { + match self.discriminant() { + discriminant_Response::BadStatus => self.BadStatus == other.BadStatus, + discriminant_Response::BadUrl => self.BadUrl == other.BadUrl, + discriminant_Response::GoodStatus => self.GoodStatus == other.GoodStatus, + discriminant_Response::NetworkError => true, + discriminant_Response::Timeout => true, + } + } + } +} + +impl PartialOrd for Response { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn partial_cmp(&self, other: &Self) -> Option { + match self.discriminant().partial_cmp(&other.discriminant()) { + Some(core::cmp::Ordering::Equal) => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_Response::BadStatus => self.BadStatus.partial_cmp(&other.BadStatus), + discriminant_Response::BadUrl => self.BadUrl.partial_cmp(&other.BadUrl), + discriminant_Response::GoodStatus => self.GoodStatus.partial_cmp(&other.GoodStatus), + discriminant_Response::NetworkError => Some(core::cmp::Ordering::Equal), + discriminant_Response::Timeout => Some(core::cmp::Ordering::Equal), + } + } + } +} + +impl Ord for Response { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + match self.discriminant().cmp(&other.discriminant()) { + core::cmp::Ordering::Equal => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_Response::BadStatus => self.BadStatus.cmp(&other.BadStatus), + discriminant_Response::BadUrl => self.BadUrl.cmp(&other.BadUrl), + discriminant_Response::GoodStatus => self.GoodStatus.cmp(&other.GoodStatus), + discriminant_Response::NetworkError => core::cmp::Ordering::Equal, + discriminant_Response::Timeout => core::cmp::Ordering::Equal, + } + } + } +} + +impl Clone for Response { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn clone(&self) -> Self { + let mut answer = unsafe { + match self.discriminant() { + discriminant_Response::BadStatus => Self { + BadStatus: self.BadStatus.clone(), + }, + discriminant_Response::BadUrl => Self { + BadUrl: self.BadUrl.clone(), + }, + discriminant_Response::GoodStatus => Self { + GoodStatus: self.GoodStatus.clone(), + }, + discriminant_Response::NetworkError => { + core::mem::transmute::, Response>( + core::mem::MaybeUninit::uninit(), + ) + } + discriminant_Response::Timeout => { + core::mem::transmute::, Response>( + core::mem::MaybeUninit::uninit(), + ) + } + } + }; + + answer.set_discriminant(self.discriminant()); + + answer + } +} + +impl core::hash::Hash for Response { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn hash(&self, state: &mut H) { + match self.discriminant() { + discriminant_Response::BadStatus => unsafe { + discriminant_Response::BadStatus.hash(state); + self.BadStatus.hash(state); + }, + discriminant_Response::BadUrl => unsafe { + discriminant_Response::BadUrl.hash(state); + self.BadUrl.hash(state); + }, + discriminant_Response::GoodStatus => unsafe { + discriminant_Response::GoodStatus.hash(state); + self.GoodStatus.hash(state); + }, + discriminant_Response::NetworkError => discriminant_Response::NetworkError.hash(state), + discriminant_Response::Timeout => discriminant_Response::Timeout.hash(state), + } + } +} + +impl core::fmt::Debug for Response { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str("Response::")?; + + unsafe { + match self.discriminant() { + discriminant_Response::BadStatus => f + .debug_tuple("BadStatus") + .field(&(&*self.BadStatus).f0) + .field(&(&*self.BadStatus).f1) + .finish(), + discriminant_Response::BadUrl => { + f.debug_tuple("BadUrl").field(&*self.BadUrl).finish() + } + discriminant_Response::GoodStatus => f + .debug_tuple("GoodStatus") + .field(&(&*self.GoodStatus).f0) + .field(&(&*self.GoodStatus).f1) + .finish(), + discriminant_Response::NetworkError => f.write_str("NetworkError"), + discriminant_Response::Timeout => f.write_str("Timeout"), + } + } + } +} + +impl U8 { + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_U8 { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(11)) + } + } + + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_U8) { + let discriminant_ptr: *mut discriminant_U8 = (self as *mut U8).cast(); + + unsafe { + *(discriminant_ptr.add(11)) = discriminant; + } + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Construct a tag named `MimeType`, with the appropriate payload + pub fn MimeType(arg: roc_std::RocStr) -> Self { + let mut answer = Self { + MimeType: core::mem::ManuallyDrop::new(arg), + }; + + answer.set_discriminant(discriminant_U8::MimeType); + + answer + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `U8` has a `.discriminant()` of `MimeType` and convert it to `MimeType`'s payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `MimeType`. + pub unsafe fn into_MimeType(mut self) -> roc_std::RocStr { + debug_assert_eq!(self.discriminant(), discriminant_U8::MimeType); + + let payload = core::mem::ManuallyDrop::take(&mut self.MimeType); + + payload + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `U8` has a `.discriminant()` of `MimeType` and return its payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `MimeType`. + pub unsafe fn as_MimeType(&self) -> &roc_std::RocStr { + debug_assert_eq!(self.discriminant(), discriminant_U8::MimeType); + + let payload = &self.MimeType; + + &payload + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_U8 { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(23)) + } + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_U8) { + let discriminant_ptr: *mut discriminant_U8 = (self as *mut U8).cast(); + + unsafe { + *(discriminant_ptr.add(23)) = discriminant; + } + } +} + +impl Drop for U8 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn drop(&mut self) { + // Drop the payloads + match self.discriminant() { + discriminant_U8::MimeType => unsafe { + core::mem::ManuallyDrop::drop(&mut self.MimeType) + }, + } + } +} + +impl Eq for U8 {} + +impl PartialEq for U8 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn eq(&self, other: &Self) -> bool { + if self.discriminant() != other.discriminant() { + return false; + } + + unsafe { + match self.discriminant() { + discriminant_U8::MimeType => self.MimeType == other.MimeType, + } + } + } +} + +impl PartialOrd for U8 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn partial_cmp(&self, other: &Self) -> Option { + match self.discriminant().partial_cmp(&other.discriminant()) { + Some(core::cmp::Ordering::Equal) => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_U8::MimeType => self.MimeType.partial_cmp(&other.MimeType), + } + } + } +} + +impl Ord for U8 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + match self.discriminant().cmp(&other.discriminant()) { + core::cmp::Ordering::Equal => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_U8::MimeType => self.MimeType.cmp(&other.MimeType), + } + } + } +} + +impl Clone for U8 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn clone(&self) -> Self { + let mut answer = unsafe { + match self.discriminant() { + discriminant_U8::MimeType => Self { + MimeType: self.MimeType.clone(), + }, + } + }; + + answer.set_discriminant(self.discriminant()); + + answer + } +} + +impl core::hash::Hash for U8 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn hash(&self, state: &mut H) { + match self.discriminant() { + discriminant_U8::MimeType => unsafe { + discriminant_U8::MimeType.hash(state); + self.MimeType.hash(state); + }, + } + } +} + +impl core::fmt::Debug for U8 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str("U8::")?; + + unsafe { + match self.discriminant() { + discriminant_U8::MimeType => { + f.debug_tuple("MimeType").field(&*self.MimeType).finish() + } + } + } + } +} + +impl U7 { + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_U7 { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(11)) + } + } + + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_U7) { + let discriminant_ptr: *mut discriminant_U7 = (self as *mut U7).cast(); + + unsafe { + *(discriminant_ptr.add(11)) = discriminant; + } + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Construct a tag named `MimeType`, with the appropriate payload + pub fn MimeType(arg: roc_std::RocStr) -> Self { + let mut answer = Self { + MimeType: core::mem::ManuallyDrop::new(arg), + }; + + answer.set_discriminant(discriminant_U7::MimeType); + + answer + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `U7` has a `.discriminant()` of `MimeType` and convert it to `MimeType`'s payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `MimeType`. + pub unsafe fn into_MimeType(mut self) -> roc_std::RocStr { + debug_assert_eq!(self.discriminant(), discriminant_U7::MimeType); + + let payload = core::mem::ManuallyDrop::take(&mut self.MimeType); + + payload + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `U7` has a `.discriminant()` of `MimeType` and return its payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `MimeType`. + pub unsafe fn as_MimeType(&self) -> &roc_std::RocStr { + debug_assert_eq!(self.discriminant(), discriminant_U7::MimeType); + + let payload = &self.MimeType; + + &payload + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_U7 { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(23)) + } + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_U7) { + let discriminant_ptr: *mut discriminant_U7 = (self as *mut U7).cast(); + + unsafe { + *(discriminant_ptr.add(23)) = discriminant; + } + } +} + +impl Drop for U7 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn drop(&mut self) { + // Drop the payloads + match self.discriminant() { + discriminant_U7::MimeType => unsafe { + core::mem::ManuallyDrop::drop(&mut self.MimeType) + }, + } + } +} + +impl Eq for U7 {} + +impl PartialEq for U7 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn eq(&self, other: &Self) -> bool { + if self.discriminant() != other.discriminant() { + return false; + } + + unsafe { + match self.discriminant() { + discriminant_U7::MimeType => self.MimeType == other.MimeType, + } + } + } +} + +impl PartialOrd for U7 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn partial_cmp(&self, other: &Self) -> Option { + match self.discriminant().partial_cmp(&other.discriminant()) { + Some(core::cmp::Ordering::Equal) => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_U7::MimeType => self.MimeType.partial_cmp(&other.MimeType), + } + } + } +} + +impl Ord for U7 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + match self.discriminant().cmp(&other.discriminant()) { + core::cmp::Ordering::Equal => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_U7::MimeType => self.MimeType.cmp(&other.MimeType), + } + } + } +} + +impl Clone for U7 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn clone(&self) -> Self { + let mut answer = unsafe { + match self.discriminant() { + discriminant_U7::MimeType => Self { + MimeType: self.MimeType.clone(), + }, + } + }; + + answer.set_discriminant(self.discriminant()); + + answer + } +} + +impl core::hash::Hash for U7 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn hash(&self, state: &mut H) { + match self.discriminant() { + discriminant_U7::MimeType => unsafe { + discriminant_U7::MimeType.hash(state); + self.MimeType.hash(state); + }, + } + } +} + +impl core::fmt::Debug for U7 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str("U7::")?; + + unsafe { + match self.discriminant() { + discriminant_U7::MimeType => { + f.debug_tuple("MimeType").field(&*self.MimeType).finish() + } + } + } + } +} + +impl U6 { + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_U6 { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(11)) + } + } + + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_U6) { + let discriminant_ptr: *mut discriminant_U6 = (self as *mut U6).cast(); + + unsafe { + *(discriminant_ptr.add(11)) = discriminant; + } + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Construct a tag named `MimeType`, with the appropriate payload + pub fn MimeType(arg: roc_std::RocStr) -> Self { + let mut answer = Self { + MimeType: core::mem::ManuallyDrop::new(arg), + }; + + answer.set_discriminant(discriminant_U6::MimeType); + + answer + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `U6` has a `.discriminant()` of `MimeType` and convert it to `MimeType`'s payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `MimeType`. + pub unsafe fn into_MimeType(mut self) -> roc_std::RocStr { + debug_assert_eq!(self.discriminant(), discriminant_U6::MimeType); + + let payload = core::mem::ManuallyDrop::take(&mut self.MimeType); + + payload + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `U6` has a `.discriminant()` of `MimeType` and return its payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `MimeType`. + pub unsafe fn as_MimeType(&self) -> &roc_std::RocStr { + debug_assert_eq!(self.discriminant(), discriminant_U6::MimeType); + + let payload = &self.MimeType; + + &payload + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_U6 { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(23)) + } + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_U6) { + let discriminant_ptr: *mut discriminant_U6 = (self as *mut U6).cast(); + + unsafe { + *(discriminant_ptr.add(23)) = discriminant; + } + } +} + +impl Drop for U6 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn drop(&mut self) { + // Drop the payloads + match self.discriminant() { + discriminant_U6::MimeType => unsafe { + core::mem::ManuallyDrop::drop(&mut self.MimeType) + }, + } + } +} + +impl Eq for U6 {} + +impl PartialEq for U6 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn eq(&self, other: &Self) -> bool { + if self.discriminant() != other.discriminant() { + return false; + } + + unsafe { + match self.discriminant() { + discriminant_U6::MimeType => self.MimeType == other.MimeType, + } + } + } +} + +impl PartialOrd for U6 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn partial_cmp(&self, other: &Self) -> Option { + match self.discriminant().partial_cmp(&other.discriminant()) { + Some(core::cmp::Ordering::Equal) => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_U6::MimeType => self.MimeType.partial_cmp(&other.MimeType), + } + } + } +} + +impl Ord for U6 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + match self.discriminant().cmp(&other.discriminant()) { + core::cmp::Ordering::Equal => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_U6::MimeType => self.MimeType.cmp(&other.MimeType), + } + } + } +} + +impl Clone for U6 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn clone(&self) -> Self { + let mut answer = unsafe { + match self.discriminant() { + discriminant_U6::MimeType => Self { + MimeType: self.MimeType.clone(), + }, + } + }; + + answer.set_discriminant(self.discriminant()); + + answer + } +} + +impl core::hash::Hash for U6 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn hash(&self, state: &mut H) { + match self.discriminant() { + discriminant_U6::MimeType => unsafe { + discriminant_U6::MimeType.hash(state); + self.MimeType.hash(state); + }, + } + } +} + +impl core::fmt::Debug for U6 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str("U6::")?; + + unsafe { + match self.discriminant() { + discriminant_U6::MimeType => { + f.debug_tuple("MimeType").field(&*self.MimeType).finish() + } + } + } + } +} + +impl U4 { + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_U4 { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(11)) + } + } + + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_U4) { + let discriminant_ptr: *mut discriminant_U4 = (self as *mut U4).cast(); + + unsafe { + *(discriminant_ptr.add(11)) = discriminant; + } + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Construct a tag named `MimeType`, with the appropriate payload + pub fn MimeType(arg: roc_std::RocStr) -> Self { + let mut answer = Self { + MimeType: core::mem::ManuallyDrop::new(arg), + }; + + answer.set_discriminant(discriminant_U4::MimeType); + + answer + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `U4` has a `.discriminant()` of `MimeType` and convert it to `MimeType`'s payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `MimeType`. + pub unsafe fn into_MimeType(mut self) -> roc_std::RocStr { + debug_assert_eq!(self.discriminant(), discriminant_U4::MimeType); + + let payload = core::mem::ManuallyDrop::take(&mut self.MimeType); + + payload + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `U4` has a `.discriminant()` of `MimeType` and return its payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `MimeType`. + pub unsafe fn as_MimeType(&self) -> &roc_std::RocStr { + debug_assert_eq!(self.discriminant(), discriminant_U4::MimeType); + + let payload = &self.MimeType; + + &payload + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_U4 { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(23)) + } + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_U4) { + let discriminant_ptr: *mut discriminant_U4 = (self as *mut U4).cast(); + + unsafe { + *(discriminant_ptr.add(23)) = discriminant; + } + } +} + +impl Drop for U4 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn drop(&mut self) { + // Drop the payloads + match self.discriminant() { + discriminant_U4::MimeType => unsafe { + core::mem::ManuallyDrop::drop(&mut self.MimeType) + }, + } + } +} + +impl Eq for U4 {} + +impl PartialEq for U4 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn eq(&self, other: &Self) -> bool { + if self.discriminant() != other.discriminant() { + return false; + } + + unsafe { + match self.discriminant() { + discriminant_U4::MimeType => self.MimeType == other.MimeType, + } + } + } +} + +impl PartialOrd for U4 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn partial_cmp(&self, other: &Self) -> Option { + match self.discriminant().partial_cmp(&other.discriminant()) { + Some(core::cmp::Ordering::Equal) => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_U4::MimeType => self.MimeType.partial_cmp(&other.MimeType), + } + } + } +} + +impl Ord for U4 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + match self.discriminant().cmp(&other.discriminant()) { + core::cmp::Ordering::Equal => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_U4::MimeType => self.MimeType.cmp(&other.MimeType), + } + } + } +} + +impl Clone for U4 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn clone(&self) -> Self { + let mut answer = unsafe { + match self.discriminant() { + discriminant_U4::MimeType => Self { + MimeType: self.MimeType.clone(), + }, + } + }; + + answer.set_discriminant(self.discriminant()); + + answer + } +} + +impl core::hash::Hash for U4 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn hash(&self, state: &mut H) { + match self.discriminant() { + discriminant_U4::MimeType => unsafe { + discriminant_U4::MimeType.hash(state); + self.MimeType.hash(state); + }, + } + } +} + +impl core::fmt::Debug for U4 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str("U4::")?; + + unsafe { + match self.discriminant() { + discriminant_U4::MimeType => { + f.debug_tuple("MimeType").field(&*self.MimeType).finish() + } + } + } + } +} + +impl U2 { + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_U2 { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(11)) + } + } + + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_U2) { + let discriminant_ptr: *mut discriminant_U2 = (self as *mut U2).cast(); + + unsafe { + *(discriminant_ptr.add(11)) = discriminant; + } + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Construct a tag named `MimeType`, with the appropriate payload + pub fn MimeType(arg: roc_std::RocStr) -> Self { + let mut answer = Self { + MimeType: core::mem::ManuallyDrop::new(arg), + }; + + answer.set_discriminant(discriminant_U2::MimeType); + + answer + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `U2` has a `.discriminant()` of `MimeType` and convert it to `MimeType`'s payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `MimeType`. + pub unsafe fn into_MimeType(mut self) -> roc_std::RocStr { + debug_assert_eq!(self.discriminant(), discriminant_U2::MimeType); + + let payload = core::mem::ManuallyDrop::take(&mut self.MimeType); + + payload + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `U2` has a `.discriminant()` of `MimeType` and return its payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `MimeType`. + pub unsafe fn as_MimeType(&self) -> &roc_std::RocStr { + debug_assert_eq!(self.discriminant(), discriminant_U2::MimeType); + + let payload = &self.MimeType; + + &payload + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_U2 { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(23)) + } + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_U2) { + let discriminant_ptr: *mut discriminant_U2 = (self as *mut U2).cast(); + + unsafe { + *(discriminant_ptr.add(23)) = discriminant; + } + } +} + +impl Drop for U2 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn drop(&mut self) { + // Drop the payloads + match self.discriminant() { + discriminant_U2::MimeType => unsafe { + core::mem::ManuallyDrop::drop(&mut self.MimeType) + }, + } + } +} + +impl Eq for U2 {} + +impl PartialEq for U2 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn eq(&self, other: &Self) -> bool { + if self.discriminant() != other.discriminant() { + return false; + } + + unsafe { + match self.discriminant() { + discriminant_U2::MimeType => self.MimeType == other.MimeType, + } + } + } +} + +impl PartialOrd for U2 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn partial_cmp(&self, other: &Self) -> Option { + match self.discriminant().partial_cmp(&other.discriminant()) { + Some(core::cmp::Ordering::Equal) => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_U2::MimeType => self.MimeType.partial_cmp(&other.MimeType), + } + } + } +} + +impl Ord for U2 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + match self.discriminant().cmp(&other.discriminant()) { + core::cmp::Ordering::Equal => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_U2::MimeType => self.MimeType.cmp(&other.MimeType), + } + } + } +} + +impl Clone for U2 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn clone(&self) -> Self { + let mut answer = unsafe { + match self.discriminant() { + discriminant_U2::MimeType => Self { + MimeType: self.MimeType.clone(), + }, + } + }; + + answer.set_discriminant(self.discriminant()); + + answer + } +} + +impl core::hash::Hash for U2 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn hash(&self, state: &mut H) { + match self.discriminant() { + discriminant_U2::MimeType => unsafe { + discriminant_U2::MimeType.hash(state); + self.MimeType.hash(state); + }, + } + } +} + +impl core::fmt::Debug for U2 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str("U2::")?; + + unsafe { + match self.discriminant() { + discriminant_U2::MimeType => { + f.debug_tuple("MimeType").field(&*self.MimeType).finish() + } + } + } + } +} + +impl TrackerConfig { + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_TrackerConfig { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(12)) + } + } + + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_TrackerConfig) { + let discriminant_ptr: *mut discriminant_TrackerConfig = (self as *mut TrackerConfig).cast(); + + unsafe { + *(discriminant_ptr.add(12)) = discriminant; + } + } + + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// A tag named NoTracker, which has no payload. + pub const NoTracker: Self = unsafe { + let mut bytes = [0; core::mem::size_of::()]; + + bytes[12] = discriminant_TrackerConfig::NoTracker as u8; + + core::mem::transmute::<[u8; core::mem::size_of::()], TrackerConfig>(bytes) + }; + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Other `into_` methods return a payload, but since the NoTracker tag + /// has no payload, this does nothing and is only here for completeness. + pub fn into_NoTracker(self) { + () + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Other `as` methods return a payload, but since the NoTracker tag + /// has no payload, this does nothing and is only here for completeness. + pub unsafe fn as_NoTracker(&self) { + () + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Construct a tag named `Tracker`, with the appropriate payload + pub fn Tracker(arg: roc_std::RocStr) -> Self { + let mut answer = Self { + Tracker: core::mem::ManuallyDrop::new(arg), + }; + + answer.set_discriminant(discriminant_TrackerConfig::Tracker); + + answer + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `TrackerConfig` has a `.discriminant()` of `Tracker` and convert it to `Tracker`'s payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `Tracker`. + pub unsafe fn into_Tracker(mut self) -> roc_std::RocStr { + debug_assert_eq!(self.discriminant(), discriminant_TrackerConfig::Tracker); + + let payload = core::mem::ManuallyDrop::take(&mut self.Tracker); + + payload + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `TrackerConfig` has a `.discriminant()` of `Tracker` and return its payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `Tracker`. + pub unsafe fn as_Tracker(&self) -> &roc_std::RocStr { + debug_assert_eq!(self.discriminant(), discriminant_TrackerConfig::Tracker); + + let payload = &self.Tracker; + + &payload + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_TrackerConfig { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(24)) + } + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_TrackerConfig) { + let discriminant_ptr: *mut discriminant_TrackerConfig = (self as *mut TrackerConfig).cast(); + + unsafe { + *(discriminant_ptr.add(24)) = discriminant; + } + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// A tag named NoTracker, which has no payload. + pub const NoTracker: Self = unsafe { + let mut bytes = [0; core::mem::size_of::()]; + + bytes[24] = discriminant_TrackerConfig::NoTracker as u8; + + core::mem::transmute::<[u8; core::mem::size_of::()], TrackerConfig>(bytes) + }; +} + +impl Drop for TrackerConfig { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn drop(&mut self) { + // Drop the payloads + match self.discriminant() { + discriminant_TrackerConfig::NoTracker => {} + discriminant_TrackerConfig::Tracker => unsafe { + core::mem::ManuallyDrop::drop(&mut self.Tracker) + }, + } + } +} + +impl Eq for TrackerConfig {} + +impl PartialEq for TrackerConfig { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn eq(&self, other: &Self) -> bool { + if self.discriminant() != other.discriminant() { + return false; + } + + unsafe { + match self.discriminant() { + discriminant_TrackerConfig::NoTracker => true, + discriminant_TrackerConfig::Tracker => self.Tracker == other.Tracker, + } + } + } +} + +impl PartialOrd for TrackerConfig { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn partial_cmp(&self, other: &Self) -> Option { + match self.discriminant().partial_cmp(&other.discriminant()) { + Some(core::cmp::Ordering::Equal) => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_TrackerConfig::NoTracker => Some(core::cmp::Ordering::Equal), + discriminant_TrackerConfig::Tracker => self.Tracker.partial_cmp(&other.Tracker), + } + } + } +} + +impl Ord for TrackerConfig { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + match self.discriminant().cmp(&other.discriminant()) { + core::cmp::Ordering::Equal => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_TrackerConfig::NoTracker => core::cmp::Ordering::Equal, + discriminant_TrackerConfig::Tracker => self.Tracker.cmp(&other.Tracker), + } + } + } +} + +impl Clone for TrackerConfig { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn clone(&self) -> Self { + let mut answer = unsafe { + match self.discriminant() { + discriminant_TrackerConfig::NoTracker => { + core::mem::transmute::, TrackerConfig>( + core::mem::MaybeUninit::uninit(), + ) + } + discriminant_TrackerConfig::Tracker => Self { + Tracker: self.Tracker.clone(), + }, + } + }; + + answer.set_discriminant(self.discriminant()); + + answer + } +} + +impl core::hash::Hash for TrackerConfig { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn hash(&self, state: &mut H) { + match self.discriminant() { + discriminant_TrackerConfig::NoTracker => { + discriminant_TrackerConfig::NoTracker.hash(state) + } + discriminant_TrackerConfig::Tracker => unsafe { + discriminant_TrackerConfig::Tracker.hash(state); + self.Tracker.hash(state); + }, + } + } +} + +impl core::fmt::Debug for TrackerConfig { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str("TrackerConfig::")?; + + unsafe { + match self.discriminant() { + discriminant_TrackerConfig::NoTracker => f.write_str("NoTracker"), + discriminant_TrackerConfig::Tracker => { + f.debug_tuple("Tracker").field(&*self.Tracker).finish() + } + } + } + } +} + +impl TimeoutConfig { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_TimeoutConfig { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(8)) + } + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_TimeoutConfig) { + let discriminant_ptr: *mut discriminant_TimeoutConfig = (self as *mut TimeoutConfig).cast(); + + unsafe { + *(discriminant_ptr.add(8)) = discriminant; + } + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// A tag named NoTimeout, which has no payload. + pub const NoTimeout: Self = unsafe { + let mut bytes = [0; core::mem::size_of::()]; + + bytes[8] = discriminant_TimeoutConfig::NoTimeout as u8; + + core::mem::transmute::<[u8; core::mem::size_of::()], TimeoutConfig>(bytes) + }; + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Other `into_` methods return a payload, but since the NoTimeout tag + /// has no payload, this does nothing and is only here for completeness. + pub fn into_NoTimeout(self) { + () + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Other `as` methods return a payload, but since the NoTimeout tag + /// has no payload, this does nothing and is only here for completeness. + pub unsafe fn as_NoTimeout(&self) { + () + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Construct a tag named `Timeout`, with the appropriate payload + pub fn Timeout(arg: f64) -> Self { + let mut answer = Self { Timeout: arg }; + + answer.set_discriminant(discriminant_TimeoutConfig::Timeout); + + answer + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `TimeoutConfig` has a `.discriminant()` of `Timeout` and convert it to `Timeout`'s payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `Timeout`. + pub unsafe fn into_Timeout(self) -> f64 { + debug_assert_eq!(self.discriminant(), discriminant_TimeoutConfig::Timeout); + + let payload = self.Timeout; + + payload + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `TimeoutConfig` has a `.discriminant()` of `Timeout` and return its payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `Timeout`. + pub unsafe fn as_Timeout(&self) -> &f64 { + debug_assert_eq!(self.discriminant(), discriminant_TimeoutConfig::Timeout); + + let payload = &self.Timeout; + + &payload + } +} + +impl Drop for TimeoutConfig { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn drop(&mut self) { + // Drop the payloads + match self.discriminant() { + discriminant_TimeoutConfig::NoTimeout => {} + discriminant_TimeoutConfig::Timeout => {} + } + } +} + +impl PartialEq for TimeoutConfig { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn eq(&self, other: &Self) -> bool { + if self.discriminant() != other.discriminant() { + return false; + } + + unsafe { + match self.discriminant() { + discriminant_TimeoutConfig::NoTimeout => true, + discriminant_TimeoutConfig::Timeout => self.Timeout == other.Timeout, + } + } + } +} + +impl PartialOrd for TimeoutConfig { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn partial_cmp(&self, other: &Self) -> Option { + match self.discriminant().partial_cmp(&other.discriminant()) { + Some(core::cmp::Ordering::Equal) => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_TimeoutConfig::NoTimeout => Some(core::cmp::Ordering::Equal), + discriminant_TimeoutConfig::Timeout => self.Timeout.partial_cmp(&other.Timeout), + } + } + } +} + +impl Ord for TimeoutConfig { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + match self.discriminant().cmp(&other.discriminant()) { + core::cmp::Ordering::Equal => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_TimeoutConfig::NoTimeout => core::cmp::Ordering::Equal, + discriminant_TimeoutConfig::Timeout => self.Timeout.cmp(&other.Timeout), + } + } + } +} + +impl Copy for TimeoutConfig {} + +impl Clone for TimeoutConfig { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn clone(&self) -> Self { + let mut answer = unsafe { + match self.discriminant() { + discriminant_TimeoutConfig::NoTimeout => { + core::mem::transmute::, TimeoutConfig>( + core::mem::MaybeUninit::uninit(), + ) + } + discriminant_TimeoutConfig::Timeout => Self { + Timeout: self.Timeout.clone(), + }, + } + }; + + answer.set_discriminant(self.discriminant()); + + answer + } +} + +impl core::hash::Hash for TimeoutConfig { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn hash(&self, state: &mut H) { + match self.discriminant() { + discriminant_TimeoutConfig::NoTimeout => { + discriminant_TimeoutConfig::NoTimeout.hash(state) + } + discriminant_TimeoutConfig::Timeout => unsafe { + discriminant_TimeoutConfig::Timeout.hash(state); + self.Timeout.hash(state); + }, + } + } +} + +impl core::fmt::Debug for TimeoutConfig { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str("TimeoutConfig::")?; + + unsafe { + match self.discriminant() { + discriminant_TimeoutConfig::NoTimeout => f.write_str("NoTimeout"), + discriminant_TimeoutConfig::Timeout => { + f.debug_tuple("Timeout").field(&self.Timeout).finish() + } + } + } + } +} + +impl U1 { + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_U1 { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(11)) + } + } + + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_U1) { + let discriminant_ptr: *mut discriminant_U1 = (self as *mut U1).cast(); + + unsafe { + *(discriminant_ptr.add(11)) = discriminant; + } + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Construct a tag named `MimeType`, with the appropriate payload + pub fn MimeType(arg: roc_std::RocStr) -> Self { + let mut answer = Self { + MimeType: core::mem::ManuallyDrop::new(arg), + }; + + answer.set_discriminant(discriminant_U1::MimeType); + + answer + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `U1` has a `.discriminant()` of `MimeType` and convert it to `MimeType`'s payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `MimeType`. + pub unsafe fn into_MimeType(mut self) -> roc_std::RocStr { + debug_assert_eq!(self.discriminant(), discriminant_U1::MimeType); + + let payload = core::mem::ManuallyDrop::take(&mut self.MimeType); + + payload + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `U1` has a `.discriminant()` of `MimeType` and return its payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `MimeType`. + pub unsafe fn as_MimeType(&self) -> &roc_std::RocStr { + debug_assert_eq!(self.discriminant(), discriminant_U1::MimeType); + + let payload = &self.MimeType; + + &payload + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_U1 { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(23)) + } + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_U1) { + let discriminant_ptr: *mut discriminant_U1 = (self as *mut U1).cast(); + + unsafe { + *(discriminant_ptr.add(23)) = discriminant; + } + } +} + +impl Drop for U1 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn drop(&mut self) { + // Drop the payloads + match self.discriminant() { + discriminant_U1::MimeType => unsafe { + core::mem::ManuallyDrop::drop(&mut self.MimeType) + }, + } + } +} + +impl Eq for U1 {} + +impl PartialEq for U1 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn eq(&self, other: &Self) -> bool { + if self.discriminant() != other.discriminant() { + return false; + } + + unsafe { + match self.discriminant() { + discriminant_U1::MimeType => self.MimeType == other.MimeType, + } + } + } +} + +impl PartialOrd for U1 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn partial_cmp(&self, other: &Self) -> Option { + match self.discriminant().partial_cmp(&other.discriminant()) { + Some(core::cmp::Ordering::Equal) => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_U1::MimeType => self.MimeType.partial_cmp(&other.MimeType), + } + } + } +} + +impl Ord for U1 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + match self.discriminant().cmp(&other.discriminant()) { + core::cmp::Ordering::Equal => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_U1::MimeType => self.MimeType.cmp(&other.MimeType), + } + } + } +} + +impl Clone for U1 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn clone(&self) -> Self { + let mut answer = unsafe { + match self.discriminant() { + discriminant_U1::MimeType => Self { + MimeType: self.MimeType.clone(), + }, + } + }; + + answer.set_discriminant(self.discriminant()); + + answer + } +} + +impl core::hash::Hash for U1 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn hash(&self, state: &mut H) { + match self.discriminant() { + discriminant_U1::MimeType => unsafe { + discriminant_U1::MimeType.hash(state); + self.MimeType.hash(state); + }, + } + } +} + +impl core::fmt::Debug for U1 { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str("U1::")?; + + unsafe { + match self.discriminant() { + discriminant_U1::MimeType => { + f.debug_tuple("MimeType").field(&*self.MimeType).finish() + } + } + } + } +} From 13018497b7fc01939e4362ed692e40d4c8477139 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sat, 16 Jul 2022 22:39:20 +0100 Subject: [PATCH 25/45] Manual fixes for bindgen code --- examples/interactive/cli-platform/src/glue.rs | 110 +++++++++++------- 1 file changed, 68 insertions(+), 42 deletions(-) diff --git a/examples/interactive/cli-platform/src/glue.rs b/examples/interactive/cli-platform/src/glue.rs index 3d76796a62..c52f78c4e0 100644 --- a/examples/interactive/cli-platform/src/glue.rs +++ b/examples/interactive/cli-platform/src/glue.rs @@ -4356,30 +4356,49 @@ impl PartialOrd for TimeoutConfig { } } -impl Ord for TimeoutConfig { - #[cfg(any( - target_arch = "arm", - target_arch = "aarch64", - target_arch = "wasm32", - target_arch = "x86", - target_arch = "x86_64" - ))] - fn cmp(&self, other: &Self) -> core::cmp::Ordering { - match self.discriminant().cmp(&other.discriminant()) { - core::cmp::Ordering::Equal => {} - not_eq => return not_eq, - } +/* +error[E0277]: the trait bound `TimeoutConfig: std::cmp::Eq` is not satisfied + --> src/glue.rs:4359:6 + | +4359 | impl Ord for TimeoutConfig { + | ^^^ the trait `std::cmp::Eq` is not implemented for `TimeoutConfig` + | +note: required by a bound in `Ord` + --> /nix/store/bfi7mh9z423f9bz8qh4zx8x5nxsipsz0-rust-default-1.61.0/lib/rustlib/src/rust/library/core/src/cmp.rs:764:16 + | +764 | pub trait Ord: Eq + PartialOrd { + | ^^ required by this bound in `Ord` + */ +// impl Ord for TimeoutConfig { +// #[cfg(any( +// target_arch = "arm", +// target_arch = "aarch64", +// target_arch = "wasm32", +// target_arch = "x86", +// target_arch = "x86_64" +// ))] +// fn cmp(&self, other: &Self) -> core::cmp::Ordering { +// match self.discriminant().cmp(&other.discriminant()) { +// core::cmp::Ordering::Equal => {} +// not_eq => return not_eq, +// } - unsafe { - match self.discriminant() { - discriminant_TimeoutConfig::NoTimeout => core::cmp::Ordering::Equal, - discriminant_TimeoutConfig::Timeout => self.Timeout.cmp(&other.Timeout), - } - } - } -} +// unsafe { +// match self.discriminant() { +// discriminant_TimeoutConfig::NoTimeout => core::cmp::Ordering::Equal, +// discriminant_TimeoutConfig::Timeout => self.Timeout.cmp(&other.Timeout), +// } +// } +// } +// } -impl Copy for TimeoutConfig {} +/* +error[E0184]: the trait `Copy` may not be implemented for this type; the type has a destructor + --> src/glue.rs:4642:1 + | +4642 | impl Copy for TimeoutConfig {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Copy not allowed on types with destructors +*/ impl Clone for TimeoutConfig { #[cfg(any( @@ -4409,26 +4428,33 @@ impl Clone for TimeoutConfig { } } -impl core::hash::Hash for TimeoutConfig { - #[cfg(any( - target_arch = "arm", - target_arch = "aarch64", - target_arch = "wasm32", - target_arch = "x86", - target_arch = "x86_64" - ))] - fn hash(&self, state: &mut H) { - match self.discriminant() { - discriminant_TimeoutConfig::NoTimeout => { - discriminant_TimeoutConfig::NoTimeout.hash(state) - } - discriminant_TimeoutConfig::Timeout => unsafe { - discriminant_TimeoutConfig::Timeout.hash(state); - self.Timeout.hash(state); - }, - } - } -} +/* +error[E0599]: no method named `hash` found for type `f64` in the current scope + --> src/glue.rs:4446:30 + | +4446 | self.Timeout.hash(state); + | ^^^^ method not found in `f64` +*/ +// impl core::hash::Hash for TimeoutConfig { +// #[cfg(any( +// target_arch = "arm", +// target_arch = "aarch64", +// target_arch = "wasm32", +// target_arch = "x86", +// target_arch = "x86_64" +// ))] +// fn hash(&self, state: &mut H) { +// match self.discriminant() { +// discriminant_TimeoutConfig::NoTimeout => { +// discriminant_TimeoutConfig::NoTimeout.hash(state) +// } +// discriminant_TimeoutConfig::Timeout => unsafe { +// discriminant_TimeoutConfig::Timeout.hash(state); +// self.Timeout.hash(state); +// }, +// } +// } +// } impl core::fmt::Debug for TimeoutConfig { #[cfg(any( From 1d99a63c592e2365294af485fc1d8805eddc83ab Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sat, 16 Jul 2022 22:40:29 +0100 Subject: [PATCH 26/45] Fix Roc compile errors in http-get.roc --- examples/interactive/http-get.roc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/interactive/http-get.roc b/examples/interactive/http-get.roc index 22444c14dd..9f213bcd39 100644 --- a/examples/interactive/http-get.roc +++ b/examples/interactive/http-get.roc @@ -1,11 +1,12 @@ app "http-get" packages { pf: "cli-platform/main.roc" } - imports [pf.Http, pf.HttpTypes, pf.Task, pf.Stdout] + imports [pf.Http, pf.Task, pf.Stdout] provides [main] to pf main : Task.Task {} [] [Write [Stdout], Network [Http]] main = - Http.send { Http.defaultRequest & url: "https://httpbin.org/get" } - |> Task.onFail (\err -> err |> Http.errorToString |> Task.succeed) - |> Task.await - |> Stdout.line + output <- Http.send { Http.defaultRequest & url: "https://httpbin.org/get" } + |> Task.onFail (\err -> err |> Http.errorToString |> Task.succeed) + |> Task.await + + Stdout.line output From 9aba821e828d999c02c14bb80a7a605f813fb5e5 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sat, 16 Jul 2022 23:52:59 +0100 Subject: [PATCH 27/45] Workaround a compile error with defaultRequest by.. not using it! --- examples/interactive/http-get.roc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/examples/interactive/http-get.roc b/examples/interactive/http-get.roc index 9f213bcd39..272ef47e8c 100644 --- a/examples/interactive/http-get.roc +++ b/examples/interactive/http-get.roc @@ -5,7 +5,17 @@ app "http-get" main : Task.Task {} [] [Write [Stdout], Network [Http]] main = - output <- Http.send { Http.defaultRequest & url: "https://httpbin.org/get" } + request = { + method: "GET", + headers: [], + url: "https://httpbin.org/get", + body: Http.emptyBody, + timeout: NoTimeout, + tracker: NoTracker, + allowCookiesFromOtherDomains: False, + } + + output <- Http.send request |> Task.onFail (\err -> err |> Http.errorToString |> Task.succeed) |> Task.await From 33d8e12d31848e490f17d087a1f3889098eca646 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sun, 17 Jul 2022 09:30:04 +0100 Subject: [PATCH 28/45] Http example is running! Not debugged yet. --- examples/interactive/.gitignore | 1 + examples/interactive/cli-platform/src/lib.rs | 47 ++------------------ 2 files changed, 4 insertions(+), 44 deletions(-) diff --git a/examples/interactive/.gitignore b/examples/interactive/.gitignore index a36aa49837..cb41e998d8 100644 --- a/examples/interactive/.gitignore +++ b/examples/interactive/.gitignore @@ -3,3 +3,4 @@ echo effects form tui +http-get diff --git a/examples/interactive/cli-platform/src/lib.rs b/examples/interactive/cli-platform/src/lib.rs index eb163df187..ae6a23f53c 100644 --- a/examples/interactive/cli-platform/src/lib.rs +++ b/examples/interactive/cli-platform/src/lib.rs @@ -129,17 +129,7 @@ pub extern "C" fn roc_fx_putLine(line: &RocStr) { } #[no_mangle] -pub extern "C" fn roc_fx_send_request(roc_request: &glue::Request) -> glue::Response { - // let (mimetype, body_bytes_slice): (String, Vec) = match roc_request.body.discriminant() { - // glue::discriminant_Body::EmptyBody => ("".into(), vec![]), - // glue::discriminant_Body::Body => { - // let (mimetype_union, body_roclist) = unsafe { roc_request.body.as_Body() }; - // let mimetype_string: String = unsafe { mimetype_union.as_MimeType() }.as_str().into(); - // let body_bytes: &[u8] = body_roclist.as_slice(); - // (mimetype_string, Vec::from(body_bytes)) - // } - // }; - +pub extern "C" fn roc_fx_sendRequest(roc_request: &glue::Request) -> glue::Response { let url = roc_request.url.as_str(); match ureq::get(url).call() { Ok(response) => { @@ -174,43 +164,12 @@ pub extern "C" fn roc_fx_send_request(roc_request: &glue::Request) -> glue::Resp glue::Response::BadStatus(metadata, body) } - Err(transortError) => { + Err(transportError) => { use ureq::ErrorKind::*; - match transortError.kind() { + match transportError.kind() { InvalidUrl | UnknownScheme => glue::Response::BadUrl(RocStr::from(url)), _ => glue::Response::NetworkError, } } } } - -/* -pub enum Error { - Status(u16, Response), - Transport(Transport), -} -match ureq::get("http://mypage.example.com/").call() { - Ok(response) => { /* it worked */}, - Err(Error::Status(code, response)) => { - /* the server returned an unexpected status - code (such as 400, 500 etc) */ - } - Err(_) => { /* some kind of io/transport error */ } -} - -enum ErrorKind { - InvalidUrl, - UnknownScheme, - Dns, - InsecureRequestHttpsOnly, - ConnectionFailed, - TooManyRedirects, - BadStatus, - BadHeader, - Io, - InvalidProxyUrl, - ProxyConnect, - ProxyUnauthorized, - HTTP, -} -*/ From 535c2b1c584d554cf6bc6e2e777abfe74fdceaf6 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sun, 17 Jul 2022 09:43:59 +0100 Subject: [PATCH 29/45] reproduce unhandled parse error --- examples/interactive/http-get.roc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/interactive/http-get.roc b/examples/interactive/http-get.roc index 272ef47e8c..5ff723cc34 100644 --- a/examples/interactive/http-get.roc +++ b/examples/interactive/http-get.roc @@ -5,15 +5,15 @@ app "http-get" main : Task.Task {} [] [Write [Stdout], Network [Http]] main = - request = { - method: "GET", - headers: [], - url: "https://httpbin.org/get", - body: Http.emptyBody, - timeout: NoTimeout, - tracker: NoTracker, - allowCookiesFromOtherDomains: False, - } + method = "GET", + headers = [{name: "Favourite-Colour", value: "Mauve"}], + url = "https://httpbin.org/get", + body = Http.stringBody (MimeType "text/plain") "Hello, I am the body text", + timeout = Timeout 1.0, + tracker = Tracker "some-progress-tracking-identifier", + allowCookiesFromOtherDomains = True, + + request = { method, headers, url, body, timeout, tracker, allowCookiesFromOtherDomains } output <- Http.send request |> Task.onFail (\err -> err |> Http.errorToString |> Task.succeed) From 2b8466d427136adee63500c7ab2673da4777267a Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sun, 17 Jul 2022 09:44:37 +0100 Subject: [PATCH 30/45] Revert "reproduce unhandled parse error" This reverts commit 9e44dedfbb3aab98ab872afea76d0c8a0aac1679. --- examples/interactive/http-get.roc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/interactive/http-get.roc b/examples/interactive/http-get.roc index 5ff723cc34..272ef47e8c 100644 --- a/examples/interactive/http-get.roc +++ b/examples/interactive/http-get.roc @@ -5,15 +5,15 @@ app "http-get" main : Task.Task {} [] [Write [Stdout], Network [Http]] main = - method = "GET", - headers = [{name: "Favourite-Colour", value: "Mauve"}], - url = "https://httpbin.org/get", - body = Http.stringBody (MimeType "text/plain") "Hello, I am the body text", - timeout = Timeout 1.0, - tracker = Tracker "some-progress-tracking-identifier", - allowCookiesFromOtherDomains = True, - - request = { method, headers, url, body, timeout, tracker, allowCookiesFromOtherDomains } + request = { + method: "GET", + headers: [], + url: "https://httpbin.org/get", + body: Http.emptyBody, + timeout: NoTimeout, + tracker: NoTracker, + allowCookiesFromOtherDomains: False, + } output <- Http.send request |> Task.onFail (\err -> err |> Http.errorToString |> Task.succeed) From f1e88e8af6512beedec1c23383150cf741a08996 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sun, 17 Jul 2022 10:01:54 +0100 Subject: [PATCH 31/45] Use a tag instead of record for Http Header. Nicer in real usage. --- examples/interactive/cli-platform/Http.roc | 4 ++-- examples/interactive/cli-platform/HttpTypes.roc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/interactive/cli-platform/Http.roc b/examples/interactive/cli-platform/Http.roc index d7d09e2ba0..8fbc089e64 100644 --- a/examples/interactive/cli-platform/Http.roc +++ b/examples/interactive/cli-platform/Http.roc @@ -37,8 +37,8 @@ defaultRequest = { ## [here](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields). ## header : Str, Str -> Header -header = \name, value -> - { name, value } +header = + Header emptyBody : Body emptyBody = diff --git a/examples/interactive/cli-platform/HttpTypes.roc b/examples/interactive/cli-platform/HttpTypes.roc index dee449d263..c64cb99b5d 100644 --- a/examples/interactive/cli-platform/HttpTypes.roc +++ b/examples/interactive/cli-platform/HttpTypes.roc @@ -12,7 +12,7 @@ Request : { allowCookiesFromOtherDomains : Bool, } -Header : { name : Str, value : Str } +Header : [Header Str Str] TimeoutConfig : [Timeout F64, NoTimeout] TrackerConfig : [Tracker Str, NoTracker] From 48aa248813c771d541902252957768d433aad592 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sun, 17 Jul 2022 10:04:17 +0100 Subject: [PATCH 32/45] Use non-empty values for all fields in Request example, to debug host interface --- examples/interactive/http-get.roc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/interactive/http-get.roc b/examples/interactive/http-get.roc index 272ef47e8c..f270d6bcd0 100644 --- a/examples/interactive/http-get.roc +++ b/examples/interactive/http-get.roc @@ -7,12 +7,12 @@ main : Task.Task {} [] [Write [Stdout], Network [Http]] main = request = { method: "GET", - headers: [], + headers: [Header "Favourite-Colour" "Mauve"], url: "https://httpbin.org/get", - body: Http.emptyBody, - timeout: NoTimeout, - tracker: NoTracker, - allowCookiesFromOtherDomains: False, + body: Http.stringBody (MimeType "text/plain") "Hello, I am the body text", + timeout: Timeout 1.0, + tracker: Tracker "some-progress-tracking-identifier", + allowCookiesFromOtherDomains: True, } output <- Http.send request From a4e4dc84b155b11648c942e9ce252a66f5061f8b Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sun, 17 Jul 2022 10:21:02 +0100 Subject: [PATCH 33/45] Change Method type to a tag union --- examples/interactive/cli-platform/Http.roc | 4 ++-- examples/interactive/cli-platform/HttpTypes.roc | 6 ++++-- examples/interactive/http-get.roc | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/examples/interactive/cli-platform/Http.roc b/examples/interactive/cli-platform/Http.roc index 8fbc089e64..77e64646ef 100644 --- a/examples/interactive/cli-platform/Http.roc +++ b/examples/interactive/cli-platform/Http.roc @@ -19,12 +19,12 @@ interface Http # Json, Task.{ Task }, # Encode.{ Encoding }, - HttpTypes.{ Request, Header, TimeoutConfig, TrackerConfig, Part, Body, Response, Metadata, Error }, + HttpTypes.{ Request, Method, Header, TimeoutConfig, TrackerConfig, Part, Body, Response, Metadata, Error }, ] defaultRequest : Request defaultRequest = { - method: "GET", + method: Get, headers: [], url: "", body: Http.emptyBody, diff --git a/examples/interactive/cli-platform/HttpTypes.roc b/examples/interactive/cli-platform/HttpTypes.roc index c64cb99b5d..fa5836ca46 100644 --- a/examples/interactive/cli-platform/HttpTypes.roc +++ b/examples/interactive/cli-platform/HttpTypes.roc @@ -1,9 +1,9 @@ interface HttpTypes - exposes [Request, Header, TimeoutConfig, TrackerConfig, Part, Body, Response, Metadata, Error] + exposes [Request, Method, Header, TimeoutConfig, TrackerConfig, Part, Body, Response, Metadata, Error] imports [] Request : { - method : Str, + method : Method, headers : List Header, url : Str, body : Body, @@ -12,6 +12,8 @@ Request : { allowCookiesFromOtherDomains : Bool, } +Method : [Options, Get, Post, Put, Delete, Head, Trace, Connect, Patch] + Header : [Header Str Str] TimeoutConfig : [Timeout F64, NoTimeout] diff --git a/examples/interactive/http-get.roc b/examples/interactive/http-get.roc index f270d6bcd0..6985af596e 100644 --- a/examples/interactive/http-get.roc +++ b/examples/interactive/http-get.roc @@ -6,7 +6,7 @@ app "http-get" main : Task.Task {} [] [Write [Stdout], Network [Http]] main = request = { - method: "GET", + method: Get, headers: [Header "Favourite-Colour" "Mauve"], url: "https://httpbin.org/get", body: Http.stringBody (MimeType "text/plain") "Hello, I am the body text", From 3c506eb79cbd0c3b424933ab0fda9467ed99b2a2 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sun, 17 Jul 2022 10:21:25 +0100 Subject: [PATCH 34/45] Update bindgen glue code --- examples/interactive/cli-platform/src/glue.rs | 333 +++++++++++++++++- 1 file changed, 324 insertions(+), 9 deletions(-) diff --git a/examples/interactive/cli-platform/src/glue.rs b/examples/interactive/cli-platform/src/glue.rs index c52f78c4e0..f0f7d04c85 100644 --- a/examples/interactive/cli-platform/src/glue.rs +++ b/examples/interactive/cli-platform/src/glue.rs @@ -85,11 +85,30 @@ pub union Part { target_arch = "x86", target_arch = "x86_64" ))] -#[derive(Clone, Debug, Default, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[derive(Clone, Copy, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[repr(u8)] +pub enum discriminant_Header { + Header = 0, +} + +impl core::fmt::Debug for discriminant_Header { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::Header => f.write_str("discriminant_Header::Header"), + } + } +} + +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] #[repr(C)] -pub struct Header { - pub name: roc_std::RocStr, - pub value: roc_std::RocStr, +pub union Header { + Header: core::mem::ManuallyDrop, } #[cfg(any( @@ -237,11 +256,11 @@ pub union Response { pub struct Request { pub body: Body, pub headers: roc_std::RocList
, - pub method: roc_std::RocStr, pub timeout: TimeoutConfig, pub tracker: TrackerConfig, pub url: roc_std::RocStr, pub allowCookiesFromOtherDomains: bool, + pub method: Method, } #[cfg(any( @@ -430,7 +449,7 @@ struct Part_Part { target_arch = "x86", target_arch = "x86_64" ))] -#[derive(Clone, Debug, Default, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[derive(Clone, Debug, Eq, Ord, Hash, PartialEq, PartialOrd)] #[repr(C)] struct Response_GoodStatus { pub f0: Metadata, @@ -444,7 +463,7 @@ struct Response_GoodStatus { target_arch = "x86", target_arch = "x86_64" ))] -#[derive(Clone, Debug, Default, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[derive(Clone, Debug, Eq, Ord, Hash, PartialEq, PartialOrd)] #[repr(C)] struct Response_BadStatus { pub f0: Metadata, @@ -458,7 +477,7 @@ struct Response_BadStatus { target_arch = "x86", target_arch = "x86_64" ))] -#[derive(Clone, Debug, Default, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[derive(Clone, Debug, Eq, Ord, Hash, PartialEq, PartialOrd)] #[repr(C)] pub struct Metadata { pub headers: roc_std::RocList
, @@ -467,6 +486,43 @@ pub struct Metadata { pub statusCode: u16, } +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[derive(Clone, Copy, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[repr(u8)] +pub enum Method { + Connect = 0, + Delete = 1, + Get = 2, + Head = 3, + Options = 4, + Patch = 5, + Post = 6, + Put = 7, + Trace = 8, +} + +impl core::fmt::Debug for Method { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::Connect => f.write_str("Method::Connect"), + Self::Delete => f.write_str("Method::Delete"), + Self::Get => f.write_str("Method::Get"), + Self::Head => f.write_str("Method::Head"), + Self::Options => f.write_str("Method::Options"), + Self::Patch => f.write_str("Method::Patch"), + Self::Post => f.write_str("Method::Post"), + Self::Put => f.write_str("Method::Put"), + Self::Trace => f.write_str("Method::Trace"), + } + } +} + #[cfg(any( target_arch = "arm", target_arch = "aarch64", @@ -527,6 +583,20 @@ pub union TimeoutConfig { _sizer: [u8; 12], } +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" +))] +#[derive(Clone, Debug, Default, Eq, Ord, Hash, PartialEq, PartialOrd)] +#[repr(C)] +struct Header_Header { + pub f0: roc_std::RocStr, + pub f1: roc_std::RocStr, +} + #[cfg(any( target_arch = "arm", target_arch = "aarch64", @@ -624,10 +694,10 @@ pub struct Request { pub timeout: TimeoutConfig, pub body: Body, pub headers: roc_std::RocList
, - pub method: roc_std::RocStr, pub tracker: TrackerConfig, pub url: roc_std::RocStr, pub allowCookiesFromOtherDomains: bool, + pub method: Method, } impl Error { @@ -1363,6 +1433,251 @@ impl core::fmt::Debug for Part { } } +impl Header { + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_Header { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(23)) + } + } + + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_Header) { + let discriminant_ptr: *mut discriminant_Header = (self as *mut Header).cast(); + + unsafe { + *(discriminant_ptr.add(23)) = discriminant; + } + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Construct a tag named `Header`, with the appropriate payload + pub fn Header(arg0: roc_std::RocStr, arg1: roc_std::RocStr) -> Self { + let mut answer = Self { + Header: core::mem::ManuallyDrop::new(Header_Header { f0: arg0, f1: arg1 }), + }; + + answer.set_discriminant(discriminant_Header::Header); + + answer + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `Header` has a `.discriminant()` of `Header` and convert it to `Header`'s payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `Header`. + pub unsafe fn into_Header(mut self) -> (roc_std::RocStr, roc_std::RocStr) { + debug_assert_eq!(self.discriminant(), discriminant_Header::Header); + + let payload = core::mem::ManuallyDrop::take(&mut self.Header); + + (payload.f0, payload.f1) + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `Header` has a `.discriminant()` of `Header` and return its payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `Header`. + pub unsafe fn as_Header(&self) -> (&roc_std::RocStr, &roc_std::RocStr) { + debug_assert_eq!(self.discriminant(), discriminant_Header::Header); + + let payload = &self.Header; + + (&payload.f0, &payload.f1) + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_Header { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(47)) + } + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_Header) { + let discriminant_ptr: *mut discriminant_Header = (self as *mut Header).cast(); + + unsafe { + *(discriminant_ptr.add(47)) = discriminant; + } + } +} + +impl Drop for Header { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn drop(&mut self) { + // Drop the payloads + match self.discriminant() { + discriminant_Header::Header => unsafe { + core::mem::ManuallyDrop::drop(&mut self.Header) + }, + } + } +} + +impl Eq for Header {} + +impl PartialEq for Header { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn eq(&self, other: &Self) -> bool { + if self.discriminant() != other.discriminant() { + return false; + } + + unsafe { + match self.discriminant() { + discriminant_Header::Header => self.Header == other.Header, + } + } + } +} + +impl PartialOrd for Header { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn partial_cmp(&self, other: &Self) -> Option { + match self.discriminant().partial_cmp(&other.discriminant()) { + Some(core::cmp::Ordering::Equal) => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_Header::Header => self.Header.partial_cmp(&other.Header), + } + } + } +} + +impl Ord for Header { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + match self.discriminant().cmp(&other.discriminant()) { + core::cmp::Ordering::Equal => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_Header::Header => self.Header.cmp(&other.Header), + } + } + } +} + +impl Clone for Header { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn clone(&self) -> Self { + let mut answer = unsafe { + match self.discriminant() { + discriminant_Header::Header => Self { + Header: self.Header.clone(), + }, + } + }; + + answer.set_discriminant(self.discriminant()); + + answer + } +} + +impl core::hash::Hash for Header { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn hash(&self, state: &mut H) { + match self.discriminant() { + discriminant_Header::Header => unsafe { + discriminant_Header::Header.hash(state); + self.Header.hash(state); + }, + } + } +} + +impl core::fmt::Debug for Header { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str("Header::")?; + + unsafe { + match self.discriminant() { + discriminant_Header::Header => f + .debug_tuple("Header") + .field(&(&*self.Header).f0) + .field(&(&*self.Header).f1) + .finish(), + } + } + } +} + impl U5 { #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] /// Returns which variant this tag union holds. Note that this never includes a payload! From c50cbd265a43572020998494093cd56054e59a42 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sun, 17 Jul 2022 15:19:16 +0100 Subject: [PATCH 35/45] Wrap a record in Box before passing it to the host, to work around an ABI issue --- examples/interactive/cli-platform/Effect.roc | 2 +- examples/interactive/cli-platform/Http.roc | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/interactive/cli-platform/Effect.roc b/examples/interactive/cli-platform/Effect.roc index e29fd147a3..ee482c1f53 100644 --- a/examples/interactive/cli-platform/Effect.roc +++ b/examples/interactive/cli-platform/Effect.roc @@ -7,4 +7,4 @@ putLine : Str -> Effect {} getLine : Effect Str -sendRequest : Request -> Effect Response +sendRequest : Box Request -> Effect Response diff --git a/examples/interactive/cli-platform/Http.roc b/examples/interactive/cli-platform/Http.roc index 77e64646ef..5d22bbced3 100644 --- a/examples/interactive/cli-platform/Http.roc +++ b/examples/interactive/cli-platform/Http.roc @@ -104,6 +104,7 @@ errorToString = \err -> send : Request -> Task Str Error [Network [Http]*]* send = \req -> - Effect.sendRequest req + # TODO: Fix our C ABI codegen so that we don't this Box.box heap allocation + Effect.sendRequest (Box.box req) |> Effect.map handleStringResponse |> InternalTask.fromEffect From 8cf7752514b129828fe9d3e4d604881977e447f4 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sun, 17 Jul 2022 15:26:08 +0100 Subject: [PATCH 36/45] Improve a debug assert message (triggered by unnecessary import of Box) --- crates/compiler/load_internal/src/work.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/compiler/load_internal/src/work.rs b/crates/compiler/load_internal/src/work.rs index b0e5b2c8ce..6c2226f6cb 100644 --- a/crates/compiler/load_internal/src/work.rs +++ b/crates/compiler/load_internal/src/work.rs @@ -64,7 +64,8 @@ impl MakeSpecializationsDependents { let entry = self.entry(module_id); debug_assert!( entry.succ.is_empty(), - "already added successors for this module" + "already added successors for module '{:?}'", + module_id ); entry.succ.extend(succ.into_iter()); From b84aac098eb9a76bc337fe80ac2f6e931be8771a Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sun, 17 Jul 2022 16:24:46 +0100 Subject: [PATCH 37/45] Tidy up reading the Response body bytes --- examples/interactive/cli-platform/src/lib.rs | 29 +++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/examples/interactive/cli-platform/src/lib.rs b/examples/interactive/cli-platform/src/lib.rs index ae6a23f53c..844ff87b6d 100644 --- a/examples/interactive/cli-platform/src/lib.rs +++ b/examples/interactive/cli-platform/src/lib.rs @@ -128,17 +128,38 @@ pub extern "C" fn roc_fx_putLine(line: &RocStr) { println!("{}", string); } +const BODY_MAX_BYTES: usize = 10 * 1024 * 1024; + #[no_mangle] pub extern "C" fn roc_fx_sendRequest(roc_request: &glue::Request) -> glue::Response { + use std::io::Read; + let url = roc_request.url.as_str(); match ureq::get(url).call() { Ok(response) => { let statusCode = response.status(); - let mut buffer: Vec = vec![]; - let mut reader = response.into_reader(); - reader.read(&mut buffer).expect("can't read response"); - let body = RocList::from_slice(&buffer); + let len: usize = response + .header("Content-Length") + .and_then(|val| val.parse::().ok()) + .map(|val| val.max(BODY_MAX_BYTES)) + .unwrap_or(BODY_MAX_BYTES); + + let mut bytes: Vec = Vec::with_capacity(len); + match response + .into_reader() + .take(len as u64) + .read_to_end(&mut bytes) + { + Ok(_read_bytes) => {} + Err(_) => { + // Not totally accurate, but let's deal with this later when we do async + return glue::Response::NetworkError; + } + } + + // Note: we could skip a full memcpy if we had `RocList::from_iter`. + let body = RocList::from_slice(&bytes); let metadata = Metadata { headers: RocList::empty(), From b0e8951e6b11f72535cc49b4fa6cdc6b1ed9c413 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sun, 17 Jul 2022 16:26:36 +0100 Subject: [PATCH 38/45] Add some TODO comments --- examples/interactive/cli-platform/src/lib.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/interactive/cli-platform/src/lib.rs b/examples/interactive/cli-platform/src/lib.rs index 844ff87b6d..65aa24aae9 100644 --- a/examples/interactive/cli-platform/src/lib.rs +++ b/examples/interactive/cli-platform/src/lib.rs @@ -162,9 +162,9 @@ pub extern "C" fn roc_fx_sendRequest(roc_request: &glue::Request) -> glue::Respo let body = RocList::from_slice(&bytes); let metadata = Metadata { - headers: RocList::empty(), - statusText: RocStr::empty(), - url: RocStr::empty(), + headers: RocList::empty(), // TODO + statusText: RocStr::empty(), // TODO + url: RocStr::empty(), // TODO statusCode, }; @@ -177,9 +177,9 @@ pub extern "C" fn roc_fx_sendRequest(roc_request: &glue::Request) -> glue::Respo let body = RocList::from_slice(&buffer); let metadata = Metadata { - headers: RocList::empty(), - statusText: RocStr::empty(), - url: RocStr::empty(), + headers: RocList::empty(), // TODO + statusText: RocStr::empty(), // TODO + url: RocStr::empty(), // TODO statusCode, }; From bcfd50724fb6e0434a9352afca49348fcf6829d8 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sun, 17 Jul 2022 16:39:17 +0100 Subject: [PATCH 39/45] More cleanup on Http platform & app --- examples/interactive/cli-platform/Http.roc | 4 ++-- .../interactive/cli-platform/HttpTypes.roc | 11 +++++----- examples/interactive/http-get.roc | 20 +++++++++++-------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/examples/interactive/cli-platform/Http.roc b/examples/interactive/cli-platform/Http.roc index 5d22bbced3..5e8dd37988 100644 --- a/examples/interactive/cli-platform/Http.roc +++ b/examples/interactive/cli-platform/Http.roc @@ -19,7 +19,7 @@ interface Http # Json, Task.{ Task }, # Encode.{ Encoding }, - HttpTypes.{ Request, Method, Header, TimeoutConfig, TrackerConfig, Part, Body, Response, Metadata, Error }, + HttpTypes.{ Request, Method, Header, Timeout, ProgressTracking, Part, Body, Response, Metadata, Error }, ] defaultRequest : Request @@ -29,7 +29,7 @@ defaultRequest = { url: "", body: Http.emptyBody, timeout: NoTimeout, - tracker: NoTracker, + progressTracking: NoProgressTracking, allowCookiesFromOtherDomains: False, } diff --git a/examples/interactive/cli-platform/HttpTypes.roc b/examples/interactive/cli-platform/HttpTypes.roc index fa5836ca46..3685d8fed0 100644 --- a/examples/interactive/cli-platform/HttpTypes.roc +++ b/examples/interactive/cli-platform/HttpTypes.roc @@ -1,5 +1,5 @@ interface HttpTypes - exposes [Request, Method, Header, TimeoutConfig, TrackerConfig, Part, Body, Response, Metadata, Error] + exposes [Request, Method, Header, Timeout, ProgressTracking, Part, Body, Response, Metadata, Error] imports [] Request : { @@ -7,8 +7,8 @@ Request : { headers : List Header, url : Str, body : Body, - timeout : TimeoutConfig, - tracker : TrackerConfig, + timeout : Timeout, + progressTracking : ProgressTracking, allowCookiesFromOtherDomains : Bool, } @@ -16,8 +16,9 @@ Method : [Options, Get, Post, Put, Delete, Head, Trace, Connect, Patch] Header : [Header Str Str] -TimeoutConfig : [Timeout F64, NoTimeout] -TrackerConfig : [Tracker Str, NoTracker] +Timeout : [Timeout F64, NoTimeout] + +ProgressTracking : [ProgressTrackingId Str, NoProgressTracking] Part : [Part Str (List U8)] diff --git a/examples/interactive/http-get.roc b/examples/interactive/http-get.roc index 6985af596e..f9e103adaa 100644 --- a/examples/interactive/http-get.roc +++ b/examples/interactive/http-get.roc @@ -1,18 +1,22 @@ app "http-get" packages { pf: "cli-platform/main.roc" } - imports [pf.Http, pf.Task, pf.Stdout] + imports [pf.Http, pf.Task, pf.Stdin, pf.Stdout] provides [main] to pf -main : Task.Task {} [] [Write [Stdout], Network [Http]] +main : Task.Task {} [] [Read [Stdin], Write [Stdout], Network [Http]] main = + _ <- Task.await (Stdout.line "Please enter a URL to fetch") + + url <- Task.await Stdin.line + request = { method: Get, - headers: [Header "Favourite-Colour" "Mauve"], - url: "https://httpbin.org/get", - body: Http.stringBody (MimeType "text/plain") "Hello, I am the body text", - timeout: Timeout 1.0, - tracker: Tracker "some-progress-tracking-identifier", - allowCookiesFromOtherDomains: True, + headers: [], + url, + body: Http.emptyBody, + timeout: NoTimeout, + progressTracking: NoProgressTracking, + allowCookiesFromOtherDomains: False, } output <- Http.send request From e7c26ae3b1eb16487c4237ce7f40913ff688601f Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sun, 17 Jul 2022 16:45:52 +0100 Subject: [PATCH 40/45] Regenerate glue code for cli-platform --- examples/interactive/cli-platform/src/glue.rs | 815 +++++++++--------- 1 file changed, 415 insertions(+), 400 deletions(-) diff --git a/examples/interactive/cli-platform/src/glue.rs b/examples/interactive/cli-platform/src/glue.rs index f0f7d04c85..444112716e 100644 --- a/examples/interactive/cli-platform/src/glue.rs +++ b/examples/interactive/cli-platform/src/glue.rs @@ -256,8 +256,8 @@ pub union Response { pub struct Request { pub body: Body, pub headers: roc_std::RocList
, - pub timeout: TimeoutConfig, - pub tracker: TrackerConfig, + pub progressTracking: ProgressTracking, + pub timeout: Timeout, pub url: roc_std::RocStr, pub allowCookiesFromOtherDomains: bool, pub method: Method, @@ -532,25 +532,25 @@ impl core::fmt::Debug for Method { ))] #[derive(Clone, Copy, Eq, Ord, Hash, PartialEq, PartialOrd)] #[repr(u8)] -pub enum discriminant_TrackerConfig { - NoTracker = 0, - Tracker = 1, +pub enum discriminant_Timeout { + NoTimeout = 0, + Timeout = 1, } -impl core::fmt::Debug for discriminant_TrackerConfig { +impl core::fmt::Debug for discriminant_Timeout { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { - Self::NoTracker => f.write_str("discriminant_TrackerConfig::NoTracker"), - Self::Tracker => f.write_str("discriminant_TrackerConfig::Tracker"), + Self::NoTimeout => f.write_str("discriminant_Timeout::NoTimeout"), + Self::Timeout => f.write_str("discriminant_Timeout::Timeout"), } } } -#[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] +#[cfg(any(target_arch = "arm", target_arch = "x86"))] #[repr(C)] -pub union TrackerConfig { - Tracker: core::mem::ManuallyDrop, - _sizer: [u8; 16], +pub union Timeout { + Timeout: f64, + _sizer: [u8; 12], } #[cfg(any( @@ -562,25 +562,29 @@ pub union TrackerConfig { ))] #[derive(Clone, Copy, Eq, Ord, Hash, PartialEq, PartialOrd)] #[repr(u8)] -pub enum discriminant_TimeoutConfig { - NoTimeout = 0, - Timeout = 1, +pub enum discriminant_ProgressTracking { + NoProgressTracking = 0, + ProgressTrackingId = 1, } -impl core::fmt::Debug for discriminant_TimeoutConfig { +impl core::fmt::Debug for discriminant_ProgressTracking { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { - Self::NoTimeout => f.write_str("discriminant_TimeoutConfig::NoTimeout"), - Self::Timeout => f.write_str("discriminant_TimeoutConfig::Timeout"), + Self::NoProgressTracking => { + f.write_str("discriminant_ProgressTracking::NoProgressTracking") + } + Self::ProgressTrackingId => { + f.write_str("discriminant_ProgressTracking::ProgressTrackingId") + } } } } -#[cfg(any(target_arch = "arm", target_arch = "x86"))] +#[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] #[repr(C)] -pub union TimeoutConfig { - Timeout: f64, - _sizer: [u8; 12], +pub union ProgressTracking { + ProgressTrackingId: core::mem::ManuallyDrop, + _sizer: [u8; 16], } #[cfg(any( @@ -669,32 +673,32 @@ pub union Response { _sizer: [u8; 112], } -#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] -#[repr(C)] -pub union TrackerConfig { - Tracker: core::mem::ManuallyDrop, - _sizer: [u8; 32], -} - #[cfg(any( target_arch = "aarch64", target_arch = "wasm32", target_arch = "x86_64" ))] #[repr(C)] -pub union TimeoutConfig { +pub union Timeout { Timeout: f64, _sizer: [u8; 16], } +#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] +#[repr(C)] +pub union ProgressTracking { + ProgressTrackingId: core::mem::ManuallyDrop, + _sizer: [u8; 32], +} + #[cfg(target_arch = "wasm32")] #[derive(Clone, Debug, PartialEq, PartialOrd)] #[repr(C)] pub struct Request { - pub timeout: TimeoutConfig, + pub timeout: Timeout, pub body: Body, pub headers: roc_std::RocList
, - pub tracker: TrackerConfig, + pub progressTracking: ProgressTracking, pub url: roc_std::RocStr, pub allowCookiesFromOtherDomains: bool, pub method: Method, @@ -4179,309 +4183,7 @@ impl core::fmt::Debug for U2 { } } -impl TrackerConfig { - #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] - /// Returns which variant this tag union holds. Note that this never includes a payload! - pub fn discriminant(&self) -> discriminant_TrackerConfig { - unsafe { - let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); - - core::mem::transmute::(*bytes.as_ptr().add(12)) - } - } - - #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] - /// Internal helper - fn set_discriminant(&mut self, discriminant: discriminant_TrackerConfig) { - let discriminant_ptr: *mut discriminant_TrackerConfig = (self as *mut TrackerConfig).cast(); - - unsafe { - *(discriminant_ptr.add(12)) = discriminant; - } - } - - #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] - /// A tag named NoTracker, which has no payload. - pub const NoTracker: Self = unsafe { - let mut bytes = [0; core::mem::size_of::()]; - - bytes[12] = discriminant_TrackerConfig::NoTracker as u8; - - core::mem::transmute::<[u8; core::mem::size_of::()], TrackerConfig>(bytes) - }; - - #[cfg(any( - target_arch = "arm", - target_arch = "aarch64", - target_arch = "wasm32", - target_arch = "x86", - target_arch = "x86_64" - ))] - /// Other `into_` methods return a payload, but since the NoTracker tag - /// has no payload, this does nothing and is only here for completeness. - pub fn into_NoTracker(self) { - () - } - - #[cfg(any( - target_arch = "arm", - target_arch = "aarch64", - target_arch = "wasm32", - target_arch = "x86", - target_arch = "x86_64" - ))] - /// Other `as` methods return a payload, but since the NoTracker tag - /// has no payload, this does nothing and is only here for completeness. - pub unsafe fn as_NoTracker(&self) { - () - } - - #[cfg(any( - target_arch = "arm", - target_arch = "aarch64", - target_arch = "wasm32", - target_arch = "x86", - target_arch = "x86_64" - ))] - /// Construct a tag named `Tracker`, with the appropriate payload - pub fn Tracker(arg: roc_std::RocStr) -> Self { - let mut answer = Self { - Tracker: core::mem::ManuallyDrop::new(arg), - }; - - answer.set_discriminant(discriminant_TrackerConfig::Tracker); - - answer - } - - #[cfg(any( - target_arch = "arm", - target_arch = "aarch64", - target_arch = "wasm32", - target_arch = "x86", - target_arch = "x86_64" - ))] - /// Unsafely assume the given `TrackerConfig` has a `.discriminant()` of `Tracker` and convert it to `Tracker`'s payload. - /// (Always examine `.discriminant()` first to make sure this is the correct variant!) - /// Panics in debug builds if the `.discriminant()` doesn't return `Tracker`. - pub unsafe fn into_Tracker(mut self) -> roc_std::RocStr { - debug_assert_eq!(self.discriminant(), discriminant_TrackerConfig::Tracker); - - let payload = core::mem::ManuallyDrop::take(&mut self.Tracker); - - payload - } - - #[cfg(any( - target_arch = "arm", - target_arch = "aarch64", - target_arch = "wasm32", - target_arch = "x86", - target_arch = "x86_64" - ))] - /// Unsafely assume the given `TrackerConfig` has a `.discriminant()` of `Tracker` and return its payload. - /// (Always examine `.discriminant()` first to make sure this is the correct variant!) - /// Panics in debug builds if the `.discriminant()` doesn't return `Tracker`. - pub unsafe fn as_Tracker(&self) -> &roc_std::RocStr { - debug_assert_eq!(self.discriminant(), discriminant_TrackerConfig::Tracker); - - let payload = &self.Tracker; - - &payload - } - - #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] - /// Returns which variant this tag union holds. Note that this never includes a payload! - pub fn discriminant(&self) -> discriminant_TrackerConfig { - unsafe { - let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); - - core::mem::transmute::(*bytes.as_ptr().add(24)) - } - } - - #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] - /// Internal helper - fn set_discriminant(&mut self, discriminant: discriminant_TrackerConfig) { - let discriminant_ptr: *mut discriminant_TrackerConfig = (self as *mut TrackerConfig).cast(); - - unsafe { - *(discriminant_ptr.add(24)) = discriminant; - } - } - - #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] - /// A tag named NoTracker, which has no payload. - pub const NoTracker: Self = unsafe { - let mut bytes = [0; core::mem::size_of::()]; - - bytes[24] = discriminant_TrackerConfig::NoTracker as u8; - - core::mem::transmute::<[u8; core::mem::size_of::()], TrackerConfig>(bytes) - }; -} - -impl Drop for TrackerConfig { - #[cfg(any( - target_arch = "arm", - target_arch = "aarch64", - target_arch = "wasm32", - target_arch = "x86", - target_arch = "x86_64" - ))] - fn drop(&mut self) { - // Drop the payloads - match self.discriminant() { - discriminant_TrackerConfig::NoTracker => {} - discriminant_TrackerConfig::Tracker => unsafe { - core::mem::ManuallyDrop::drop(&mut self.Tracker) - }, - } - } -} - -impl Eq for TrackerConfig {} - -impl PartialEq for TrackerConfig { - #[cfg(any( - target_arch = "arm", - target_arch = "aarch64", - target_arch = "wasm32", - target_arch = "x86", - target_arch = "x86_64" - ))] - fn eq(&self, other: &Self) -> bool { - if self.discriminant() != other.discriminant() { - return false; - } - - unsafe { - match self.discriminant() { - discriminant_TrackerConfig::NoTracker => true, - discriminant_TrackerConfig::Tracker => self.Tracker == other.Tracker, - } - } - } -} - -impl PartialOrd for TrackerConfig { - #[cfg(any( - target_arch = "arm", - target_arch = "aarch64", - target_arch = "wasm32", - target_arch = "x86", - target_arch = "x86_64" - ))] - fn partial_cmp(&self, other: &Self) -> Option { - match self.discriminant().partial_cmp(&other.discriminant()) { - Some(core::cmp::Ordering::Equal) => {} - not_eq => return not_eq, - } - - unsafe { - match self.discriminant() { - discriminant_TrackerConfig::NoTracker => Some(core::cmp::Ordering::Equal), - discriminant_TrackerConfig::Tracker => self.Tracker.partial_cmp(&other.Tracker), - } - } - } -} - -impl Ord for TrackerConfig { - #[cfg(any( - target_arch = "arm", - target_arch = "aarch64", - target_arch = "wasm32", - target_arch = "x86", - target_arch = "x86_64" - ))] - fn cmp(&self, other: &Self) -> core::cmp::Ordering { - match self.discriminant().cmp(&other.discriminant()) { - core::cmp::Ordering::Equal => {} - not_eq => return not_eq, - } - - unsafe { - match self.discriminant() { - discriminant_TrackerConfig::NoTracker => core::cmp::Ordering::Equal, - discriminant_TrackerConfig::Tracker => self.Tracker.cmp(&other.Tracker), - } - } - } -} - -impl Clone for TrackerConfig { - #[cfg(any( - target_arch = "arm", - target_arch = "aarch64", - target_arch = "wasm32", - target_arch = "x86", - target_arch = "x86_64" - ))] - fn clone(&self) -> Self { - let mut answer = unsafe { - match self.discriminant() { - discriminant_TrackerConfig::NoTracker => { - core::mem::transmute::, TrackerConfig>( - core::mem::MaybeUninit::uninit(), - ) - } - discriminant_TrackerConfig::Tracker => Self { - Tracker: self.Tracker.clone(), - }, - } - }; - - answer.set_discriminant(self.discriminant()); - - answer - } -} - -impl core::hash::Hash for TrackerConfig { - #[cfg(any( - target_arch = "arm", - target_arch = "aarch64", - target_arch = "wasm32", - target_arch = "x86", - target_arch = "x86_64" - ))] - fn hash(&self, state: &mut H) { - match self.discriminant() { - discriminant_TrackerConfig::NoTracker => { - discriminant_TrackerConfig::NoTracker.hash(state) - } - discriminant_TrackerConfig::Tracker => unsafe { - discriminant_TrackerConfig::Tracker.hash(state); - self.Tracker.hash(state); - }, - } - } -} - -impl core::fmt::Debug for TrackerConfig { - #[cfg(any( - target_arch = "arm", - target_arch = "aarch64", - target_arch = "wasm32", - target_arch = "x86", - target_arch = "x86_64" - ))] - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_str("TrackerConfig::")?; - - unsafe { - match self.discriminant() { - discriminant_TrackerConfig::NoTracker => f.write_str("NoTracker"), - discriminant_TrackerConfig::Tracker => { - f.debug_tuple("Tracker").field(&*self.Tracker).finish() - } - } - } - } -} - -impl TimeoutConfig { +impl Timeout { #[cfg(any( target_arch = "arm", target_arch = "aarch64", @@ -4490,11 +4192,11 @@ impl TimeoutConfig { target_arch = "x86_64" ))] /// Returns which variant this tag union holds. Note that this never includes a payload! - pub fn discriminant(&self) -> discriminant_TimeoutConfig { + pub fn discriminant(&self) -> discriminant_Timeout { unsafe { let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); - core::mem::transmute::(*bytes.as_ptr().add(8)) + core::mem::transmute::(*bytes.as_ptr().add(8)) } } @@ -4506,8 +4208,8 @@ impl TimeoutConfig { target_arch = "x86_64" ))] /// Internal helper - fn set_discriminant(&mut self, discriminant: discriminant_TimeoutConfig) { - let discriminant_ptr: *mut discriminant_TimeoutConfig = (self as *mut TimeoutConfig).cast(); + fn set_discriminant(&mut self, discriminant: discriminant_Timeout) { + let discriminant_ptr: *mut discriminant_Timeout = (self as *mut Timeout).cast(); unsafe { *(discriminant_ptr.add(8)) = discriminant; @@ -4523,11 +4225,11 @@ impl TimeoutConfig { ))] /// A tag named NoTimeout, which has no payload. pub const NoTimeout: Self = unsafe { - let mut bytes = [0; core::mem::size_of::()]; + let mut bytes = [0; core::mem::size_of::()]; - bytes[8] = discriminant_TimeoutConfig::NoTimeout as u8; + bytes[8] = discriminant_Timeout::NoTimeout as u8; - core::mem::transmute::<[u8; core::mem::size_of::()], TimeoutConfig>(bytes) + core::mem::transmute::<[u8; core::mem::size_of::()], Timeout>(bytes) }; #[cfg(any( @@ -4567,7 +4269,7 @@ impl TimeoutConfig { pub fn Timeout(arg: f64) -> Self { let mut answer = Self { Timeout: arg }; - answer.set_discriminant(discriminant_TimeoutConfig::Timeout); + answer.set_discriminant(discriminant_Timeout::Timeout); answer } @@ -4579,11 +4281,11 @@ impl TimeoutConfig { target_arch = "x86", target_arch = "x86_64" ))] - /// Unsafely assume the given `TimeoutConfig` has a `.discriminant()` of `Timeout` and convert it to `Timeout`'s payload. + /// Unsafely assume the given `Timeout` has a `.discriminant()` of `Timeout` and convert it to `Timeout`'s payload. /// (Always examine `.discriminant()` first to make sure this is the correct variant!) /// Panics in debug builds if the `.discriminant()` doesn't return `Timeout`. pub unsafe fn into_Timeout(self) -> f64 { - debug_assert_eq!(self.discriminant(), discriminant_TimeoutConfig::Timeout); + debug_assert_eq!(self.discriminant(), discriminant_Timeout::Timeout); let payload = self.Timeout; @@ -4597,11 +4299,11 @@ impl TimeoutConfig { target_arch = "x86", target_arch = "x86_64" ))] - /// Unsafely assume the given `TimeoutConfig` has a `.discriminant()` of `Timeout` and return its payload. + /// Unsafely assume the given `Timeout` has a `.discriminant()` of `Timeout` and return its payload. /// (Always examine `.discriminant()` first to make sure this is the correct variant!) /// Panics in debug builds if the `.discriminant()` doesn't return `Timeout`. pub unsafe fn as_Timeout(&self) -> &f64 { - debug_assert_eq!(self.discriminant(), discriminant_TimeoutConfig::Timeout); + debug_assert_eq!(self.discriminant(), discriminant_Timeout::Timeout); let payload = &self.Timeout; @@ -4609,7 +4311,7 @@ impl TimeoutConfig { } } -impl Drop for TimeoutConfig { +impl Drop for Timeout { #[cfg(any( target_arch = "arm", target_arch = "aarch64", @@ -4620,13 +4322,13 @@ impl Drop for TimeoutConfig { fn drop(&mut self) { // Drop the payloads match self.discriminant() { - discriminant_TimeoutConfig::NoTimeout => {} - discriminant_TimeoutConfig::Timeout => {} + discriminant_Timeout::NoTimeout => {} + discriminant_Timeout::Timeout => {} } } } -impl PartialEq for TimeoutConfig { +impl PartialEq for Timeout { #[cfg(any( target_arch = "arm", target_arch = "aarch64", @@ -4641,14 +4343,14 @@ impl PartialEq for TimeoutConfig { unsafe { match self.discriminant() { - discriminant_TimeoutConfig::NoTimeout => true, - discriminant_TimeoutConfig::Timeout => self.Timeout == other.Timeout, + discriminant_Timeout::NoTimeout => true, + discriminant_Timeout::Timeout => self.Timeout == other.Timeout, } } } } -impl PartialOrd for TimeoutConfig { +impl PartialOrd for Timeout { #[cfg(any( target_arch = "arm", target_arch = "aarch64", @@ -4664,27 +4366,22 @@ impl PartialOrd for TimeoutConfig { unsafe { match self.discriminant() { - discriminant_TimeoutConfig::NoTimeout => Some(core::cmp::Ordering::Equal), - discriminant_TimeoutConfig::Timeout => self.Timeout.partial_cmp(&other.Timeout), + discriminant_Timeout::NoTimeout => Some(core::cmp::Ordering::Equal), + discriminant_Timeout::Timeout => self.Timeout.partial_cmp(&other.Timeout), } } } } -/* -error[E0277]: the trait bound `TimeoutConfig: std::cmp::Eq` is not satisfied - --> src/glue.rs:4359:6 - | -4359 | impl Ord for TimeoutConfig { - | ^^^ the trait `std::cmp::Eq` is not implemented for `TimeoutConfig` - | -note: required by a bound in `Ord` - --> /nix/store/bfi7mh9z423f9bz8qh4zx8x5nxsipsz0-rust-default-1.61.0/lib/rustlib/src/rust/library/core/src/cmp.rs:764:16 - | -764 | pub trait Ord: Eq + PartialOrd { - | ^^ required by this bound in `Ord` - */ -// impl Ord for TimeoutConfig { +// error[E0184]: the trait `Copy` may not be implemented for this type; the type has a destructor +// --> src/glue.rs:4399:1 +// | +// 4399 | impl Copy for Timeout {} +// | ^^^^^^^^^^^^^^^^^^^^^^^^ Copy not allowed on types with destructors +// +// For more information about this error, try `rustc --explain E0184`. +// +// impl Ord for Timeout { // #[cfg(any( // target_arch = "arm", // target_arch = "aarch64", @@ -4700,22 +4397,16 @@ note: required by a bound in `Ord` // unsafe { // match self.discriminant() { -// discriminant_TimeoutConfig::NoTimeout => core::cmp::Ordering::Equal, -// discriminant_TimeoutConfig::Timeout => self.Timeout.cmp(&other.Timeout), +// discriminant_Timeout::NoTimeout => core::cmp::Ordering::Equal, +// discriminant_Timeout::Timeout => self.Timeout.cmp(&other.Timeout), // } // } // } // } -/* -error[E0184]: the trait `Copy` may not be implemented for this type; the type has a destructor - --> src/glue.rs:4642:1 - | -4642 | impl Copy for TimeoutConfig {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Copy not allowed on types with destructors -*/ +// impl Copy for Timeout {} -impl Clone for TimeoutConfig { +impl Clone for Timeout { #[cfg(any( target_arch = "arm", target_arch = "aarch64", @@ -4726,12 +4417,12 @@ impl Clone for TimeoutConfig { fn clone(&self) -> Self { let mut answer = unsafe { match self.discriminant() { - discriminant_TimeoutConfig::NoTimeout => { - core::mem::transmute::, TimeoutConfig>( + discriminant_Timeout::NoTimeout => { + core::mem::transmute::, Timeout>( core::mem::MaybeUninit::uninit(), ) } - discriminant_TimeoutConfig::Timeout => Self { + discriminant_Timeout::Timeout => Self { Timeout: self.Timeout.clone(), }, } @@ -4743,14 +4434,15 @@ impl Clone for TimeoutConfig { } } -/* -error[E0599]: no method named `hash` found for type `f64` in the current scope - --> src/glue.rs:4446:30 - | -4446 | self.Timeout.hash(state); - | ^^^^ method not found in `f64` -*/ -// impl core::hash::Hash for TimeoutConfig { +// error[E0599]: no method named `hash` found for type `f64` in the current scope +// --> src/glue.rs:4450:30 +// | +// 4450 | self.Timeout.hash(state); +// | ^^^^ method not found in `f64` +// +// For more information about this error, try `rustc --explain E0599`. +// +// impl core::hash::Hash for Timeout { // #[cfg(any( // target_arch = "arm", // target_arch = "aarch64", @@ -4760,18 +4452,16 @@ error[E0599]: no method named `hash` found for type `f64` in the current scope // ))] // fn hash(&self, state: &mut H) { // match self.discriminant() { -// discriminant_TimeoutConfig::NoTimeout => { -// discriminant_TimeoutConfig::NoTimeout.hash(state) -// } -// discriminant_TimeoutConfig::Timeout => unsafe { -// discriminant_TimeoutConfig::Timeout.hash(state); +// discriminant_Timeout::NoTimeout => discriminant_Timeout::NoTimeout.hash(state), +// discriminant_Timeout::Timeout => unsafe { +// discriminant_Timeout::Timeout.hash(state); // self.Timeout.hash(state); // }, // } // } // } -impl core::fmt::Debug for TimeoutConfig { +impl core::fmt::Debug for Timeout { #[cfg(any( target_arch = "arm", target_arch = "aarch64", @@ -4780,12 +4470,12 @@ impl core::fmt::Debug for TimeoutConfig { target_arch = "x86_64" ))] fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_str("TimeoutConfig::")?; + f.write_str("Timeout::")?; unsafe { match self.discriminant() { - discriminant_TimeoutConfig::NoTimeout => f.write_str("NoTimeout"), - discriminant_TimeoutConfig::Timeout => { + discriminant_Timeout::NoTimeout => f.write_str("NoTimeout"), + discriminant_Timeout::Timeout => { f.debug_tuple("Timeout").field(&self.Timeout).finish() } } @@ -4793,6 +4483,331 @@ impl core::fmt::Debug for TimeoutConfig { } } +impl ProgressTracking { + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_ProgressTracking { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(12)) + } + } + + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_ProgressTracking) { + let discriminant_ptr: *mut discriminant_ProgressTracking = + (self as *mut ProgressTracking).cast(); + + unsafe { + *(discriminant_ptr.add(12)) = discriminant; + } + } + + #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] + /// A tag named NoProgressTracking, which has no payload. + pub const NoProgressTracking: Self = unsafe { + let mut bytes = [0; core::mem::size_of::()]; + + bytes[12] = discriminant_ProgressTracking::NoProgressTracking as u8; + + core::mem::transmute::<[u8; core::mem::size_of::()], ProgressTracking>( + bytes, + ) + }; + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Other `into_` methods return a payload, but since the NoProgressTracking tag + /// has no payload, this does nothing and is only here for completeness. + pub fn into_NoProgressTracking(self) { + () + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Other `as` methods return a payload, but since the NoProgressTracking tag + /// has no payload, this does nothing and is only here for completeness. + pub unsafe fn as_NoProgressTracking(&self) { + () + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Construct a tag named `ProgressTrackingId`, with the appropriate payload + pub fn ProgressTrackingId(arg: roc_std::RocStr) -> Self { + let mut answer = Self { + ProgressTrackingId: core::mem::ManuallyDrop::new(arg), + }; + + answer.set_discriminant(discriminant_ProgressTracking::ProgressTrackingId); + + answer + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `ProgressTracking` has a `.discriminant()` of `ProgressTrackingId` and convert it to `ProgressTrackingId`'s payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `ProgressTrackingId`. + pub unsafe fn into_ProgressTrackingId(mut self) -> roc_std::RocStr { + debug_assert_eq!( + self.discriminant(), + discriminant_ProgressTracking::ProgressTrackingId + ); + + let payload = core::mem::ManuallyDrop::take(&mut self.ProgressTrackingId); + + payload + } + + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + /// Unsafely assume the given `ProgressTracking` has a `.discriminant()` of `ProgressTrackingId` and return its payload. + /// (Always examine `.discriminant()` first to make sure this is the correct variant!) + /// Panics in debug builds if the `.discriminant()` doesn't return `ProgressTrackingId`. + pub unsafe fn as_ProgressTrackingId(&self) -> &roc_std::RocStr { + debug_assert_eq!( + self.discriminant(), + discriminant_ProgressTracking::ProgressTrackingId + ); + + let payload = &self.ProgressTrackingId; + + &payload + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Returns which variant this tag union holds. Note that this never includes a payload! + pub fn discriminant(&self) -> discriminant_ProgressTracking { + unsafe { + let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::()]>(self); + + core::mem::transmute::(*bytes.as_ptr().add(24)) + } + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// Internal helper + fn set_discriminant(&mut self, discriminant: discriminant_ProgressTracking) { + let discriminant_ptr: *mut discriminant_ProgressTracking = + (self as *mut ProgressTracking).cast(); + + unsafe { + *(discriminant_ptr.add(24)) = discriminant; + } + } + + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] + /// A tag named NoProgressTracking, which has no payload. + pub const NoProgressTracking: Self = unsafe { + let mut bytes = [0; core::mem::size_of::()]; + + bytes[24] = discriminant_ProgressTracking::NoProgressTracking as u8; + + core::mem::transmute::<[u8; core::mem::size_of::()], ProgressTracking>( + bytes, + ) + }; +} + +impl Drop for ProgressTracking { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn drop(&mut self) { + // Drop the payloads + match self.discriminant() { + discriminant_ProgressTracking::NoProgressTracking => {} + discriminant_ProgressTracking::ProgressTrackingId => unsafe { + core::mem::ManuallyDrop::drop(&mut self.ProgressTrackingId) + }, + } + } +} + +impl Eq for ProgressTracking {} + +impl PartialEq for ProgressTracking { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn eq(&self, other: &Self) -> bool { + if self.discriminant() != other.discriminant() { + return false; + } + + unsafe { + match self.discriminant() { + discriminant_ProgressTracking::NoProgressTracking => true, + discriminant_ProgressTracking::ProgressTrackingId => { + self.ProgressTrackingId == other.ProgressTrackingId + } + } + } + } +} + +impl PartialOrd for ProgressTracking { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn partial_cmp(&self, other: &Self) -> Option { + match self.discriminant().partial_cmp(&other.discriminant()) { + Some(core::cmp::Ordering::Equal) => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_ProgressTracking::NoProgressTracking => { + Some(core::cmp::Ordering::Equal) + } + discriminant_ProgressTracking::ProgressTrackingId => self + .ProgressTrackingId + .partial_cmp(&other.ProgressTrackingId), + } + } + } +} + +impl Ord for ProgressTracking { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + match self.discriminant().cmp(&other.discriminant()) { + core::cmp::Ordering::Equal => {} + not_eq => return not_eq, + } + + unsafe { + match self.discriminant() { + discriminant_ProgressTracking::NoProgressTracking => core::cmp::Ordering::Equal, + discriminant_ProgressTracking::ProgressTrackingId => { + self.ProgressTrackingId.cmp(&other.ProgressTrackingId) + } + } + } + } +} + +impl Clone for ProgressTracking { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn clone(&self) -> Self { + let mut answer = unsafe { + match self.discriminant() { + discriminant_ProgressTracking::NoProgressTracking => { + core::mem::transmute::, ProgressTracking>( + core::mem::MaybeUninit::uninit(), + ) + } + discriminant_ProgressTracking::ProgressTrackingId => Self { + ProgressTrackingId: self.ProgressTrackingId.clone(), + }, + } + }; + + answer.set_discriminant(self.discriminant()); + + answer + } +} + +impl core::hash::Hash for ProgressTracking { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn hash(&self, state: &mut H) { + match self.discriminant() { + discriminant_ProgressTracking::NoProgressTracking => { + discriminant_ProgressTracking::NoProgressTracking.hash(state) + } + discriminant_ProgressTracking::ProgressTrackingId => unsafe { + discriminant_ProgressTracking::ProgressTrackingId.hash(state); + self.ProgressTrackingId.hash(state); + }, + } + } +} + +impl core::fmt::Debug for ProgressTracking { + #[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "wasm32", + target_arch = "x86", + target_arch = "x86_64" + ))] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str("ProgressTracking::")?; + + unsafe { + match self.discriminant() { + discriminant_ProgressTracking::NoProgressTracking => { + f.write_str("NoProgressTracking") + } + discriminant_ProgressTracking::ProgressTrackingId => f + .debug_tuple("ProgressTrackingId") + .field(&*self.ProgressTrackingId) + .finish(), + } + } + } +} + impl U1 { #[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))] /// Returns which variant this tag union holds. Note that this never includes a payload! From 530f153301d6282ca889e06e70e4fcb9f30d6dcf Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Mon, 18 Jul 2022 08:15:47 +0100 Subject: [PATCH 41/45] update Cargo.toml --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 02d6153877..3ee6691d04 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3772,7 +3772,7 @@ dependencies = [ "clap 3.2.11", "iced-x86", "mach_object", - "memmap2 0.5.4", + "memmap2 0.5.5", "object 0.26.2", "roc_build", "roc_collections", From 16af6fc297b633960efbebcbf07a6ff2325b8b90 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Mon, 18 Jul 2022 18:26:49 +0100 Subject: [PATCH 42/45] Format Http.roc --- examples/interactive/cli-platform/Http.roc | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/interactive/cli-platform/Http.roc b/examples/interactive/cli-platform/Http.roc index 5e8dd37988..2ab0b2cd04 100644 --- a/examples/interactive/cli-platform/Http.roc +++ b/examples/interactive/cli-platform/Http.roc @@ -62,10 +62,10 @@ multiPartBody = \parts -> afterName = Str.toUtf8 "\"\r\n" appendPart = \buffer, Part name partBytes -> buffer - |> List.concat beforeName - |> List.concat (Str.toUtf8 name) - |> List.concat afterName - |> List.concat partBytes + |> List.concat beforeName + |> List.concat (Str.toUtf8 name) + |> List.concat afterName + |> List.concat partBytes bodyBytes = List.walk parts [] appendPart Body (MimeType "multipart/form-data;boundary=\"\(boundary)\"") bodyBytes @@ -87,11 +87,11 @@ handleStringResponse = \response -> BadStatus metadata _ -> Err (BadStatus metadata.statusCode) GoodStatus _ bodyBytes -> Str.fromUtf8 bodyBytes - |> Result.mapErr - \BadUtf8 _ pos -> - position = Num.toStr pos + |> Result.mapErr + \BadUtf8 _ pos -> + position = Num.toStr pos - BadBody "Invalid UTF-8 at byte offset \(position)" + BadBody "Invalid UTF-8 at byte offset \(position)" errorToString : Error -> Str errorToString = \err -> @@ -106,5 +106,5 @@ send : Request -> Task Str Error [Network [Http]*]* send = \req -> # TODO: Fix our C ABI codegen so that we don't this Box.box heap allocation Effect.sendRequest (Box.box req) - |> Effect.map handleStringResponse - |> InternalTask.fromEffect + |> Effect.map handleStringResponse + |> InternalTask.fromEffect From c35318dbfb897e83d24807f5741ab33a7e2a5087 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Mon, 18 Jul 2022 21:04:12 +0100 Subject: [PATCH 43/45] formatting --- examples/interactive/http-get.roc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/interactive/http-get.roc b/examples/interactive/http-get.roc index f9e103adaa..70d93bf8a0 100644 --- a/examples/interactive/http-get.roc +++ b/examples/interactive/http-get.roc @@ -20,7 +20,7 @@ main = } output <- Http.send request - |> Task.onFail (\err -> err |> Http.errorToString |> Task.succeed) - |> Task.await + |> Task.onFail (\err -> err |> Http.errorToString |> Task.succeed) + |> Task.await Stdout.line output From e1bf4a317a10a7fc5f7550866437b407c2689024 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Mon, 18 Jul 2022 23:16:54 +0100 Subject: [PATCH 44/45] Re-export Http types from the Http module itself --- examples/interactive/cli-platform/Effect.roc | 2 +- examples/interactive/cli-platform/Http.roc | 31 +++++++++++++------ .../{HttpTypes.roc => InternalHttp.roc} | 2 +- 3 files changed, 24 insertions(+), 11 deletions(-) rename examples/interactive/cli-platform/{HttpTypes.roc => InternalHttp.roc} (97%) diff --git a/examples/interactive/cli-platform/Effect.roc b/examples/interactive/cli-platform/Effect.roc index ee482c1f53..3ae9806fc4 100644 --- a/examples/interactive/cli-platform/Effect.roc +++ b/examples/interactive/cli-platform/Effect.roc @@ -1,6 +1,6 @@ hosted Effect exposes [Effect, after, map, always, forever, loop, putLine, getLine, sendRequest] - imports [HttpTypes.{ Request, Response }] + imports [InternalHttp.{ Request, Response }] generates Effect with [after, map, always, forever, loop] putLine : Str -> Effect {} diff --git a/examples/interactive/cli-platform/Http.roc b/examples/interactive/cli-platform/Http.roc index 2ab0b2cd04..85f12a7ee9 100644 --- a/examples/interactive/cli-platform/Http.roc +++ b/examples/interactive/cli-platform/Http.roc @@ -1,10 +1,19 @@ interface Http exposes [ + Request, + Method, + Header, + Timeout, + ProgressTracking, + Part, + Body, + Response, + Metadata, + Error, header, emptyBody, bytesBody, stringBody, - # jsonBody, multiPartBody, stringPart, bytesPart, @@ -13,14 +22,18 @@ interface Http errorToString, send, ] - imports [ - Effect, - InternalTask, - # Json, - Task.{ Task }, - # Encode.{ Encoding }, - HttpTypes.{ Request, Method, Header, Timeout, ProgressTracking, Part, Body, Response, Metadata, Error }, - ] + imports [Effect, InternalTask, Task.{ Task }, InternalHttp] + +Request : InternalHttp.Request +Method : InternalHttp.Method +Header : InternalHttp.Header +Timeout : InternalHttp.Timeout +ProgressTracking : InternalHttp.ProgressTracking +Part : InternalHttp.Part +Body : InternalHttp.Body +Response : InternalHttp.Response +Metadata : InternalHttp.Metadata +Error : InternalHttp.Error defaultRequest : Request defaultRequest = { diff --git a/examples/interactive/cli-platform/HttpTypes.roc b/examples/interactive/cli-platform/InternalHttp.roc similarity index 97% rename from examples/interactive/cli-platform/HttpTypes.roc rename to examples/interactive/cli-platform/InternalHttp.roc index 3685d8fed0..1811702ffc 100644 --- a/examples/interactive/cli-platform/HttpTypes.roc +++ b/examples/interactive/cli-platform/InternalHttp.roc @@ -1,4 +1,4 @@ -interface HttpTypes +interface InternalHttp exposes [Request, Method, Header, Timeout, ProgressTracking, Part, Body, Response, Metadata, Error] imports [] From 5c94064c7be245cb8160dbae7dae2f56389b1cf8 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Mon, 18 Jul 2022 23:21:24 +0100 Subject: [PATCH 45/45] Remove multiPartBody since it's not implemented properly --- examples/interactive/cli-platform/Http.roc | 48 +++++++++------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/examples/interactive/cli-platform/Http.roc b/examples/interactive/cli-platform/Http.roc index 85f12a7ee9..3368c35a39 100644 --- a/examples/interactive/cli-platform/Http.roc +++ b/examples/interactive/cli-platform/Http.roc @@ -5,7 +5,6 @@ interface Http Header, Timeout, ProgressTracking, - Part, Body, Response, Metadata, @@ -14,9 +13,6 @@ interface Http emptyBody, bytesBody, stringBody, - multiPartBody, - stringPart, - bytesPart, handleStringResponse, defaultRequest, errorToString, @@ -29,7 +25,6 @@ Method : InternalHttp.Method Header : InternalHttp.Header Timeout : InternalHttp.Timeout ProgressTracking : InternalHttp.ProgressTracking -Part : InternalHttp.Part Body : InternalHttp.Body Response : InternalHttp.Response Metadata : InternalHttp.Metadata @@ -68,29 +63,26 @@ stringBody = \mimeType, str -> # jsonBody : a -> Body | a has Encoding # jsonBody = \val -> # Body (MimeType "application/json") (Encode.toBytes val Json.format) -multiPartBody : List Part -> Body -multiPartBody = \parts -> - boundary = "7MA4YWxkTrZu0gW" # TODO: what's this exactly? a hash of all the part bodies? - beforeName = Str.toUtf8 "-- \(boundary)\r\nContent-Disposition: form-data; name=\"" - afterName = Str.toUtf8 "\"\r\n" - appendPart = \buffer, Part name partBytes -> - buffer - |> List.concat beforeName - |> List.concat (Str.toUtf8 name) - |> List.concat afterName - |> List.concat partBytes - bodyBytes = List.walk parts [] appendPart - - Body (MimeType "multipart/form-data;boundary=\"\(boundary)\"") bodyBytes - -bytesPart : Str, List U8 -> Part -bytesPart = - Part - -stringPart : Str, Str -> Part -stringPart = \name, str -> - Part name (Str.toUtf8 str) - +# +# multiPartBody : List Part -> Body +# multiPartBody = \parts -> +# boundary = "7MA4YWxkTrZu0gW" # TODO: what's this exactly? a hash of all the part bodies? +# beforeName = Str.toUtf8 "-- \(boundary)\r\nContent-Disposition: form-data; name=\"" +# afterName = Str.toUtf8 "\"\r\n" +# appendPart = \buffer, Part name partBytes -> +# buffer +# |> List.concat beforeName +# |> List.concat (Str.toUtf8 name) +# |> List.concat afterName +# |> List.concat partBytes +# bodyBytes = List.walk parts [] appendPart +# Body (MimeType "multipart/form-data;boundary=\"\(boundary)\"") bodyBytes +# bytesPart : Str, List U8 -> Part +# bytesPart = +# Part +# stringPart : Str, Str -> Part +# stringPart = \name, str -> +# Part name (Str.toUtf8 str) handleStringResponse : Response -> Result Str Error handleStringResponse = \response -> when response is