Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion quest/m3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,5 @@ generic std gap is planned here even when moq never calls it.
- [A string's exact capacity](/quest/m3/ts-string-capacity.md) - a `String` holds std's capacity, so a program making a `Bytes` of one reads its capacity
- [A B-tree's searches call Ord as std's do](/quest/m3/ts-btree-search-order.md) - a B-tree's lookups and inserts call a key's own `Ord` in std's order and number
- [Every panic of a hooked program has its location](/quest/m3/ts-panic-sites.md) - no panic in a program that sets a hook lacks the location native code gives it
- [A string Cow's variant](/quest/m3/ts-cow-str-variant.md) - matching a `Cow<str>`'s `Borrowed` or `Owned`, and `to_mut`'s change of it, translate as std's
- [The chunk a BufMut lends](/quest/m3/ts-chunk-mut.md) - `BufMut::chunk_mut` and its `UninitSlice`'s writes translate, reaching the buffer's storage
- [Slices not yet written](/quest/m3/ts-uninit-slices.md) - `Box::new_uninit_slice` and `write_clone_of_slice` translate
42 changes: 0 additions & 42 deletions quest/m3/ts-cow-str-variant.md

This file was deleted.

6 changes: 6 additions & 0 deletions ts/MIGRATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## Unreleased

- A `Cow<str>` is an `rt.StrCow`, the string it owns or an `rt.Borrowed` of the one it
borrows, rather than a `string`: read its text with `rt.strCowStr(c)`, and pass a
borrowed one as `new rt.Borrowed(s)` or an owned one as the string. `rt.Borrowed<S>`
takes the type of what it borrows, so a `Cow<[T]>`'s is an `rt.Borrowed<T[]>`.
`rt.stringFromUtf8Lossy` returns an `rt.StrCow`, and `rt.strFromUtf8Unchecked` is the
plain decode it was.
- `rt.handleAllocError`, and a `LocalKey` initialized while it drops, throw `rt.Abort`
rather than an `rt.Panic`, as std aborts there without running the panic hook. An
`rt.Abort` is an `rt.Panic`, so a caller catching one still catches both; one telling
Expand Down
23 changes: 12 additions & 11 deletions ts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ crate translation reaches is refused, and so are two versions of one crate it re

| Rust | TypeScript |
| --- | --- |
| `bool`, `str`, `String`, `Box<str>`, `Cow<str>` | `boolean`, `string` |
| `bool`, `str`, `String`, `Box<str>` | `boolean`, `string` |
| `char` | `rt.char`: a `number` branded so, its Unicode scalar value |
| `u8`-`u32`, `i8`-`i32`, `usize`, `isize` | `rt.u8` and so on: a `number` branded with its type, checked: overflow panics |
| `u64`, `i64`, `u128`, `i128` | `rt.u64` and so on: a branded `number` while a safe integer, 32-bit limbs past 2^53, checked the same way |
Expand All @@ -105,7 +105,7 @@ crate translation reaches is refused, and so are two versions of one crate it re
| `Result<T, E>` | `rt.Result<T, E>`: `{ ok: true, value }` or `{ ok: false, error }`; `rt.OK` or `rt.ERR` where the payload is `undefined`, as in `Ok(())` |
| `ControlFlow<B, C>` | `rt.Result<C, B>`, `Ok` to continue; what `?` branches on is the value it was applied to, but for a `Poll`'s `Pending` and `Ready(None)`, which continue as `Ok` of themselves |
| tuple, `[T; N]`, `&[T]`, `Box<[T]>`, `Vec<T>` | an array; for bytes, `u8` or `MaybeUninit<u8>`, `Uint8Array` for `[u8; N]`, `rt.ByteSlice` for `&[u8]`, `&[u8; N]`, and `Box<[u8]>`, and `rt.ByteVec` for `Vec<u8>` |
| `Cow<[T]>` | `rt.Cow<T>`: the `Vec` it owns, or an `rt.Borrowed` holding the slice it borrows; `rt.ByteCow` for bytes, an `rt.ByteVec` or an `rt.ByteSlice` |
| `Cow<[T]>`, `Cow<str>` | `rt.Cow<T>`: the `Vec` it owns, or an `rt.Borrowed` holding the slice it borrows; `rt.ByteCow` for bytes, an `rt.ByteVec` or an `rt.ByteSlice`; `rt.StrCow` for text, the string it owns or an `rt.Borrowed` holding the one it borrows, which `rt.strCowStr` reads |
| `&T`, `&mut T`, `Box<T>`, `Reverse<T>`, `NonZero<T>`, `AssertUnwindSafe<T>` | the value; a `&mut` to a value JS copies, such as a number, an `Option`, a `String`, or a reference, or to an `Arc`, a `Waker`, or a `LocalKey`, whose copies share what it points at, is an `rt.Place<T>`, which for what a box holds is the place holding the box |
| `*const T`, `*mut T`, `NonNull<T>` | what a `&mut T` is: the object, an `rt.ByteSlice` of a `[u8; N]`'s bytes, which compares by the buffer and offset they are at, or an `rt.Place<T>` to a value JS copies and to a library type such as a `Vec` or an `Arc`, which into an array, slice, or `Vec` is the `rt.AtIndex` of its element, which `add`, `sub`, `offset`, their wrapping forms, `offset_from`, `ptr::copy`, and `slice::from_raw_parts` move, measure, copy between, and view; one to a value in no array is element 0 of an array of one, as in Rust; JS keeps that array, and a shared subslice, which JS copies, apart from what holds it in Rust, so a pointer, slice, or copy the body shows reaching past either, a raw or mutable slice of a byte in no array, and `offset_from` between pointers the body shows JS keeps in different arrays are refused, and through a pointer from elsewhere, such as a field, any of these, or a read or write past the array JS keeps it in, fails at run time; a pointer into an array of values JS keeps as objects is refused, as is comparing pointers to an array of other values than bytes, which a slice lends as a copy of its own; `rt.NULL` for null and `rt.DANGLING` for dangling. A `*const ()` is an identity, such as a waker's data, and `rt.DANGLING_UNIT` when dangling; one to a place of `()` or from a reference to one is refused. A pointer to a value JS keeps as an object cast to one, by `as` or `cast`, is the same object, which `rt.ptrErase` notes the type of, so a cast back to a pointer to another type fails at run time, and null and dangling stay so, dangling at the alignment of the type it was cast from; one to a value JS copies is the same place where an `Arc`'s or `Rc`'s `into_raw` or `as_ptr` gave it, its value's one place, which `rt.arcErase` checks where the body doesn't show it, and refused where the body shows a borrow's, a new place each borrow, as is casting one to a view of bytes, a new one each borrow, or one of no fixed size. A write of a whole object copies into it one object deep, as an assignment through a `&mut` does, the state an `rt` class such as `rt.LazyCell` keeps private included, so a pointer to a part kept as an object, such as a field of a tuple or struct type, is refused wherever the crate may put another object there while a pointer into that memory may still be read, which a write into a fresh allocation, or a variable before any pointer into it is taken, can't, whether by index or through std's iterators over its slots; a read copies what the crate writes into in place |
| `MaybeUninit<T>` | `T`: `undefined` until written, `0` for a byte, or an object whose parts kept as objects are there, holding `undefined` |
Expand Down Expand Up @@ -240,7 +240,7 @@ their lossy forms over bytes, decode as `char::decode_utf16` does: an unpaired s
fails with `rt.FromUtf16Error`, `{ kind }`, its private `FromUtf16ErrorKind`'s name, or
becomes U+FFFD, and so does an odd byte at the end.
`String::from_utf8_lossy` is a `TextDecoder`'s, which writes one U+FFFD for each maximal
invalid sequence, as std's does; its `Cow<str>` is the text either way. `utf8_chunks` splits
invalid sequence, as std's does, and borrows the text of valid UTF-8, as std's does. `utf8_chunks` splits
where `str::from_utf8` fails, so each `Utf8Chunk`'s `invalid` bytes are std's, and `Debug`
of it writes what is left as std's does, each invalid byte as `\xNN`. `from_utf8_unchecked`,
of a `str` or a `String`, decodes as `from_utf8_lossy` does the UTF-8 its contract promises.
Expand Down Expand Up @@ -395,8 +395,8 @@ one `&s[a..b]` or `&s[a..=b]` takes, which reads the string up to it and panics
does inside a char, where `get` gives `None`. A JS string can't change in place, so `String`'s edits, `push_str`, `truncate`,
`insert`, `retain`, `replace_range`, and the rest, assign the edited one to the local or
field the `&mut` borrows, taking and checking byte offsets as std does, and `retain` then
drops its closure. `+`, of a `String` or a `Cow<str>`, is JS's `+` of the moved text, as
`+=` is. A `&mut str` is
drops its closure. `+`, of a `String`, is JS's `+` of the moved text, as `+=` is, and of a
`Cow<str>` takes either side whole when the other is empty, as std's does. A `&mut str` is
the `rt.Place` of its `String` wherever that is, and a part of one, from `&mut s[a..b]`,
`get_mut`, or `split_at_mut`, is `rt.strPart(p, a, b)`, a place of its own that writes the
whole string anew, checking its offsets as `&s[a..b]` does. `as_bytes_mut`,
Expand All @@ -405,12 +405,13 @@ whole string anew, checking its offsets as `&s[a..b]` does. `as_bytes_mut`,
size hint's lower bound, which panics past `isize::MAX`. A `drain` holds the `&mut`'s
place and writes the string without the drained text as it drops, so one that
`mem::forget` leaks leaves it as it was, as std's does. A `String` keeps no capacity:
`with_capacity`, `reserve`, and `shrink_to_fit` do nothing, and `capacity` is refused. A `Cow<str>` is its text, borrowed or owned, so
`to_mut` borrows the `Cow`'s own place, and code that tells its variants apart, a `match`
on them or `Cow::is_borrowed`, is refused. A `Cow<[T]>` keeps its variant in its class,
so a `match` reads it, and `to_mut` of a borrowed one stores a clone of its slice in the
`Cow`'s place before lending it. Its `clone_from` of an owned one over an owned one clones
into the `Vec` it owns, keeping its buffer, as std's does.
`with_capacity`, `reserve`, and `shrink_to_fit` do nothing, and `capacity` is refused. A `Cow` keeps its
variant in its class, so a `match` reads it, and `to_mut` of a borrowed one stores what it
owns in the `Cow`'s place before lending it: a `Cow<[T]>`'s clone of its slice, or a
`Cow<str>`'s text, which a `String` is, so the `&mut` borrows the `Cow`'s own place. A
`Cow<[T]>`'s `clone_from` of an owned one over an owned one clones into the `Vec` it owns,
keeping its buffer, as std's does. `Cow::is_borrowed` and `is_owned` are unstable, and
refused.

Functions and members are camelCase. Functions are monomorphized: each instance is its
own function, suffixed after a `$` by the items it is nested in below its module, its
Expand Down
4 changes: 2 additions & 2 deletions ts/fixtures/lang/boxes/expected/boxes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -612,11 +612,11 @@ export function places(_1: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void {
});
}
if (res.ok) {
res = rt.Ok(rt.u32WrappingMul(res.value, by as rt.u32));
res = { ok: true, value: rt.u32WrappingMul(res.value, by as rt.u32) };
}
const _165: rt.Place<rt.Result<string, rt.u8>> = rt.place(() => said, (value12) => said = value12);
if (_165.v.ok) {
_165.v = rt.Ok(_165.v.value + String.fromCodePoint(rt.u8Add(97, rt.u8Rem(by, 26)) as rt.char));
_165.v = { ok: true, value: _165.v.value + String.fromCodePoint(rt.u8Add(97, rt.u8Rem(by, 26)) as rt.char) };
}
if (rt.usizeRem(i, 5) === 4) {
said = rt.Err(by);
Expand Down
40 changes: 38 additions & 2 deletions ts/fixtures/lang/cows/expected/core/option.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
// Generated by rust2-ts. Do not edit.

import * as rt from "../rt.ts";
import { borrows } from "../cows.ts";

export function unwrapOr$1qh6z5m(self: rt.StrCow | undefined, default_: rt.StrCow): rt.StrCow {
if (self === undefined) {
return default_;
}
return self;
}

export function unwrapOr$1iemzn8(self: string | undefined, default_: string): string {
if (self === undefined) {
Expand All @@ -23,11 +31,39 @@ export function unwrapOr$0r2bmpr(self: rt.u8 | undefined, default_: rt.u8): rt.u
return self;
}

export function map$1uo1d4o(self: string | undefined, _: (a0: string) => string): string | undefined {
export function map$00b7lvf(self: rt.StrCow | undefined, _: (a0: rt.StrCow) => string): string | undefined {
if (self === undefined) {
return undefined;
}
return self;
return rt.strCowStr(self);
}

export function map$1li8gst(self: string | undefined, _: (a0: string) => rt.StrCow): rt.StrCow | undefined {
if (self === undefined) {
return undefined;
}
return new rt.Borrowed(self);
}

export function mapOr$0lcrgk1(self: string | undefined, default_: rt.u8, f: (a0: string) => rt.u8): rt.u8 {
if (self === undefined) {
return default_;
}
return f(self);
}

export function mapOr$1612aex(self: rt.char | undefined, default_: rt.usize, _: (a0: rt.char) => rt.usize): rt.usize {
if (self === undefined) {
return default_;
}
return rt.charLenUtf8(self);
}

export function mapOr$1nwl1hk(self: rt.StrCow | undefined, default_: rt.u8, _: (a0: rt.StrCow) => rt.u8): rt.u8 {
if (self === undefined) {
return default_;
}
return borrows(self);
}

//# sourceMappingURL=option.ts.map
19 changes: 10 additions & 9 deletions ts/fixtures/lang/cows/expected/cows.Named.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
import * as rt from "./rt.ts";

export function clone$Clone(self: Named): Named {
return { name: self.name, id: self.id };
return { name: rt.strCowClone(self.name), id: self.id };
}

export function fmt$fmt_Debug(self: Named, f: rt.Formatter): rt.Result<undefined, rt.FmtError> {
const _3: string = "Named";
const _4: string = "name";
const _5: rt.Fmt = (f: rt.Formatter) => rt.fmtStr(self.name, f);
const _5: rt.Fmt = (f: rt.Formatter) => rt.fmtStr(rt.strCowStr(self.name), f);
const _7: string = "id";
const _8: rt.Fmt = (f: rt.Formatter) => rt.u8Debug(self.id, f);
return rt.debugStructFinish(rt.debugStructField(rt.debugStructField(rt.fmtDebugStruct(f, _3), _4, _5), _7, _8));
Expand All @@ -23,11 +23,11 @@ export function eq$cmp_PartialEq(self: Named, other: Named): boolean {
if (!(self.id === other.id)) {
return false;
}
return self.name === other.name;
return rt.strCowStr(self.name) === rt.strCowStr(other.name);
}

export function hash$Hash_hash_DefaultHasher(self: Named, state: rt.Hasher): void {
rt.hashStr(self.name, state);
rt.hashCow(rt.hashStr)(self.name, state);
rt.hash8(self.id, state);
}

Expand All @@ -36,7 +36,7 @@ export function partialCmp$cmp_PartialOrd(self: Named, other: Named): rt.Orderin
}

export function cmp$cmp_Ord(self: Named, other: Named): rt.Ordering {
const cmp: rt.Ordering = rt.cmpStr(self.name, other.name);
const cmp: rt.Ordering = rt.cowBy(rt.cmpStr)(self.name, other.name);
if (cmp === 0) {
return rt.cmp(self.id, other.id);
}
Expand All @@ -45,16 +45,16 @@ export function cmp$cmp_Ord(self: Named, other: Named): rt.Ordering {

/** A `Cow` in a field, with each derived impl reading it. */
export interface Named {
name: string;
name: rt.StrCow;
id: rt.u8;
}

/** Borrowed unless it has to make the text, as moq-net's `Relative::new` is. */
function new_(s: string, id: rt.u8): Named {
let name!: string;
let name!: rt.StrCow;
const trimmed: string = rt.strTrimEndMatches(s, "/");
if (!(trimmed.length === 0)) {
name = trimmed;
name = new rt.Borrowed(trimmed);
} else {
const args2: rt.Fmt[] = [(f: rt.Formatter) => rt.u8Display(id, f)];
name = rt.fmtFormat(["#", args2[0]]);
Expand All @@ -64,11 +64,12 @@ function new_(s: string, id: rt.u8): Named {

/** Through `to_mut` of the field. */
export function tag(self: Named, c: rt.char): void {
self.name = rt.strCowStr(self.name);
self.name = self.name + String.fromCodePoint(c);
}

export function intoOwned(self: Named): Named {
return { name: self.name, id: self.id };
return { name: rt.strCowStr(self.name), id: self.id };
}

export { new_ as new };
Expand Down
Loading