diff --git a/quest/m3/ts-runtime-throws.md b/quest/m3/ts-runtime-throws.md index 6f8bd6d3b..974300d95 100644 --- a/quest/m3/ts-runtime-throws.md +++ b/quest/m3/ts-runtime-throws.md @@ -26,7 +26,10 @@ The rest are gaps. At `main` they include a panic its hook cannot locate [#565](https://github.com/moq-dev/rust2/pull/565)), `offset_from` of one Rust allocation JS keeps in two arrays, a pointer moved past the array JS keeps it in (`AtIndex.reach`, such as one kept in a field), `Bytes::slice_ref` of other storage, `alloc`'s bytes read as -values, ranges stepped without their type, and fmt widths written as a placeholder. +values, ranges stepped without their type, fmt widths written as a placeholder, and a raw +slice of a byte in no array cast to `*const [u8; N]` by a route the body doesn't show, +which [a byte local in a buffer of its own](/quest/m3/ts-unsafe/lone-byte-buffers.md) owns +for locals. `git grep 'rust2-ts: ' ts/runtime` lists them; classify each before fixing. The pointer comparisons [#584](https://github.com/moq-dev/rust2/pull/584) refuses at translation, where JS may make two `rs.Place`s for one place, are out of scope: addresses were their route, and diff --git a/quest/m3/ts-unsafe/README.md b/quest/m3/ts-unsafe/README.md index b9c9cfe0f..e54d29d86 100644 --- a/quest/m3/ts-unsafe/README.md +++ b/quest/m3/ts-unsafe/README.md @@ -76,8 +76,8 @@ Public API: the translator's output. - [Vec::from_raw_parts of a typed allocation](/quest/m3/ts-unsafe/vec-from-raw-parts.md) - a `Vec` adopts an `alloc`ed array of `T`s, with its length, capacity, and drops - [Vec::drain from std's MIR](/quest/m3/ts-unsafe/vec-drain-mir.md) - std's `Drain` translates, replacing the runtime's port - [BinaryHeap from std's MIR](/quest/m3/ts-unsafe/binary-heap-mir.md) - std's `BinaryHeap` and `PeekMut` translate, replacing the runtime's port -- [A slice's pointer cast to an array's](/quest/m3/ts-unsafe/array-casts.md) - `*(s as *const [u8] as *const [u8; N])` in a crate's own code, and `IoSlice` - [Unchecked integer operations](/quest/m3/ts-unsafe/unchecked-ops.md) - `unchecked_*` and `NonZero::new_unchecked` translate, aborting on a violated precondition - [NonZero's unchecked arithmetic](/quest/m3/ts-unsafe/nonzero-unchecked-ops.md) - `NonZero::unchecked_add` and `unchecked_mul` translate, aborting at std's site - [UnsafeCell's raw accessors](/quest/m3/ts-unsafe/unsafecell.md) - `UnsafeCell::raw_get`, `from_mut`, and `replace` translate - [A Box of one uninitialized value](/quest/m3/ts-unsafe/box-new-uninit.md) - `Box::new_uninit` and `new_zeroed` for one value translate, through `write` and `assume_init` +- [A byte local whose address is taken, in a buffer of its own](/quest/m3/ts-unsafe/lone-byte-buffers.md) - raw and mutable slices of a `u8` local, and casts of them to byte arrays, translate instead of being refused diff --git a/quest/m3/ts-unsafe/array-casts.md b/quest/m3/ts-unsafe/array-casts.md deleted file mode 100644 index 0274386ea..000000000 --- a/quest/m3/ts-unsafe/array-casts.md +++ /dev/null @@ -1,18 +0,0 @@ -# [S] A slice's pointer cast to an array's - -## Goal - -[rust2-ts](/ts/README.md) translates `*(s as *const [u8] as *const [u8; N])` in a crate's -own code, and `std::io::IoSlice` (`IoSlice::new`, `Buf::chunks_vectored`), proven by -differential tests against native Rust. Today the cast is refused as ``a cast from a -pointer to `[u8]` to one to `[u8; 2]`, which reads the bytes of one type as another`` -(`ts/src/lower/pointer.rs`), and `IoSlice` as an unsupported type -(`ts/src/lower/mod.rs`, `ts/src/lower/dynamic.rs`). - -## Plan - -The bytes keep their type, so the cast reinterprets nothing. `bytes`' own `get_u16` and -wider already map to the runtime since [#447](https://github.com/moq-dev/rust2/pull/447), -and `<[u8]>::get` and `get_mut` of a range translate. No consumer at the moq pin. - -Public API: the translator's output. diff --git a/quest/m3/ts-unsafe/lone-byte-buffers.md b/quest/m3/ts-unsafe/lone-byte-buffers.md new file mode 100644 index 000000000..99d2157bf --- /dev/null +++ b/quest/m3/ts-unsafe/lone-byte-buffers.md @@ -0,0 +1,32 @@ +# [M] A byte local whose address is taken, in a buffer of its own + +## Goal + +[rust2-ts](/ts/README.md) keeps a `u8` local whose raw pointer the body takes (`&raw const` +or `&raw mut` of it) in a `Uint8Array(1)`, so raw slices, mutable slices, and casts to +`*const [u8; N]` of it are views of that buffer, as for any other byte, proven by +differential tests against native Rust. Today JS keeps such a byte in no array of bytes, +so `stray` and `lone_byte_array` (`ts/src/lower/mir/origin.rs`) refuse, with `a raw or +mutable slice of a byte in no array of bytes`, each route the body shows, and the runtime +throws the same where it doesn't (`ptrByteSlice`, `RawSlice.byteArray` in +`ts/runtime/rs.ts`), or copies the byte for a shared slice (`Array::Copy`). + +## Plan + +Decided with the maintainer on 2026-11-07: m3. Planned on review of +[#624](https://github.com/moq-dev/rust2/pull/624), whose body-visible refusal of a cast of +an empty raw slice of a lone byte to `*const [u8; N]` kept missing routes (`&raw *s`, +`NonNull::from`, `NonNull::new(p).unwrap()`); this fixes the class at its root. + +- Which locals: those whose `&raw` the body takes, decided per body before lowering, so + every read and write of the local is `buf[0]` and a place of it is the `rs.AtIndex` of + element 0. +- Then the lone-byte refusals and the `Array::Copy` case go for those locals. A byte in a + field of an object JS keeps, or one behind a reference from elsewhere, stays in no array: + keep refusing or throwing there, and say so in the README's pointer row. + +Public API: the translator's output. + +## Related + +- [Throw only where Rust panics](/quest/m3/ts-runtime-throws.md) - lists the run-time throws this removes for locals diff --git a/ts/README.md b/ts/README.md index 733c5cc90..2fae9e2c3 100644 --- a/ts/README.md +++ b/ts/README.md @@ -110,7 +110,7 @@ crate translation reaches is refused, and so are two versions of one crate it re | `Vec` | `rs.Vec`: its items, the array `items`, and the capacity std's holds; `rs.vecFrom(items)` makes one of an array with room for exactly them. `rs.ByteVec` of bytes | | `Cow<[T]>`, `Cow` | `rs.Cow`: the `Vec` it owns, or an `rs.Borrowed` holding the slice it borrows; `rs.ByteCow` for bytes, an `rs.ByteVec` or an `rs.ByteSlice`; `rs.StrCow` for text, the `rs.String` it owns or an `rs.Borrowed` holding the string it borrows, whose text `rs.strCowStr` reads | | `&T`, `&mut T`, `Box`, `Reverse`, `NonZero`, `AssertUnwindSafe` | the value; a `&mut` to a value JS copies, such as a number, an `Option`, or a reference, or to an `Arc`, a `Waker`, or a `LocalKey`, whose copies share what it points at, is an `rs.Place`, which for what a box holds is the place holding the box | -| `*const T`, `*mut T`, `NonNull` | what a `&mut T` is: the object, an `rs.Slice` of a `[T; N]`'s elements or an `rs.ByteSlice` of a `[u8; N]`'s bytes, which compares by the array or buffer and offset they are at, refused for an array of one, which `array::from_ref`, `from_mut` of a variable, and `Option::as_slice` make of their own, or an `rs.Place` 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 `rs.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 but for a `Vec`'s room up to its capacity, fails at run time; a pointer into an array of values JS keeps as objects is refused, as is comparing pointers to other values JS copies, each a place JS makes of its own; `rs.NULL` for null and `rs.DANGLING` for dangling. A `*const ()` is an identity, such as a waker's data, and `rs.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 `rs.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 `rs.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 `rs` class such as `rs.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 | +| `*const T`, `*mut T`, `NonNull` | what a `&mut T` is: the object, an `rs.Slice` of a `[T; N]`'s elements or an `rs.ByteSlice` of a `[u8; N]`'s bytes, which compares by the array or buffer and offset they are at, refused for an array of one, which `array::from_ref`, `from_mut` of a variable, and `Option::as_slice` make of their own, or an `rs.Place` 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 `rs.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 but for a `Vec`'s room up to its capacity, fails at run time; a pointer into an array of values JS keeps as objects is refused, as is comparing pointers to other values JS copies, each a place JS makes of its own; `rs.NULL` for null and `rs.DANGLING` for dangling. A pointer to a slice cast to one to an array of its elements is the `rs.Slice` or `rs.ByteSlice` of that many from its first, read through only where Rust reads. A `*const ()` is an identity, such as a waker's data, and `rs.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 `rs.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 `rs.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 `rs` class such as `rs.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`: `undefined` until written, `0` for a byte, or an object whose parts kept as objects are there, holding `undefined`, as each of `Box::new_uninit_slice`'s is; a slice's `write_clone_of_slice` clones into its slots without dropping what they held | | `ManuallyDrop` | `T`, which nothing drops but its own `drop`; its `Debug`, comparisons, and constants are refused | | `union` | an object of slots named by offset, `at0` and `at8`, each holding the field part kept there; fields must overlap in the same type, or in a non-null pointer and an `Option` of it | @@ -149,6 +149,7 @@ crate translation reaches is refused, and so are two versions of one crate it re | `pin!(x)`, `poll_fn(f)`, `future::pending()`, `future::ready(v)` | `x`; `rs.PollFn`, which drops `f` with itself; `rs.NEVER`, which every `Pending` is; `rs.Ready`, whose first poll or `into_inner` takes `v` and a later one panics, and which drops `v` with itself unless one took it | | `Box::pin(x)`, `dyn Future` | `x`; `rs.Future`: an `async` body or std's future as it is, and another future as an `rs.DynFuture` over its `poll`, which drops it with itself unless borrowed | | `bytes::Bytes` | `rs.ByteSlice`, as `&[u8]` is: its clones and slices share bytes that never change | +| `io::IoSlice` | `rs.ByteSlice`, the `&[u8]` it lends, which `advance` and `advance_slices` move past | | `bytes::BytesMut` | `rs.BytesMut`: a window of storage, which what it splits off and freezes share without overlapping | | `rand::rngs::ThreadRng` | `rs.ThreadRng`, which holds no state | | `hashbrown::HashMap`, `HashSet` | `rs.HashMap` and `rs.HashSet`, as std's, which are hashbrown's | @@ -648,8 +649,6 @@ not all of `Buf`'s; a TS caller sees the same in its type. Hashing into a `dyn H each of `Hasher`'s. A class of a std type's value calls the mapping of its impl, such as `DefaultHasher`'s `Hasher`, or a `String`'s or a `Formatter`'s `fmt::Write`, and one no mapping makes, such as a `Vec`'s `io::Write`, is refused where a call dispatches to it. -A `dyn Buf` holds no `chunks_vectored`, whose `IoSlice` has no JS value, so a call of it -fails. A `dyn Any` is such an object with no methods, whose class `is`, `downcast_ref`, `downcast_mut`, and `Box`'s, `Arc`'s, and `Rc`'s `downcast` check for: `a instanceof of$dyns_Square ? diff --git a/ts/fixtures/lang/panics/hook/expected/hooked.ts b/ts/fixtures/lang/panics/hook/expected/hooked.ts index 7e835f1da..7f8d89c6c 100644 --- a/ts/fixtures/lang/panics/hook/expected/hooked.ts +++ b/ts/fixtures/lang/panics/hook/expected/hooked.ts @@ -268,7 +268,7 @@ export function sited(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { const _19: rs.u16[] = [n as rs.u16]; const set: rs.BTreeSet = rs.btreeExtendKeys(rs.btreeNew(rs.cmp) as rs.BTreeSet, rs.iterSlice(_19), true, undefined, undefined, 2, true); b0: { - const k: rs.u8 = rs.u8Rem(kind, 73, { file: "fixtures/lang/panics/src/hooked.rs", line: 203, col: 11 }); + const k: rs.u8 = rs.u8Rem(kind, 75, { file: "fixtures/lang/panics/src/hooked.rs", line: 203, col: 11 }); if (k === 0) { rs.byteVecPush(out, rs.byteVecWithCapacity(rs.usizeSub(4294967295, at, { file: "fixtures/lang/panics/src/hooked.rs", line: 204, col: 48 })).length & 0xff); } else if (k === 1) { @@ -502,6 +502,17 @@ export function sited(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { rs.byteVecPush(out, rs.sliceNewUninit(rs.usizeSub(4294967295, at, { file: "fixtures/lang/panics/src/hooked.rs", line: 337, col: 55 }), 2, (): rs.u16 => { return (undefined as unknown) as rs.u16; }).length & 0xff); + } else if (k === 72) { + let lent: rs.ByteSlice = rs.byteVecSlice(v); + const _482: rs.usize = rs.usizeAdd(rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 340, col: 26 }), 3, { file: "fixtures/lang/panics/src/hooked.rs", line: 340, col: 26 }); + rs.ioSliceAdvance(rs.place(() => lent, (value2) => lent = value2), _482, { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/io/io_slice/repr_generic.rs", line: 14, col: 25 }); + rs.byteVecExtendFromSlice(out, lent); + } else if (k === 73) { + const lent2: rs.ByteSlice[] = [rs.byteVecSlice(v)]; + let left: rs.Slice = rs.sliceFrom(lent2); + const _498: rs.usize = rs.usizeAdd(rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 346, col: 57 }), 3, { file: "fixtures/lang/panics/src/hooked.rs", line: 346, col: 57 }); + rs.ioSliceAdvanceSlices(rs.place(() => left, (value) => left = value), _498, { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/io/io_slice.rs", line: 304, col: 13 }); + rs.byteVecPush(out, left.length & 0xff); } else { if (53 <= k) { if (k <= 56) { @@ -529,16 +540,16 @@ export function joined(kind: rs.u8, n: rs.u8, out: rs.ByteVec): void { let joined!: rs.ByteVec; const big: rs.ByteVec = rs.byteVecOf(n, 1 << 16); const refs: (a0: rs.usize) => rs.Vec = (count: rs.usize): rs.Vec => { - return rs.vecFromElem(rs.byteSliceRange(rs.byteVecSlice(big), 0, undefined, { file: "fixtures/lang/panics/src/hooked.rs", line: 346, col: 40 }), count, undefined); + return rs.vecFromElem(rs.byteSliceRange(rs.byteVecSlice(big), 0, undefined, { file: "fixtures/lang/panics/src/hooked.rs", line: 357, col: 40 }), count, undefined); }; if (kind === 0) { - joined = rs.byteSlicesJoin(rs.sliceFrom(refs(rs.usizeAdd(1 << 16, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 348, col: 19 })).items)); + joined = rs.byteSlicesJoin(rs.sliceFrom(refs(rs.usizeAdd(1 << 16, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 359, col: 19 })).items)); } else if (kind === 1) { - joined = rs.byteSlicesJoin(rs.sliceFrom(refs(rs.usizeAdd(1 << 16, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 349, col: 19 })).items), rs.byteSliceFrom(Uint8Array.of(n))); + joined = rs.byteSlicesJoin(rs.sliceFrom(refs(rs.usizeAdd(1 << 16, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 360, col: 19 })).items), rs.byteSliceFrom(Uint8Array.of(n))); } else if (kind === 2) { - joined = rs.byteSlicesJoin(rs.sliceFrom(refs(rs.usizeAdd(1 << 15, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 350, col: 19 })).items)); + joined = rs.byteSlicesJoin(rs.sliceFrom(refs(rs.usizeAdd(1 << 15, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 361, col: 19 })).items)); } else { - joined = rs.iterToByteVec(rs.iterMap(rs.iterSlice(rs.slicesJoin(rs.sliceFrom(rs.vecFromElem(rs.sliceFrom(rs.vecFromElem(n as rs.u16, 1 << 16, undefined).items), rs.usizeAdd(1 << 14, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 353, col: 42 }), undefined).items), 2, rs.sliceFrom([1])).items), (_2: rs.u16): rs.u8 => { + joined = rs.iterToByteVec(rs.iterMap(rs.iterSlice(rs.slicesJoin(rs.sliceFrom(rs.vecFromElem(rs.sliceFrom(rs.vecFromElem(n as rs.u16, 1 << 16, undefined).items), rs.usizeAdd(1 << 14, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 364, col: 42 }), undefined).items), 2, rs.sliceFrom([1])).items), (_2: rs.u16): rs.u8 => { return _2 & 0xff; }), undefined, true); } @@ -561,10 +572,10 @@ export function compared(kind: rs.u8, n: rs.u8): rs.u8 { const _5: [rs.RefCell, rs.RefCell] = [new rs.RefCell(n), new rs.RefCell(rs.u8WrappingAdd(n, 1))]; const a: rs.RefCell = _5[0]; const b: rs.RefCell = _5[1]; - if (!(rs.u8Rem(n, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 365, col: 20 }) === 0)) { - _held = rs.refCellBorrowMut(b, { file: "fixtures/lang/panics/src/hooked.rs", line: 365, col: 59 }); + if (!(rs.u8Rem(n, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 376, col: 20 }) === 0)) { + _held = rs.refCellBorrowMut(b, { file: "fixtures/lang/panics/src/hooked.rs", line: 376, col: 59 }); } else { - _held = rs.refCellBorrowMut(a, { file: "fixtures/lang/panics/src/hooked.rs", line: 365, col: 35 }); + _held = rs.refCellBorrowMut(a, { file: "fixtures/lang/panics/src/hooked.rs", line: 376, col: 35 }); } if (kind === 0) { _0 = rs.refCellBy(rs.same, { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell.rs", line: 1482, col: 15 }, { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell.rs", line: 1482, col: 34 })(a, b) ? 1 : 0; @@ -611,11 +622,11 @@ export function stock(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { const at: rs.usize = n as rs.usize; const whole: rs.ByteSlice = rs.bytesFromVec(rs.byteVecOf(n, 4)); b0: { - const k: rs.u8 = rs.u8Rem(kind, 33, { file: "fixtures/lang/panics/src/hooked.rs", line: 407, col: 24 }); + const k: rs.u8 = rs.u8Rem(kind, 33, { file: "fixtures/lang/panics/src/hooked.rs", line: 418, col: 24 }); if (0 <= k) { if (k <= 1) { rs.setHook((info: rs.PanicHookInfo): undefined => { - const at2: rs.Location = rs.optionUnwrap(info.location, undefined, { file: "fixtures/lang/panics/src/hooked.rs", line: 409, col: 38 }); + const at2: rs.Location = rs.optionUnwrap(info.location, undefined, { file: "fixtures/lang/panics/src/hooked.rs", line: 420, col: 38 }); const _10: string = at2.file; const _126: rs.u32 = at2.line; const _14: rs.u32 = at2.col; @@ -624,16 +635,16 @@ export function stock(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { rs.localKeyWithBorrowMut(NOTE, (note: rs.String): undefined => { rs.stringPushStr(note, line.v); }, { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/thread/local.rs", line: 721, col: 38 }); - rs.panicFmt(["unread"], { file: "fixtures/lang/panics/src/hooked.rs", line: 412, col: 13 }); + rs.panicFmt(["unread"], { file: "fixtures/lang/panics/src/hooked.rs", line: 423, col: 13 }); }, { capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/raw_vec/mod.rs", line: 29, col: 5 }, trusted_capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/spec_from_iter_nested.rs", line: 57, col: 18 }, swap_remove: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2178, col: 13 }, vec_set_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2138, col: 9 }, into_flattened: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 3667, col: 36 }, rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3902, col: 9 }, rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3948, col: 9 }, ord_violation: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/sort/shared/smallsort.rs", line: 854, col: 5 }, ord_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cmp.rs", line: 1166, col: 9 }, f32_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f32.rs", line: 1665, col: 9 }, f64_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f64.rs", line: 1643, col: 9 }, encode_utf8: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2507, col: 9 }, encode_utf16: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2601, col: 13 }, format: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/fmt.rs", line: 657, col: 14 }, to_string: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/string.rs", line: 2997, col: 14 }, debug_struct_fields: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/fmt/mod.rs", line: 2572, col: 9 }, exact_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/exact_size.rs", line: 122, col: 9 }, join_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/str.rs", line: 177, col: 10 }, int_sum: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/accum.rs", line: 206, col: 1 }, int_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 554, col: 1 }, char_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 119, col: 45 }, hash_capacity: { file: "/cargo/registry/25cdd57fae9f0462/hashbrown-0.17.1/src/raw.rs", line: 36, col: 40 }, btree_range_equal_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 110, col: 21 }, btree_range_equal_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 112, col: 21 }, btree_range_order_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 119, col: 21 }, btree_range_order_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 121, col: 21 }, deque_insert: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2612, col: 9 }, deque_swap_i: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1062, col: 9 }, deque_swap_j: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1063, col: 9 }, deque_rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3198, col: 9 }, deque_rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3243, col: 9 }, deque_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2724, col: 9 }, list_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/linked_list.rs", line: 1015, col: 9 }, mutex_lock: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sys/sync/mutex/no_threads.rs", line: 28, col: 9 }, once_force: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sync/once.rs", line: 227, col: 20 }, reentrant_init: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/once.rs", line: 325, col: 66 }, lazy_poisoned: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/lazy.rs", line: 386, col: 5 }, ready_poll: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 23, col: 35 }, ready_into_inner: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 46, col: 16 }, duration_new: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 281, col: 18 }, duration_from_mins: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 540, col: 13 }, duration_from_hours: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 510, col: 13 }, duration_add: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1345, col: 31 }, duration_sub: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1365, col: 31 }, duration_mul: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1385, col: 31 }, bytes_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 207, col: 5 }, bytes_does_not_fit: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 215, col: 5 }, bytes_slice: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 374, col: 28 }, bytes_slice_ref_start: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 426, col: 9 }, bytes_slice_ref_end: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 432, col: 9 }, bytes_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 481, col: 9 }, bytes_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 533, col: 9 }, bytes_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 694, col: 9 }, bytes_mut_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 329, col: 9 }, bytes_mut_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 408, col: 9 }, bytes_mut_set_len: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 545, col: 9 }, bytes_mut_overflow: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 700, col: 21 }, bytes_mut_overflow_offset: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 720, col: 29 }, bytes_mut_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 1246, col: 9 } }); const subset: rs.ByteSlice = rs.bytesSlice(whole, 0, 1); if (k === 0) { - const _22: rs.ByteSlice = rs.bytesSlice(whole, rs.usizeAdd(1, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 416, col: 34 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 416, col: 30 })); + const _22: rs.ByteSlice = rs.bytesSlice(whole, rs.usizeAdd(1, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 427, col: 34 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 427, col: 30 })); held = rs.bytesSliceRef(_22, subset); rs.bytesDrop(_22); } else { const _32: rs.ByteSlice = rs.bytesSlice(whole, 0, 1); - const _35: rs.ByteSlice = rs.byteSliceRange(whole, 0, rs.usizeAdd(2, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 417, col: 58 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 417, col: 54 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 417, col: 51 }); + const _35: rs.ByteSlice = rs.byteSliceRange(whole, 0, rs.usizeAdd(2, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 428, col: 58 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 428, col: 54 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 428, col: 51 }); held = rs.bytesSliceRef(_32, _35); rs.bytesDrop(_32); } @@ -645,38 +656,38 @@ export function stock(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { } } hook(); - const shared: rs.BytesMut = rs.bytesMutFrom(rs.byteSliceRange(rs.byteSliceFrom(rs.bytes(8).fill(n)), 0, undefined, { file: "fixtures/lang/panics/src/hooked.rs", line: 423, col: 44 })); - const _52: rs.u8 = rs.u8Rem(kind, 33, { file: "fixtures/lang/panics/src/hooked.rs", line: 424, col: 11 }); + const shared: rs.BytesMut = rs.bytesMutFrom(rs.byteSliceRange(rs.byteSliceFrom(rs.bytes(8).fill(n)), 0, undefined, { file: "fixtures/lang/panics/src/hooked.rs", line: 434, col: 44 })); + const _52: rs.u8 = rs.u8Rem(kind, 33, { file: "fixtures/lang/panics/src/hooked.rs", line: 435, col: 11 }); if (_52 === 2) { - const _56: rs.ByteSlice = rs.bytesSlice(whole, rs.usizeAdd(at, 3, { file: "fixtures/lang/panics/src/hooked.rs", line: 425, col: 49 }), 2); + const _56: rs.ByteSlice = rs.bytesSlice(whole, rs.usizeAdd(at, 3, { file: "fixtures/lang/panics/src/hooked.rs", line: 436, col: 49 }), 2); rs.byteVecExtendFromSlice(out, _56); rs.bytesDrop(_56); } else if (_52 === 3) { - const _63: rs.ByteSlice = rs.bytesSlice(whole, 0, rs.usizeAdd(at, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 426, col: 51 })); + const _63: rs.ByteSlice = rs.bytesSlice(whole, 0, rs.usizeAdd(at, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 437, col: 51 })); rs.byteVecExtendFromSlice(out, _63); rs.bytesDrop(_63); } else if (_52 === 4) { - const _72: rs.RangeInclusive = new rs.RangeInclusive(rs.usizeSub(4294967295, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 427, col: 62 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 427, col: 49 }), 4294967295, rs.usizeStep); + const _72: rs.RangeInclusive = new rs.RangeInclusive(rs.usizeSub(4294967295, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 438, col: 62 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 438, col: 49 }), 4294967295, rs.usizeStep); const _70: rs.ByteSlice = rs.bytesSliceInclusive(whole, _72); rs.byteVecExtendFromSlice(out, _70); rs.bytesDrop(_70); } else if (_52 === 5) { let _81: rs.ByteSlice = rs.bytesClone(whole); - const _83: rs.usize = rs.usizeAdd(at, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 428, col: 60 }); + const _83: rs.usize = rs.usizeAdd(at, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 439, col: 60 }); const _79: rs.ByteSlice = rs.bytesSplitTo(rs.place(() => _81, (value9) => _81 = value9), _83); rs.byteVecExtendFromSlice(out, _79); rs.bytesDrop(_79); rs.bytesDrop(_81); } else if (_52 === 6) { let _89: rs.ByteSlice = rs.bytesClone(whole); - const _91: rs.usize = rs.usizeAdd(at, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 429, col: 61 }); + const _91: rs.usize = rs.usizeAdd(at, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 440, col: 61 }); const _87: rs.ByteSlice = rs.bytesSplitOff(rs.place(() => _89, (value8) => _89 = value8), _91); rs.byteVecExtendFromSlice(out, _87); rs.bytesDrop(_87); rs.bytesDrop(_89); } else if (_52 === 7) { let _94: rs.ByteSlice = rs.bytesClone(whole); - const _96: rs.usize = rs.usizeAdd(at, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 430, col: 36 }); + const _96: rs.usize = rs.usizeAdd(at, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 441, col: 36 }); rs.bytesAdvance(rs.place(() => _94, (value7) => _94 = value7), _96); rs.bytesDrop(_94); } else if (_52 === 8) { @@ -685,12 +696,12 @@ export function stock(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { rs.bytesDrop(_101); } else if (_52 === 9) { let _107: rs.ByteSlice = rs.bytesClone(whole); - const _109: rs.usize = rs.usizeAdd(9, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 432, col: 50 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 432, col: 46 }); + const _109: rs.usize = rs.usizeAdd(9, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 443, col: 50 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 443, col: 46 }); rs.byteVecPush(out, rs.u64Low(rs.u64FromBeBytes(rs.bytesReadInt(rs.place(() => _107, (value5) => _107 = value5), 8, _109, false, false))) & 0xff); rs.bytesDrop(_107); } else if (_52 === 10) { - let _114: rs.ByteSlice = rs.byteSliceRange(data, 0, undefined, { file: "fixtures/lang/panics/src/hooked.rs", line: 433, col: 21 }); - const _116: rs.usize = rs.usizeAdd(data.length, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 433, col: 35 }); + let _114: rs.ByteSlice = rs.byteSliceRange(data, 0, undefined, { file: "fixtures/lang/panics/src/hooked.rs", line: 444, col: 21 }); + const _116: rs.usize = rs.usizeAdd(data.length, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 444, col: 35 }); rs.byteSliceAdvance(rs.place(() => _114, (value4) => _114 = value4), _116); } else if (_52 === 11) { let _120: rs.ByteSlice = rs.bytesClone(whole); @@ -699,75 +710,75 @@ export function stock(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { rs.bytesDrop(_120); } else if (_52 === 12) { let _129: rs.ByteSlice = rs.bytesClone(whole); - const _131: rs.usize = rs.usizeAdd(at, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 435, col: 66 }); + const _131: rs.usize = rs.usizeAdd(at, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 446, col: 66 }); const _127: rs.ByteSlice = rs.bytesSplitTo(rs.place(() => _129, (value2) => _129 = value2), _131); rs.byteVecExtendFromSlice(out, _127); rs.bytesDrop(_127); rs.bytesDrop(_129); } else if (_52 === 13) { - let _137: rs.ByteSlice = rs.byteSliceRange(data, 0, undefined, { file: "fixtures/lang/panics/src/hooked.rs", line: 436, col: 44 }); - const _139: rs.usize = rs.usizeAdd(data.length, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 436, col: 64 }); + let _137: rs.ByteSlice = rs.byteSliceRange(data, 0, undefined, { file: "fixtures/lang/panics/src/hooked.rs", line: 447, col: 44 }); + const _139: rs.usize = rs.usizeAdd(data.length, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 447, col: 64 }); const _135: rs.ByteSlice = rs.byteSliceCopyToBytes(rs.place(() => _137, (value) => _137 = value), _139); rs.byteVecExtendFromSlice(out, _135); rs.bytesDrop(_135); } else if (_52 === 14) { const _146: rs.BytesMut = rs.bytesMutFrom(data); - const _144: rs.BytesMut = rs.bytesMutSplitTo(_146, rs.usizeAdd(data.length, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 437, col: 68 })); + const _144: rs.BytesMut = rs.bytesMutSplitTo(_146, rs.usizeAdd(data.length, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 448, col: 68 })); rs.byteVecExtendFromSlice(out, rs.bytesMutView(_144)); _144[Symbol.dispose](); _146[Symbol.dispose](); } else if (_52 === 15) { const _154: rs.BytesMut = rs.bytesMutWithCapacity(4); - const _152: rs.BytesMut = rs.bytesMutSplitOff(_154, rs.usizeAdd(at, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 438, col: 75 })); + const _152: rs.BytesMut = rs.bytesMutSplitOff(_154, rs.usizeAdd(at, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 449, col: 75 })); rs.byteVecExtendFromSlice(out, rs.bytesMutView(_152)); _152[Symbol.dispose](); _154[Symbol.dispose](); } else if (_52 === 16) { - const b: rs.BytesMut = rs.bytesMutWithCapacity(rs.usizeRem(at, 4, { file: "fixtures/lang/panics/src/hooked.rs", line: 440, col: 49 })); - rs.bytesMutSetLen(b, rs.usizeAdd(b.cap, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 442, col: 32 })); + const b: rs.BytesMut = rs.bytesMutWithCapacity(rs.usizeRem(at, 4, { file: "fixtures/lang/panics/src/hooked.rs", line: 451, col: 49 })); + rs.bytesMutSetLen(b, rs.usizeAdd(b.cap, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 453, col: 32 })); rs.byteVecPush(out, b.length & 0xff); b[Symbol.dispose](); } else if (_52 === 17) { - const b2: rs.BytesMut = rs.bytesMutWithCapacity(rs.usizeRem(at, 4, { file: "fixtures/lang/panics/src/hooked.rs", line: 446, col: 49 })); - rs.bytesMutAdvanceMut(b2, rs.usizeAdd(b2.cap, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 448, col: 36 })); + const b2: rs.BytesMut = rs.bytesMutWithCapacity(rs.usizeRem(at, 4, { file: "fixtures/lang/panics/src/hooked.rs", line: 457, col: 49 })); + rs.bytesMutAdvanceMut(b2, rs.usizeAdd(b2.cap, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 459, col: 36 })); rs.byteVecPush(out, b2.length & 0xff); b2[Symbol.dispose](); } else if (_52 === 18) { - const v: rs.ByteVec = rs.byteVecWithCapacity(rs.usizeRem(at, 4, { file: "fixtures/lang/panics/src/hooked.rs", line: 452, col: 50 })); - rs.byteVecAdvanceMut(v, rs.usizeAdd(v.data.length, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 454, col: 36 })); + const v: rs.ByteVec = rs.byteVecWithCapacity(rs.usizeRem(at, 4, { file: "fixtures/lang/panics/src/hooked.rs", line: 463, col: 50 })); + rs.byteVecAdvanceMut(v, rs.usizeAdd(v.data.length, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 465, col: 36 })); rs.byteVecPush(out, v.length & 0xff); } else if (_52 === 19) { const _197: rs.BytesMut = rs.bytesMutFrom(data); - rs.bytesMutAdvance(_197, rs.usizeAdd(data.length, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 457, col: 44 })); + rs.bytesMutAdvance(_197, rs.usizeAdd(data.length, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 468, col: 44 })); _197[Symbol.dispose](); } else if (_52 === 20) { - const _204: rs.BytesMut = rs.bytesMutFrom(rs.byteSliceRange(data, 0, rs.min(data.length, 3), { file: "fixtures/lang/panics/src/hooked.rs", line: 458, col: 44 })); + const _204: rs.BytesMut = rs.bytesMutFrom(rs.byteSliceRange(data, 0, rs.min(data.length, 3), { file: "fixtures/lang/panics/src/hooked.rs", line: 469, col: 44 })); rs.byteVecPush(out, (rs.bytesMutReadWord(_204, 4, false) as rs.u32) & 0xff); _204[Symbol.dispose](); } else if (_52 === 21) { - const _212: rs.BytesMut = rs.bytesMutWithCapacity(rs.usizeSub(4294967295, at, { file: "fixtures/lang/panics/src/hooked.rs", line: 459, col: 48 })); + const _212: rs.BytesMut = rs.bytesMutWithCapacity(rs.usizeSub(4294967295, at, { file: "fixtures/lang/panics/src/hooked.rs", line: 470, col: 48 })); rs.byteVecPush(out, _212.cap & 0xff); _212[Symbol.dispose](); } else if (_52 === 22) { const _tail: rs.BytesMut = rs.bytesMutSplitOff(shared, 4); - rs.bytesMutReserve(shared, rs.usizeSub(4294967295, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 463, col: 41 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 463, col: 28 })); + rs.bytesMutReserve(shared, rs.usizeSub(4294967295, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 474, col: 41 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 474, col: 28 })); _tail[Symbol.dispose](); } else if (_52 === 23) { rs.bytesMutSplitTo(shared, 4)[Symbol.dispose](); - rs.bytesMutReserve(shared, rs.usizeSub(4294967295 - 4, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 468, col: 45 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 468, col: 28 })); + rs.bytesMutReserve(shared, rs.usizeSub(4294967295 - 4, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 479, col: 45 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 479, col: 28 })); } else if (_52 === 24) { const _235: rs.u64 = n as rs.u64; - const _236: rs.usize = rs.usizeAdd(9, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 470, col: 49 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 470, col: 45 }); + const _236: rs.usize = rs.usizeAdd(9, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 481, col: 49 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 481, col: 45 }); rs.bytesMutPutInt(shared, rs.u64ToBeBytes(_235), _236, false); } else if (_52 === 25) { const _240: rs.i64 = n as rs.i64; - const _241: rs.usize = rs.usizeAdd(9, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 471, col: 45 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 471, col: 41 }); + const _241: rs.usize = rs.usizeAdd(9, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 482, col: 45 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 482, col: 41 }); rs.byteVecPutInt(out, rs.i64ToBeBytes(_240), _241, false); } else if (_52 === 26) { - rs.byteVecPutFill(out, n, rs.usizeSub(4294967295, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 472, col: 53 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 472, col: 40 })); + rs.byteVecPutFill(out, n, rs.usizeSub(4294967295, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 483, col: 53 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 483, col: 40 })); } else if (_52 === 27) { const _253: Take.Take = buf_impl_take$bytes_Buf_bytes_Bytes(rs.bytesClone(whole), 2); - const _251: rs.ByteSlice = Take.copyToBytes$bytes_Buf_bytes_Bytes(_253, rs.usizeAdd(at, 3, { file: "fixtures/lang/panics/src/hooked.rs", line: 473, col: 74 })); + const _251: rs.ByteSlice = Take.copyToBytes$bytes_Buf_bytes_Bytes(_253, rs.usizeAdd(at, 3, { file: "fixtures/lang/panics/src/hooked.rs", line: 484, col: 74 })); rs.byteVecExtendFromSlice(out, _251); rs.bytesDrop(_251); drop$bytes_buf_Take_bytes_Bytes(_253); @@ -777,15 +788,15 @@ export function stock(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { drop$bytes_buf_Take_bytes_Bytes(_261); } else if (_52 === 29) { const chunk: rs.ByteSlice = rs.bytesMutChunkMut(shared); - UninitSlice.writeByte(chunk, rs.usizeAdd(UninitSlice.len(chunk), rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 478, col: 44 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 478, col: 30 }), n); + UninitSlice.writeByte(chunk, rs.usizeAdd(UninitSlice.len(chunk), rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 489, col: 44 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 489, col: 30 }), n); } else if (_52 === 30) { - UninitSlice.writeByte(UninitSlice.indexMut$ops_IndexMut_ops_RangeFrom_usize(rs.byteVecChunkMut(rs.byteVecWithCapacity(rs.usizeRem(at, 4, { file: "fixtures/lang/panics/src/hooked.rs", line: 480, col: 40 }))), new rs.RangeFrom(rs.usizeAdd(65, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 480, col: 65 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 480, col: 60 }), rs.usizeStep), { file: "fixtures/lang/panics/src/hooked.rs", line: 480, col: 59 }), 0, n); + UninitSlice.writeByte(UninitSlice.indexMut$ops_IndexMut_ops_RangeFrom_usize(rs.byteVecChunkMut(rs.byteVecWithCapacity(rs.usizeRem(at, 4, { file: "fixtures/lang/panics/src/hooked.rs", line: 491, col: 40 }))), new rs.RangeFrom(rs.usizeAdd(65, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 491, col: 65 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 491, col: 60 }), rs.usizeStep), { file: "fixtures/lang/panics/src/hooked.rs", line: 491, col: 59 }), 0, n); } else if (_52 === 31) { const _287: rs.BytesMut = rs.bytesMutWithCapacity(0); - UninitSlice.copyFromSlice(UninitSlice.indexMut$ops_IndexMut_ops_RangeTo_usize(rs.bytesMutChunkMut(_287), { end: rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 481, col: 45 }) }, { file: "fixtures/lang/panics/src/hooked.rs", line: 481, col: 42 }), rs.byteSliceFrom(rs.bytes(3).fill(n))); + UninitSlice.copyFromSlice(UninitSlice.indexMut$ops_IndexMut_ops_RangeTo_usize(rs.bytesMutChunkMut(_287), { end: rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 492, col: 45 }) }, { file: "fixtures/lang/panics/src/hooked.rs", line: 492, col: 42 }), rs.byteSliceFrom(rs.bytes(3).fill(n))); _287[Symbol.dispose](); } else { - const _297: rs.BytesMut = rs.bytesMutZeroed(rs.usizeSub(4294967295, at, { file: "fixtures/lang/panics/src/hooked.rs", line: 482, col: 40 })); + const _297: rs.BytesMut = rs.bytesMutZeroed(rs.usizeSub(4294967295, at, { file: "fixtures/lang/panics/src/hooked.rs", line: 493, col: 40 })); rs.byteVecPush(out, _297.length & 0xff); _297[Symbol.dispose](); } @@ -801,7 +812,7 @@ export function stock(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { */ export function edition2018Panicked(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { b0: { - if (!(rs.u8Rem(kind, 7, { file: "fixtures/lang/panics/src/hooked.rs", line: 490, col: 8 }) !== 6)) { + if (!(rs.u8Rem(kind, 7, { file: "fixtures/lang/panics/src/hooked.rs", line: 501, col: 8 }) !== 6)) { if (!(option_unwrapOr$1fr498u(rs.byteSliceFirst(data), 0) > 200)) { break b0; } diff --git a/ts/fixtures/lang/panics/src/hooked.rs b/ts/fixtures/lang/panics/src/hooked.rs index 92adaba61..ae4114b61 100644 --- a/ts/fixtures/lang/panics/src/hooked.rs +++ b/ts/fixtures/lang/panics/src/hooked.rs @@ -200,7 +200,7 @@ pub fn sited(kind: u8, data: &[u8], out: &mut Vec) { let deque = VecDeque::from(v.clone()); let map = BTreeMap::from([(u16::from(n), n)]); let set = BTreeSet::from([u16::from(n)]); - match kind % 73 { + match kind % 75 { 0 => out.push(Vec::::with_capacity(usize::MAX - at).len() as u8), 1 => v.clone().rotate_right(at + 3), 2 => out.push(n.clamp(n.max(1), n.max(1) - 1)), @@ -335,6 +335,17 @@ pub fn sited(kind: u8, data: &[u8], out: &mut Vec) { 69 => _ = [std::mem::MaybeUninit::uninit(); 2].write_copy_of_slice(&v[..at % 2]), 70 => _ = [const { std::mem::MaybeUninit::uninit() }; 2].write_clone_of_slice(&[String::new()][..at % 2]), 71 => out.push(Box::<[u16]>::new_uninit_slice(usize::MAX - at).len() as u8), + 72 => { + let mut lent = std::io::IoSlice::new(&v); + lent.advance(at % 2 + 3); + out.extend_from_slice(&lent); + } + 73 => { + let mut lent = [std::io::IoSlice::new(&v)]; + let mut left = &mut lent[..]; + std::io::IoSlice::advance_slices(&mut left, at % 2 + 3); + out.push(left.len() as u8); + } _ => out.push(Lying(n).len() as u8), } } diff --git a/ts/fixtures/lang/pointers/expected/lib.ts b/ts/fixtures/lang/pointers/expected/lib.ts index 0f3ef1956..e0bf9590c 100644 --- a/ts/fixtures/lang/pointers/expected/lib.ts +++ b/ts/fixtures/lang/pointers/expected/lib.ts @@ -1,7 +1,7 @@ // Generated by rust2-ts. Do not edit. import * as rs from "./rs.ts"; -import { lists, shared, places, unchecked, nested, copies, sentinels, cells, rebound, lapsed, writers, made, segments, uninitRuns, iteratedRuns, besideWritten, waiters, taken, bytes, loaded, reattached, partWritten, aimed, distinct, rawArcs, rawPlaces, arrays, genericUnions } from "./pointers.ts"; +import { lists, shared, places, unchecked, nested, copies, sentinels, cells, rebound, lapsed, writers, made, segments, uninitRuns, iteratedRuns, besideWritten, waiters, taken, bytes, loaded, reattached, partWritten, aimed, distinct, rawArcs, rawPlaces, arrays, arrayCasts, genericUnions } from "./pointers.ts"; import type * as Aimed from "./pointers.Aimed.ts"; import * as Bin from "./pointers.Bin.ts"; import type * as ByCall from "./pointers.ByCall.ts"; @@ -302,8 +302,10 @@ export function cases(): rs.Vec<[string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.By rawPlaces(data26, out26); }] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["pointers::arrays", (_236: rs.u8, data27: rs.ByteSlice, out27: rs.ByteVec): undefined => { arrays(data27, out27); - }] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["pointers::generic_unions", (_237: rs.u8, data28: rs.ByteSlice, out28: rs.ByteVec): undefined => { - genericUnions(data28, out28); + }] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["pointers::array_casts", (_237: rs.u8, data28: rs.ByteSlice, out28: rs.ByteVec): undefined => { + arrayCasts(data28, out28); + }] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["pointers::generic_unions", (_238: rs.u8, data29: rs.ByteSlice, out29: rs.ByteVec): undefined => { + genericUnions(data29, out29); }] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined]]); } diff --git a/ts/fixtures/lang/pointers/expected/pointers.ts b/ts/fixtures/lang/pointers/expected/pointers.ts index a059e4922..ee9a363b1 100644 --- a/ts/fixtures/lang/pointers/expected/pointers.ts +++ b/ts/fixtures/lang/pointers/expected/pointers.ts @@ -2980,6 +2980,87 @@ export function lent(n: rs.u8): rs.ByteVec { return o; } +/** + * Pointers to slices cast to ones to arrays of their elements, of bytes and of numbers: + * read whole, borrowed, and written through, at every offset; compared with the arrays + * std's safe casts give; cast past where the slice ends and read only where its elements + * are; and cast from null, dangling, and empty ones, which point at nothing. + */ +export function arrayCasts(data: rs.ByteSlice, out: rs.ByteVec): void { + let _9!: rs.usize; + let _91!: rs.usize; + const bytes: rs.ByteVec = rs.byteSliceToByteVec(data); + const _6: rs.usize = bytes.length; + let iterStart: rs.usize = 0; + const iterEnd: rs.usize = _6; + while ((_9 = iterStart++) < iterEnd) { + const at: rs.usize = _9; + const rest: rs.ByteSlice = rs.byteSliceRange(rs.byteVecSlice(bytes), at); + const pair: rs.ByteSlice = rs.rawByteSliceOf(rest).byteArray(2); + if (rest.length >= 2) { + rs.iterExtendBytes(out, rs.iterSlice(rs.byteSliceToArray(pair)), undefined, true); + rs.byteVecPush(out, rs.byteSliceSame(pair, rs.optionUnwrap(rs.byteSliceGetRange(rest, 0, 2))) ? 1 : 0); + rs.byteVecPush(out, rs.byteSliceSame(pair, rs.optionUnwrap(rs.byteSliceGetRange(rest, 0, 2))) ? 1 : 0); + } + const _43: rs.ByteSlice = rs.byteSliceFrom(rs.byteSliceView(rs.rawByteSliceOf(rs.byteSliceRange(rs.byteVecSlice(bytes), at)).byteArray(1))); + rs.byteVecPush(out, _43.data[_43.start]); + } + if (bytes.length >= 3) { + const part = rs.usizeSub(bytes.length, 3); + const _55: rs.ByteSlice = rs.rawByteSliceOf(rs.byteSliceRange(rs.byteVecSlice(bytes), part)).byteArray(3); + _55.data[_55.start] = _55.data[_55.start] ^ _55.data[_55.start + 2]; + rs.byteSliceView(_55).reverse(); + const _68: rs.ByteSlice = rs.rawByteSliceOf(rs.byteSliceRange(rs.byteVecSlice(bytes), 0)).byteArray(3); + const _72: rs.u8 = rs.u8WrappingAdd(_68.data[_68.start + 1], 1); + _68.data[_68.start + 1] = _72; + } + rs.iterExtendBytes(out, rs.iterSlice(rs.byteVecView(bytes)), undefined, true); + const words: rs.Vec = rs.iterToVec(rs.iterMap(rs.iterSlice(rs.byteSliceView(data)), (_2: rs.u8): rs.u32 => { + return rs.u32Mul(_2 as rs.u32, 65793); + }), undefined, 4, true); + const copy: rs.Vec = rs.vecFrom(words.items.slice()); + const _87: rs.usize = rs.usizeSaturatingSub(words.items.length, 1); + let iterStart2: rs.usize = 0; + const iterEnd2: rs.usize = _87; + while ((_91 = iterStart2++) < iterEnd2) { + const at2: rs.usize = _91; + const three: rs.Slice = rs.rawSliceOf(rs.sliceRange(rs.sliceFrom(words.items), at2)).array(3); + if (rs.usizeSub(words.items.length, at2) >= 3) { + rs.iterExtendBytes(out, rs.iterFlatMap(rs.iterSlice(rs.sliceToArray(three)), (w: rs.u32): Uint8Array => { + return rs.u32ToBeBytes(w).reverse(); + }, (value: Uint8Array) => rs.iterSlice(value), true, 4), undefined, true); + rs.byteVecPush(out, rs.sliceSame(three, rs.optionUnwrap(rs.sliceGetRange(rs.sliceRange(rs.sliceFrom(words.items), at2), 0, 3))) ? 1 : 0); + } + const _121: rs.Slice = rs.rawSliceOf(rs.sliceRange(rs.sliceFrom(copy.items), at2)).array(2); + rs.sliceSwap(_121, 0, 1); + _121.data[_121.start] = (_121.data[_121.start] ^ 257) >>> 0; + } + rs.iterExtendBytes(out, rs.iterFlatMap(rs.iterSlice(copy.items), (w2: rs.u32): Uint8Array => { + return rs.u32ToBeBytes(w2).reverse(); + }, (value: Uint8Array) => rs.iterSlice(value), true, 4), undefined, true); + const pairs: rs.Vec = rs.iterToVec(rs.iterMap(rs.iterSlice(rs.byteSliceView(data)), (_22: rs.u8): Uint8Array => { + const b2: rs.u8 = _22; + return Uint8Array.of(b2, ~b2 & 0xff); + }), undefined, 2, true); + if (pairs.items.length >= 3) { + const _142: rs.Slice = rs.rawSliceOf(rs.sliceRange(rs.sliceFrom(pairs.items), 1)).array(2); + _142.data[_142.start][1] = _142.data[_142.start][1] ^ _142.data[_142.start + 1][0]; + rs.sliceSwap(_142, 0, 1); + rs.iterExtendBytes(out, rs.iterFlatten(rs.iterLend(rs.iterSlice(rs.sliceToArray(rs.rawSliceOf(rs.sliceFrom(pairs.items)).array(3), copy$array_u8)), rs.byteSliceFrom), (value: rs.ByteSlice) => rs.iterSlice(rs.byteSliceView(value)), true, 2), undefined, true); + } + rs.iterExtendBytes(out, rs.iterFlatten(rs.iterLend(rs.iterSlice(pairs.items), rs.byteSliceFrom), (value: rs.ByteSlice) => rs.iterSlice(rs.byteSliceView(value)), true, 2), undefined, true); + const part2 = bytes.length; + rs.rawByteSliceOf(rs.byteSliceRange(rs.byteVecSlice(bytes), part2)); + rs.byteVecPush(out, rs.byteSliceFrom(Uint8Array.of()).length & 0xff); + let byte: rs.u8 = option_unwrapOr$1fr498u(rs.byteSliceFirst(data), 7); + const lone: rs.ByteSlice = new rs.RawSlice(rs.place(() => byte, (value) => byte = value), 0).byteArray(0); + rs.byteVecPush(out, lone === rs.NULL ? 1 : 0); + rs.byteVecPush(out, new rs.RawSlice(rs.byteSliceAsPtr(lone), 0).derefBytes(false).length & 0xff); + let word: rs.u32 = rs.u32Mul(byte as rs.u32, 3); + rs.iterExtendBytes(out, rs.iterSlice(rs.u32ToBeBytes(rs.sliceToArray(new rs.RawSlice(rs.place(() => word, (value2) => word = value2), 1).array(1))[0]).reverse()), undefined, true); + rs.iterExtendBytes(out, rs.iterSlice(Uint8Array.of(new rs.RawSlice(rs.NULL, 4).byteArray(4) === rs.NULL ? 1 : 0, rs.sliceSame(new rs.RawSlice(rs.DANGLING, 0).array(2), rs.DANGLING) ? 1 : 0)), undefined, true); +} + /** * Each instance of a union over a type parameter: written as one field, in part through * another and through a reference into it, and whole as a third, read as each, and copied diff --git a/ts/fixtures/lang/pointers/src/lib.rs b/ts/fixtures/lang/pointers/src/lib.rs index 78c55881b..a43a090d1 100644 --- a/ts/fixtures/lang/pointers/src/lib.rs +++ b/ts/fixtures/lang/pointers/src/lib.rs @@ -49,6 +49,7 @@ fn cases() -> Vec<(&'static str, Case)> { ("pointers::raw_arcs", |_, data, out| pointers::raw_arcs(data, out)), ("pointers::raw_places", |_, data, out| pointers::raw_places(data, out)), ("pointers::arrays", |_, data, out| pointers::arrays(data, out)), + ("pointers::array_casts", |_, data, out| pointers::array_casts(data, out)), ("pointers::generic_unions", |_, data, out| { pointers::generic_unions(data, out) }), diff --git a/ts/fixtures/lang/pointers/src/pointers.rs b/ts/fixtures/lang/pointers/src/pointers.rs index 53cf26155..f89770365 100644 --- a/ts/fixtures/lang/pointers/src/pointers.rs +++ b/ts/fixtures/lang/pointers/src/pointers.rs @@ -2411,6 +2411,76 @@ struct Holder { arr: [u32; 2], } +/// Pointers to slices cast to ones to arrays of their elements, of bytes and of numbers: +/// read whole, borrowed, and written through, at every offset; compared with the arrays +/// std's safe casts give; cast past where the slice ends and read only where its elements +/// are; and cast from null, dangling, and empty ones, which point at nothing. +pub fn array_casts(data: &[u8], out: &mut Vec) { + let mut bytes = data.to_vec(); + for at in 0..bytes.len() { + let rest = &bytes[at..]; + // Cast first, then read only where the slice reaches, as Rust allows. + let pair = rest as *const [u8] as *const [u8; 2]; + if rest.len() >= 2 { + out.extend(unsafe { *pair }); + let borrowed = unsafe { &*pair }; + out.push(u8::from(ptr::eq(borrowed, rest.first_chunk::<2>().unwrap()))); + out.push(u8::from(ptr::eq(pair, rest.first_chunk::<2>().unwrap()))); + } + let lent = NonNull::from(&bytes[at..]).cast::<[u8; 1]>(); + out.push(unsafe { lent.as_ref() }[0]); + } + if bytes.len() >= 3 { + let tail = bytes.len() - 3; + let quad = unsafe { &mut *(&mut bytes[tail..] as *mut [u8] as *mut [u8; 3]) }; + quad[0] ^= quad[2]; + quad.reverse(); + let whole = unsafe { &mut *(&raw mut bytes[..]).cast::<[u8; 3]>() }; + whole[1] = whole[1].wrapping_add(1); + } + out.extend(&bytes); + let words: Vec = data.iter().map(|&b| u32::from(b) * 65_793).collect(); + let mut copy = words.clone(); + for at in 0..words.len().saturating_sub(1) { + let three = &words[at..] as *const [u32] as *const [u32; 3]; + if words.len() - at >= 3 { + let read = unsafe { *three }; + out.extend(read.iter().flat_map(|w| w.to_le_bytes())); + out.push(u8::from(ptr::eq(three, words[at..].first_chunk::<3>().unwrap()))); + } + let first = unsafe { &mut *(&mut copy[at..] as *mut [u32] as *mut [u32; 2]) }; + first.swap(0, 1); + first[0] ^= 0x0101; + } + out.extend(copy.iter().flat_map(|w| w.to_le_bytes())); + let mut pairs: Vec<[u8; 2]> = data.iter().map(|&b| [b, !b]).collect(); + if pairs.len() >= 3 { + let two = unsafe { &mut *(&mut pairs[1..] as *mut [[u8; 2]] as *mut [[u8; 2]; 2]) }; + two[0][1] ^= two[1][0]; + two.swap(0, 1); + let read = unsafe { *(&pairs[..] as *const [[u8; 2]] as *const [[u8; 2]; 3]) }; + out.extend(read.iter().flatten()); + } + out.extend(pairs.iter().flatten()); + let empty: &[u8] = &bytes[bytes.len()..]; + let none = empty as *const [u8] as *const [u8; 0]; + out.push(unsafe { *none }.len() as u8); + // Values in no array, an empty slice of a byte and a whole one of a number. + let byte = data.first().copied().unwrap_or(7); + let lone = ptr::slice_from_raw_parts(&raw const byte, 0).cast::<[u8; 0]>(); + out.push(u8::from(lone.is_null())); + out.push(unsafe { &*(lone as *const [u8]) }.len() as u8); + let word = u32::from(byte) * 3; + let one = ptr::slice_from_raw_parts(&raw const word, 1) as *const [u32; 1]; + out.extend(unsafe { *one }[0].to_le_bytes()); + let null = ptr::slice_from_raw_parts(ptr::null::(), 4) as *const [u8; 4]; + let dangling = NonNull::<[u32]>::slice_from_raw_parts(NonNull::dangling(), 0).cast::<[u32; 2]>(); + out.extend([ + u8::from(null.is_null()), + u8::from(ptr::eq(dangling.as_ptr(), NonNull::dangling().as_ptr())), + ]); +} + /// A value beside a byte, which each instance of [`Either`] lays out at its own offsets. #[derive(Clone, Copy)] struct Tagged { diff --git a/ts/fixtures/reject/census.txt b/ts/fixtures/reject/census.txt index c528f2e62..fcc1ca045 100644 --- a/ts/fixtures/reject/census.txt +++ b/ts/fixtures/reject/census.txt @@ -192,6 +192,11 @@ fixtures/reject/src/pointers.rs:erased_empty+2:20: a pointer to `((), ())` cast fixtures/reject/src/pointers.rs:erased_place+2:2: a pointer to `u32` cast to one to `()`, whose JS value is a place of its own each borrow fixtures/reject/src/pointers.rs:erased_place+2:22: a pointer to `u32` cast to one to `()`, whose JS value is a place of its own each borrow fixtures/reject/src/pointers.rs:erased_start+2:2: a pointer to `pointers::Outer` cast to one to `()`, whose address its `pointers::Inner` at its start shares, which JS keeps as an object of its own +fixtures/reject/src/pointers.rs:lone_byte_arrays+2:13: a raw or mutable slice of a byte in no array of bytes +fixtures/reject/src/pointers.rs:lone_byte_arrays+3:17: a raw or mutable slice of a byte in no array of bytes +fixtures/reject/src/pointers.rs:lone_byte_arrays+5:13: a raw or mutable slice of a byte in no array of bytes +fixtures/reject/src/pointers.rs:lone_byte_arrays+6:39: a raw or mutable slice of a byte in no array of bytes +fixtures/reject/src/pointers.rs:lone_byte_arrays+7:44: a raw or mutable slice of a byte in no array of bytes fixtures/reject/src/pointers.rs:lone_byte_slices+1:12: a raw or mutable slice of a byte in no array of bytes fixtures/reject/src/pointers.rs:lone_byte_slices+2:19: a raw or mutable slice of a byte in no array of bytes fixtures/reject/src/pointers.rs:made_part_replaced+5:10: a raw pointer to `(u32, u32)` in `pointers::Gap`, which the crate may put another object in place of diff --git a/ts/fixtures/reject/expected.txt b/ts/fixtures/reject/expected.txt index d3a5d8ec1..aca92ddf3 100644 --- a/ts/fixtures/reject/expected.txt +++ b/ts/fixtures/reject/expected.txt @@ -194,6 +194,11 @@ fixtures/reject/src/pointers.rs:erased_empty+2:20: a pointer to `((), ())` cast fixtures/reject/src/pointers.rs:erased_place+2:2: a pointer to `u32` cast to one to `()`, whose JS value is a place of its own each borrow fixtures/reject/src/pointers.rs:erased_place+2:22: a pointer to `u32` cast to one to `()`, whose JS value is a place of its own each borrow fixtures/reject/src/pointers.rs:erased_start+2:2: a pointer to `pointers::Outer` cast to one to `()`, whose address its `pointers::Inner` at its start shares, which JS keeps as an object of its own +fixtures/reject/src/pointers.rs:lone_byte_arrays+2:13: a raw or mutable slice of a byte in no array of bytes +fixtures/reject/src/pointers.rs:lone_byte_arrays+3:17: a raw or mutable slice of a byte in no array of bytes +fixtures/reject/src/pointers.rs:lone_byte_arrays+5:13: a raw or mutable slice of a byte in no array of bytes +fixtures/reject/src/pointers.rs:lone_byte_arrays+6:39: a raw or mutable slice of a byte in no array of bytes +fixtures/reject/src/pointers.rs:lone_byte_arrays+7:44: a raw or mutable slice of a byte in no array of bytes fixtures/reject/src/pointers.rs:lone_byte_slices+1:12: a raw or mutable slice of a byte in no array of bytes fixtures/reject/src/pointers.rs:lone_byte_slices+2:19: a raw or mutable slice of a byte in no array of bytes fixtures/reject/src/pointers.rs:made_part_replaced+5:10: a raw pointer to `(u32, u32)` in `pointers::Gap`, which the crate may put another object in place of diff --git a/ts/fixtures/reject/src/pointers.rs b/ts/fixtures/reject/src/pointers.rs index 75e53e1ef..0f5a155c3 100644 --- a/ts/fixtures/reject/src/pointers.rs +++ b/ts/fixtures/reject/src/pointers.rs @@ -416,6 +416,19 @@ pub fn lone_byte_slices(mut b: u8) -> u8 { unsafe { (*raw)[0] } } +/// None of a byte in no array, cast to a pointer to bytes from it, which no `Uint8Array` +/// can share, though Rust reads nothing at the cast. +pub fn lone_byte_arrays(b: u8) -> bool { + let none = std::ptr::slice_from_raw_parts(&raw const b, 0); + let pair = none as *const [u8; 2]; + let one = none.cast::<[u8; 1]>(); + let empty = unsafe { std::slice::from_raw_parts(&raw const b, 0) }; + let lent = empty as *const [u8] as *const [u8; 1]; + let from = std::ptr::from_ref(empty).cast::<[u8; 1]>(); + let made = std::ptr::NonNull::from(empty).cast::<[u8; 1]>(); + pair.is_null() || one.is_null() || lent.is_null() || from.is_null() || made.as_ptr().is_null() +} + /// Pointers, slices, and copies the body shows reach out of an array of one or a copied /// subslice, where Rust's reach the rest of what holds them. pub fn reached_out(h: Halves, lanes: [u32; 4]) -> u32 { diff --git a/ts/fixtures/reject/ts.toml b/ts/fixtures/reject/ts.toml index 99304f296..be4ba8734 100644 --- a/ts/fixtures/reject/ts.toml +++ b/ts/fixtures/reject/ts.toml @@ -145,6 +145,7 @@ roots = [ "pointers::erased_empty", "pointers::erased_place", "pointers::erased_start", + "pointers::lone_byte_arrays", "pointers::lone_byte_slices", "pointers::made_part_replaced", "pointers::nonnull_reassigned", diff --git a/ts/fixtures/stock/expected/buf.Counted.ts b/ts/fixtures/stock/expected/buf.Counted.ts index 5691e97da..932d3d0ea 100644 --- a/ts/fixtures/stock/expected/buf.Counted.ts +++ b/ts/fixtures/stock/expected/buf.Counted.ts @@ -129,6 +129,48 @@ export function drop$ops_Drop(self: Counted): void { rs.cellSet(self._1.value, rs.u8Add(self._1.value.v, 1)); } +/** + * Fills `dst` with potentially multiple slices starting at `self`'s + * current position. + * + * If the `Buf` is backed by disjoint slices of bytes, `chunk_vectored` enables + * fetching more than one slice at once. `dst` is a slice of `IoSlice` + * references, enabling the slice to be directly used with [`writev`] + * without any further conversion. The sum of the lengths of all the + * buffers written to `dst` will be less than or equal to `Buf::remaining()`. + * + * The entries in `dst` will be overwritten, but the data **contained** by + * the slices **will not** be modified. The return value is the number of + * slices written to `dst`. If `Buf::remaining()` is non-zero, then this + * writes at least one non-empty slice to `dst`. + * + * This is a lower level function. Most operations are done with other + * functions. + * + * # Implementer notes + * + * This function should never panic. Once the end of the buffer is reached, + * i.e., `Buf::remaining` returns 0, calls to `chunk_vectored` must return 0 + * without mutating `dst`. + * + * Implementations should also take care to properly handle being called + * with `dst` being a zero length slice. + * + * [`writev`]: http://man7.org/linux/man-pages/man2/readv.2.html + */ +export function chunksVectored$bytes_Buf(self: Counted, dst: rs.Slice): rs.usize { + if (!(dst.length === 0)) { + if (!hasRemaining$bytes_Buf(self)) { + return 0; + } + const _6: rs.ByteSlice = chunk$bytes_Buf(self); + rs.idx(dst, 0); + dst.data[dst.start] = _6; + return 1; + } + return 0; +} + /** * Returns true if there are any more bytes to consume * diff --git a/ts/fixtures/stock/expected/buf.Leased.ts b/ts/fixtures/stock/expected/buf.Leased.ts index d4ae7fded..c1228ca05 100644 --- a/ts/fixtures/stock/expected/buf.Leased.ts +++ b/ts/fixtures/stock/expected/buf.Leased.ts @@ -6,6 +6,6 @@ import type * as TryGetError from "./bytes.TryGetError.ts"; /** A buffer of the crate's own over `Buf`, as moq's transports lend a stream's chunks. */ export type Leased = - | { pieces$Leased: () => rs.usize; skip$Leased: (a0: Buf.Buf) => void; remaining$Buf: () => rs.usize; chunk$Buf: () => rs.ByteSlice; advance$Buf: (a0: rs.usize) => void; hasRemaining$Buf: () => boolean; copyToSlice$Buf: (a0: rs.ByteSlice) => void; getU8$Buf: () => rs.u8; getI8$Buf: () => rs.i8; getU16$Buf: () => rs.u16; getU16Le$Buf: () => rs.u16; getU16Ne$Buf: () => rs.u16; getI16$Buf: () => rs.i16; getI16Le$Buf: () => rs.i16; getI16Ne$Buf: () => rs.i16; getU32$Buf: () => rs.u32; getU32Le$Buf: () => rs.u32; getU32Ne$Buf: () => rs.u32; getI32$Buf: () => rs.i32; getI32Le$Buf: () => rs.i32; getI32Ne$Buf: () => rs.i32; getU64$Buf: () => rs.u64; getU64Le$Buf: () => rs.u64; getU64Ne$Buf: () => rs.u64; getI64$Buf: () => rs.i64; getI64Le$Buf: () => rs.i64; getI64Ne$Buf: () => rs.i64; getU128$Buf: () => rs.u128; getU128Le$Buf: () => rs.u128; getU128Ne$Buf: () => rs.u128; getI128$Buf: () => rs.i128; getI128Le$Buf: () => rs.i128; getI128Ne$Buf: () => rs.i128; getUint$Buf: (a0: rs.usize) => rs.u64; getUintLe$Buf: (a0: rs.usize) => rs.u64; getUintNe$Buf: (a0: rs.usize) => rs.u64; getInt$Buf: (a0: rs.usize) => rs.i64; getIntLe$Buf: (a0: rs.usize) => rs.i64; getIntNe$Buf: (a0: rs.usize) => rs.i64; getF32$Buf: () => rs.f32; getF32Le$Buf: () => rs.f32; getF32Ne$Buf: () => rs.f32; getF64$Buf: () => rs.f64; getF64Le$Buf: () => rs.f64; getF64Ne$Buf: () => rs.f64; tryCopyToSlice$Buf: (a0: rs.ByteSlice) => rs.Result; tryGetU8$Buf: () => rs.Result; tryGetI8$Buf: () => rs.Result; tryGetU16$Buf: () => rs.Result; tryGetU16Le$Buf: () => rs.Result; tryGetU16Ne$Buf: () => rs.Result; tryGetI16$Buf: () => rs.Result; tryGetI16Le$Buf: () => rs.Result; tryGetI16Ne$Buf: () => rs.Result; tryGetU32$Buf: () => rs.Result; tryGetU32Le$Buf: () => rs.Result; tryGetU32Ne$Buf: () => rs.Result; tryGetI32$Buf: () => rs.Result; tryGetI32Le$Buf: () => rs.Result; tryGetI32Ne$Buf: () => rs.Result; tryGetU64$Buf: () => rs.Result; tryGetU64Le$Buf: () => rs.Result; tryGetU64Ne$Buf: () => rs.Result; tryGetI64$Buf: () => rs.Result; tryGetI64Le$Buf: () => rs.Result; tryGetI64Ne$Buf: () => rs.Result; tryGetU128$Buf: () => rs.Result; tryGetU128Le$Buf: () => rs.Result; tryGetU128Ne$Buf: () => rs.Result; tryGetI128$Buf: () => rs.Result; tryGetI128Le$Buf: () => rs.Result; tryGetI128Ne$Buf: () => rs.Result; tryGetUint$Buf: (a0: rs.usize) => rs.Result; tryGetUintLe$Buf: (a0: rs.usize) => rs.Result; tryGetUintNe$Buf: (a0: rs.usize) => rs.Result; tryGetInt$Buf: (a0: rs.usize) => rs.Result; tryGetIntLe$Buf: (a0: rs.usize) => rs.Result; tryGetIntNe$Buf: (a0: rs.usize) => rs.Result; tryGetF32$Buf: () => rs.Result; tryGetF32Le$Buf: () => rs.Result; tryGetF32Ne$Buf: () => rs.Result; tryGetF64$Buf: () => rs.Result; tryGetF64Le$Buf: () => rs.Result; tryGetF64Ne$Buf: () => rs.Result; copyToBytes$Buf: (a0: rs.usize) => rs.ByteSlice }; + | { pieces$Leased: () => rs.usize; skip$Leased: (a0: Buf.Buf) => void; remaining$Buf: () => rs.usize; chunk$Buf: () => rs.ByteSlice; chunksVectored$Buf: (a0: rs.Slice) => rs.usize; advance$Buf: (a0: rs.usize) => void; hasRemaining$Buf: () => boolean; copyToSlice$Buf: (a0: rs.ByteSlice) => void; getU8$Buf: () => rs.u8; getI8$Buf: () => rs.i8; getU16$Buf: () => rs.u16; getU16Le$Buf: () => rs.u16; getU16Ne$Buf: () => rs.u16; getI16$Buf: () => rs.i16; getI16Le$Buf: () => rs.i16; getI16Ne$Buf: () => rs.i16; getU32$Buf: () => rs.u32; getU32Le$Buf: () => rs.u32; getU32Ne$Buf: () => rs.u32; getI32$Buf: () => rs.i32; getI32Le$Buf: () => rs.i32; getI32Ne$Buf: () => rs.i32; getU64$Buf: () => rs.u64; getU64Le$Buf: () => rs.u64; getU64Ne$Buf: () => rs.u64; getI64$Buf: () => rs.i64; getI64Le$Buf: () => rs.i64; getI64Ne$Buf: () => rs.i64; getU128$Buf: () => rs.u128; getU128Le$Buf: () => rs.u128; getU128Ne$Buf: () => rs.u128; getI128$Buf: () => rs.i128; getI128Le$Buf: () => rs.i128; getI128Ne$Buf: () => rs.i128; getUint$Buf: (a0: rs.usize) => rs.u64; getUintLe$Buf: (a0: rs.usize) => rs.u64; getUintNe$Buf: (a0: rs.usize) => rs.u64; getInt$Buf: (a0: rs.usize) => rs.i64; getIntLe$Buf: (a0: rs.usize) => rs.i64; getIntNe$Buf: (a0: rs.usize) => rs.i64; getF32$Buf: () => rs.f32; getF32Le$Buf: () => rs.f32; getF32Ne$Buf: () => rs.f32; getF64$Buf: () => rs.f64; getF64Le$Buf: () => rs.f64; getF64Ne$Buf: () => rs.f64; tryCopyToSlice$Buf: (a0: rs.ByteSlice) => rs.Result; tryGetU8$Buf: () => rs.Result; tryGetI8$Buf: () => rs.Result; tryGetU16$Buf: () => rs.Result; tryGetU16Le$Buf: () => rs.Result; tryGetU16Ne$Buf: () => rs.Result; tryGetI16$Buf: () => rs.Result; tryGetI16Le$Buf: () => rs.Result; tryGetI16Ne$Buf: () => rs.Result; tryGetU32$Buf: () => rs.Result; tryGetU32Le$Buf: () => rs.Result; tryGetU32Ne$Buf: () => rs.Result; tryGetI32$Buf: () => rs.Result; tryGetI32Le$Buf: () => rs.Result; tryGetI32Ne$Buf: () => rs.Result; tryGetU64$Buf: () => rs.Result; tryGetU64Le$Buf: () => rs.Result; tryGetU64Ne$Buf: () => rs.Result; tryGetI64$Buf: () => rs.Result; tryGetI64Le$Buf: () => rs.Result; tryGetI64Ne$Buf: () => rs.Result; tryGetU128$Buf: () => rs.Result; tryGetU128Le$Buf: () => rs.Result; tryGetU128Ne$Buf: () => rs.Result; tryGetI128$Buf: () => rs.Result; tryGetI128Le$Buf: () => rs.Result; tryGetI128Ne$Buf: () => rs.Result; tryGetUint$Buf: (a0: rs.usize) => rs.Result; tryGetUintLe$Buf: (a0: rs.usize) => rs.Result; tryGetUintNe$Buf: (a0: rs.usize) => rs.Result; tryGetInt$Buf: (a0: rs.usize) => rs.Result; tryGetIntLe$Buf: (a0: rs.usize) => rs.Result; tryGetIntNe$Buf: (a0: rs.usize) => rs.Result; tryGetF32$Buf: () => rs.Result; tryGetF32Le$Buf: () => rs.Result; tryGetF32Ne$Buf: () => rs.Result; tryGetF64$Buf: () => rs.Result; tryGetF64Le$Buf: () => rs.Result; tryGetF64Ne$Buf: () => rs.Result; copyToBytes$Buf: (a0: rs.usize) => rs.ByteSlice }; //# sourceMappingURL=buf.Leased.ts.map diff --git a/ts/fixtures/stock/expected/buf.Pieces.ts b/ts/fixtures/stock/expected/buf.Pieces.ts index 4d30447e8..9637ce837 100644 --- a/ts/fixtures/stock/expected/buf.Pieces.ts +++ b/ts/fixtures/stock/expected/buf.Pieces.ts @@ -7,7 +7,7 @@ import { panicAdvance, panicDoesNotFit } from "./bytes.ts"; import { signExtend, hasRemaining$bytes_Buf_mut_dyn_bytes_Buf, remaining$bytes_Buf_mut_dyn_bytes_Buf as buf_impl_remaining$bytes_Buf_mut_dyn_bytes_Buf } from "./bytes/buf/buf_impl.ts"; import type * as Buf from "./bytes/buf/buf_impl.Buf.ts"; import * as Chain from "./bytes/buf/chain.Chain.ts"; -import { new_$mut_buf_Pieces as take_new_$mut_buf_Pieces } from "./bytes/buf/take.ts"; +import { new_$buf_Pieces as take_new_$buf_Pieces, new_$mut_buf_Pieces as take_new_$mut_buf_Pieces } from "./bytes/buf/take.ts"; import type * as Take from "./bytes/buf/take.Take.ts"; import type * as TryGetError from "./bytes.TryGetError.ts"; import { unwrapOrElse$1b4ownx as result_unwrapOrElse$1b4ownx, unwrapOrElse$1fg63zn as result_unwrapOrElse$1fg63zn } from "./core/result.ts"; @@ -199,6 +199,48 @@ export function skip$buf_Leased(self: Pieces, other: Buf.Buf): void { advance$bytes_Buf(self, _7); } +/** + * Fills `dst` with potentially multiple slices starting at `self`'s + * current position. + * + * If the `Buf` is backed by disjoint slices of bytes, `chunk_vectored` enables + * fetching more than one slice at once. `dst` is a slice of `IoSlice` + * references, enabling the slice to be directly used with [`writev`] + * without any further conversion. The sum of the lengths of all the + * buffers written to `dst` will be less than or equal to `Buf::remaining()`. + * + * The entries in `dst` will be overwritten, but the data **contained** by + * the slices **will not** be modified. The return value is the number of + * slices written to `dst`. If `Buf::remaining()` is non-zero, then this + * writes at least one non-empty slice to `dst`. + * + * This is a lower level function. Most operations are done with other + * functions. + * + * # Implementer notes + * + * This function should never panic. Once the end of the buffer is reached, + * i.e., `Buf::remaining` returns 0, calls to `chunk_vectored` must return 0 + * without mutating `dst`. + * + * Implementations should also take care to properly handle being called + * with `dst` being a zero length slice. + * + * [`writev`]: http://man7.org/linux/man-pages/man2/readv.2.html + */ +export function chunksVectored$bytes_Buf(self: Pieces, dst: rs.Slice): rs.usize { + if (!(dst.length === 0)) { + if (!hasRemaining$bytes_Buf(self)) { + return 0; + } + const _6: rs.ByteSlice = chunk$bytes_Buf(self); + rs.idx(dst, 0); + dst.data[dst.start] = _6; + return 1; + } + return 0; +} + /** * Returns true if there are any more bytes to consume * @@ -1230,6 +1272,33 @@ export function tryGetF64Ne$bytes_Buf(self: Pieces): rs.f64 | undefined { return undefined; } +/** + * Creates an adaptor which will read at most `limit` bytes from `self`. + * + * This function returns a new instance of `Buf` which will read at most + * `limit` bytes. + * + * # Examples + * + * ``` + * use bytes::{Buf, BufMut}; + * + * let mut buf = b"hello world"[..].take(5); + * let mut dst = vec![]; + * + * dst.put(&mut buf); + * assert_eq!(dst, b"hello"); + * + * let mut buf = buf.into_inner(); + * dst.clear(); + * dst.put(&mut buf); + * assert_eq!(dst, b" world"); + * ``` + */ +export function take$bytes_Buf(self: Pieces, limit: rs.usize): Take.Take { + return take_new_$buf_Pieces(self, limit); +} + /** * Creates an adaptor which will read at most `limit` bytes from `self`. * @@ -1278,6 +1347,27 @@ export function chain$bytes_Buf_buf_Provided(self: Pieces, next: Provided.Provid return Chain.new$buf_Pieces_buf_Provided(self, next); } +/** + * Creates an adaptor which will chain this buffer with another. + * + * The returned `Buf` instance will first consume all bytes from `self`. + * Afterwards the output is equivalent to the output of next. + * + * # Examples + * + * ``` + * use bytes::Buf; + * + * let mut chain = b"hello "[..].chain(&b"world"[..]); + * + * let full = chain.copy_to_bytes(11); + * assert_eq!(full.chunk(), b"hello world"); + * ``` + */ +export function chain$bytes_Buf_bytes_Bytes(self: Pieces, next: rs.ByteSlice): Chain.Chain { + return Chain.new$buf_Pieces_bytes_Bytes(self, next); +} + /** * Advance the internal cursor of the Buf * diff --git a/ts/fixtures/stock/expected/buf.Provided.ts b/ts/fixtures/stock/expected/buf.Provided.ts index 7dbf423b2..7c15be672 100644 --- a/ts/fixtures/stock/expected/buf.Provided.ts +++ b/ts/fixtures/stock/expected/buf.Provided.ts @@ -120,6 +120,48 @@ export function advance$bytes_Buf(self: Provided, cnt: rs.usize): void { Pieces.advance$bytes_Buf(self._0, cnt); } +/** + * Fills `dst` with potentially multiple slices starting at `self`'s + * current position. + * + * If the `Buf` is backed by disjoint slices of bytes, `chunk_vectored` enables + * fetching more than one slice at once. `dst` is a slice of `IoSlice` + * references, enabling the slice to be directly used with [`writev`] + * without any further conversion. The sum of the lengths of all the + * buffers written to `dst` will be less than or equal to `Buf::remaining()`. + * + * The entries in `dst` will be overwritten, but the data **contained** by + * the slices **will not** be modified. The return value is the number of + * slices written to `dst`. If `Buf::remaining()` is non-zero, then this + * writes at least one non-empty slice to `dst`. + * + * This is a lower level function. Most operations are done with other + * functions. + * + * # Implementer notes + * + * This function should never panic. Once the end of the buffer is reached, + * i.e., `Buf::remaining` returns 0, calls to `chunk_vectored` must return 0 + * without mutating `dst`. + * + * Implementations should also take care to properly handle being called + * with `dst` being a zero length slice. + * + * [`writev`]: http://man7.org/linux/man-pages/man2/readv.2.html + */ +export function chunksVectored$bytes_Buf(self: Provided, dst: rs.Slice): rs.usize { + if (!(dst.length === 0)) { + if (!hasRemaining$bytes_Buf(self)) { + return 0; + } + const _6: rs.ByteSlice = chunk$bytes_Buf(self); + rs.idx(dst, 0); + dst.data[dst.start] = _6; + return 1; + } + return 0; +} + /** * Returns true if there are any more bytes to consume * diff --git a/ts/fixtures/stock/expected/buf.ts b/ts/fixtures/stock/expected/buf.ts index 1c378b78e..74747c0bd 100644 --- a/ts/fixtures/stock/expected/buf.ts +++ b/ts/fixtures/stock/expected/buf.ts @@ -1,7 +1,7 @@ // Generated by rust2-ts. Do not edit. import * as rs from "./rs.ts"; -import { drop$Option_bytes_Bytes as lib_drop$Option_bytes_Bytes, drop$Result_bytes_BytesMut_bytes_Bytes as lib_drop$Result_bytes_BytesMut_bytes_Bytes, drop$bytes_buf_Chain_buf_Provided_bytes_Bytes as lib_drop$bytes_buf_Chain_buf_Provided_bytes_Bytes, drop$bytes_buf_Chain_bytes_Bytes_bytes_buf_Chain_buf_Provided_ref_slice_u8 as lib_drop$bytes_buf_Chain_bytes_Bytes_bytes_buf_Chain_buf_Provided_ref_slice_u8, drop$bytes_buf_Chain_bytes_Bytes_ref_slice_u8 as lib_drop$bytes_buf_Chain_bytes_Bytes_ref_slice_u8, drop$bytes_buf_Chain_bytes_buf_Chain_ref_slice_u8_bytes_Bytes_buf_Pieces as lib_drop$bytes_buf_Chain_bytes_buf_Chain_ref_slice_u8_bytes_Bytes_buf_Pieces, drop$bytes_buf_Chain_bytes_buf_Take_bytes_Bytes_buf_Pieces as lib_drop$bytes_buf_Chain_bytes_buf_Take_bytes_Bytes_buf_Pieces, drop$bytes_buf_Take_bytes_Bytes as lib_drop$bytes_buf_Take_bytes_Bytes, of$buf_Counted, of$buf_Pieces, of$buf_Provided, of$bytes_Bytes, of$bytes_BytesMut, of$bytes_buf_Chain_buf_Provided_mut_ref_slice_u8, of$bytes_buf_Chain_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_Bytes_ref_slice_u8, of$bytes_buf_Take_bytes_Bytes, of$bytes_buf_Take_ref_slice_u8, of$ref_slice_u8, ofPlace$bytes_Bytes, ofPlace$ref_slice_u8, out$i64, out$u128, out$u16, out$u8 } from "./lib.ts"; +import { drop$Option_bytes_Bytes as lib_drop$Option_bytes_Bytes, drop$Result_bytes_BytesMut_bytes_Bytes as lib_drop$Result_bytes_BytesMut_bytes_Bytes, drop$bytes_buf_Chain_buf_Provided_bytes_Bytes as lib_drop$bytes_buf_Chain_buf_Provided_bytes_Bytes, drop$bytes_buf_Chain_bytes_Bytes_bytes_buf_Chain_buf_Provided_ref_slice_u8 as lib_drop$bytes_buf_Chain_bytes_Bytes_bytes_buf_Chain_buf_Provided_ref_slice_u8, drop$bytes_buf_Chain_bytes_Bytes_ref_slice_u8 as lib_drop$bytes_buf_Chain_bytes_Bytes_ref_slice_u8, drop$bytes_buf_Chain_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as lib_drop$bytes_buf_Chain_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, drop$bytes_buf_Chain_bytes_buf_Chain_ref_slice_u8_bytes_Bytes_buf_Pieces as lib_drop$bytes_buf_Chain_bytes_buf_Chain_ref_slice_u8_bytes_Bytes_buf_Pieces, drop$bytes_buf_Chain_bytes_buf_Take_bytes_Bytes_buf_Pieces as lib_drop$bytes_buf_Chain_bytes_buf_Take_bytes_Bytes_buf_Pieces, drop$bytes_buf_Take_bytes_Bytes as lib_drop$bytes_buf_Take_bytes_Bytes, of$buf_Counted, of$buf_Pieces, of$buf_Provided, of$bytes_Bytes, of$bytes_BytesMut, of$bytes_buf_Chain_buf_Provided_mut_ref_slice_u8, of$bytes_buf_Chain_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_Bytes_ref_slice_u8, of$bytes_buf_Chain_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, of$bytes_buf_Take_bytes_Bytes, of$bytes_buf_Take_ref_slice_u8, of$ref_slice_u8, ofPlace$bytes_Bytes, ofPlace$ref_slice_u8, out$i64, out$u128, out$u16, out$u8 } from "./lib.ts"; import * as buf_Counted from "./buf.Counted.ts"; import * as Fixed from "./buf.Fixed.ts"; import type * as Leased from "./buf.Leased.ts"; @@ -10,13 +10,13 @@ import * as Pieces from "./buf.Pieces.ts"; import * as Provided from "./buf.Provided.ts"; import * as Spare from "./buf.Spare.ts"; import * as Tagged from "./buf.Tagged.ts"; -import { copyToSlice$bytes_Buf_collections_VecDeque_u8, getU8$bytes_Buf_collections_VecDeque_u8, getI8$bytes_Buf_collections_VecDeque_u8, getUint$bytes_Buf_collections_VecDeque_u8, getIntLe$bytes_Buf_collections_VecDeque_u8, getF32Le$bytes_Buf_collections_VecDeque_u8, getF64$bytes_Buf_collections_VecDeque_u8, tryGetU8$bytes_Buf_bytes_Bytes, tryGetU8$bytes_Buf_bytes_BytesMut, tryGetU8$bytes_Buf_collections_VecDeque_u8, tryGetU8$bytes_Buf_ref_slice_u8, take$bytes_Buf_bytes_Bytes as buf_impl_take$bytes_Buf_bytes_Bytes, take$bytes_Buf_ref_slice_u8 as buf_impl_take$bytes_Buf_ref_slice_u8, chain$bytes_Buf_boxed_Box_dyn_bytes_Buf_bytes_Bytes, chain$bytes_Buf_bytes_Bytes_bytes_buf_Chain_buf_Provided_ref_slice_u8, chain$bytes_Buf_bytes_Bytes_ref_slice_u8, chain$bytes_Buf_ref_slice_u8_bytes_Bytes, chain$bytes_Buf_ref_slice_u8_bytes_BytesMut, advance$bytes_Buf_mut_bytes_Bytes as buf_impl_advance$bytes_Buf_mut_bytes_Bytes, advance$bytes_Buf_mut_collections_VecDeque_u8 as buf_impl_advance$bytes_Buf_mut_collections_VecDeque_u8, advance$bytes_Buf_mut_dyn_bytes_Buf as buf_impl_advance$bytes_Buf_mut_dyn_bytes_Buf, advance$bytes_Buf_mut_ref_slice_u8 as buf_impl_advance$bytes_Buf_mut_ref_slice_u8, copyToBytes$bytes_Buf_mut_bytes_Bytes, copyToBytes$bytes_Buf_mut_collections_VecDeque_u8, copyToBytes$bytes_Buf_mut_dyn_bytes_Buf, copyToBytes$bytes_Buf_mut_ref_slice_u8, copyToSlice$bytes_Buf_mut_bytes_Bytes, copyToSlice$bytes_Buf_mut_collections_VecDeque_u8, copyToSlice$bytes_Buf_mut_dyn_bytes_Buf, copyToSlice$bytes_Buf_mut_ref_slice_u8, getF32Le$bytes_Buf_mut_bytes_Bytes, getF32Le$bytes_Buf_mut_collections_VecDeque_u8, getF32Le$bytes_Buf_mut_dyn_bytes_Buf, getF32Le$bytes_Buf_mut_ref_slice_u8, getF64$bytes_Buf_mut_bytes_Bytes, getF64$bytes_Buf_mut_collections_VecDeque_u8, getF64$bytes_Buf_mut_dyn_bytes_Buf, getF64$bytes_Buf_mut_ref_slice_u8, getI128$bytes_Buf_mut_bytes_Bytes, getI128$bytes_Buf_mut_collections_VecDeque_u8, getI128$bytes_Buf_mut_dyn_bytes_Buf, getI128$bytes_Buf_mut_ref_slice_u8, getI16Le$bytes_Buf_mut_bytes_Bytes, getI16Le$bytes_Buf_mut_collections_VecDeque_u8, getI16Le$bytes_Buf_mut_dyn_bytes_Buf, getI16Le$bytes_Buf_mut_ref_slice_u8, getI32$bytes_Buf_mut_bytes_Bytes, getI32$bytes_Buf_mut_collections_VecDeque_u8, getI32$bytes_Buf_mut_dyn_bytes_Buf, getI32$bytes_Buf_mut_ref_slice_u8, getI64Le$bytes_Buf_mut_bytes_Bytes, getI64Le$bytes_Buf_mut_collections_VecDeque_u8, getI64Le$bytes_Buf_mut_dyn_bytes_Buf, getI64Le$bytes_Buf_mut_ref_slice_u8, getI8$bytes_Buf_mut_bytes_Bytes, getI8$bytes_Buf_mut_collections_VecDeque_u8, getI8$bytes_Buf_mut_dyn_bytes_Buf, getI8$bytes_Buf_mut_ref_slice_u8, getIntLe$bytes_Buf_mut_bytes_Bytes, getIntLe$bytes_Buf_mut_collections_VecDeque_u8, getIntLe$bytes_Buf_mut_dyn_bytes_Buf, getIntLe$bytes_Buf_mut_ref_slice_u8, getU128Le$bytes_Buf_mut_bytes_Bytes, getU128Le$bytes_Buf_mut_collections_VecDeque_u8, getU128Le$bytes_Buf_mut_dyn_bytes_Buf, getU128Le$bytes_Buf_mut_ref_slice_u8, getU16$bytes_Buf_mut_bytes_Bytes, getU16$bytes_Buf_mut_collections_VecDeque_u8, getU16$bytes_Buf_mut_dyn_bytes_Buf, getU16$bytes_Buf_mut_ref_slice_u8, getU32Le$bytes_Buf_mut_bytes_Bytes, getU32Le$bytes_Buf_mut_collections_VecDeque_u8, getU32Le$bytes_Buf_mut_dyn_bytes_Buf, getU32Le$bytes_Buf_mut_ref_slice_u8, getU64$bytes_Buf_mut_bytes_Bytes, getU64$bytes_Buf_mut_collections_VecDeque_u8, getU64$bytes_Buf_mut_dyn_bytes_Buf, getU64$bytes_Buf_mut_ref_slice_u8, getU8$bytes_Buf_mut_bytes_Bytes, getU8$bytes_Buf_mut_collections_VecDeque_u8, getU8$bytes_Buf_mut_dyn_bytes_Buf, getU8$bytes_Buf_mut_ref_slice_u8, getUint$bytes_Buf_mut_bytes_Bytes, getUint$bytes_Buf_mut_collections_VecDeque_u8, getUint$bytes_Buf_mut_dyn_bytes_Buf, getUint$bytes_Buf_mut_ref_slice_u8, hasRemaining$bytes_Buf_mut_boxed_Box_dyn_bytes_Buf, hasRemaining$bytes_Buf_mut_bytes_Bytes, hasRemaining$bytes_Buf_mut_bytes_BytesMut, hasRemaining$bytes_Buf_mut_dyn_buf_Leased, hasRemaining$bytes_Buf_mut_dyn_bytes_Buf, hasRemaining$bytes_Buf_mut_mut_bytes_Bytes, hasRemaining$bytes_Buf_mut_mut_collections_VecDeque_u8, hasRemaining$bytes_Buf_mut_mut_dyn_bytes_Buf, hasRemaining$bytes_Buf_mut_mut_ref_slice_u8, hasRemaining$bytes_Buf_mut_ref_slice_u8, remaining$bytes_Buf_mut_boxed_Box_dyn_bytes_Buf as buf_impl_remaining$bytes_Buf_mut_boxed_Box_dyn_bytes_Buf, remaining$bytes_Buf_mut_bytes_Bytes as buf_impl_remaining$bytes_Buf_mut_bytes_Bytes, remaining$bytes_Buf_mut_bytes_BytesMut as buf_impl_remaining$bytes_Buf_mut_bytes_BytesMut, remaining$bytes_Buf_mut_dyn_buf_Leased as buf_impl_remaining$bytes_Buf_mut_dyn_buf_Leased, remaining$bytes_Buf_mut_dyn_bytes_Buf as buf_impl_remaining$bytes_Buf_mut_dyn_bytes_Buf, remaining$bytes_Buf_mut_mut_bytes_Bytes as buf_impl_remaining$bytes_Buf_mut_mut_bytes_Bytes, remaining$bytes_Buf_mut_mut_collections_VecDeque_u8 as buf_impl_remaining$bytes_Buf_mut_mut_collections_VecDeque_u8, remaining$bytes_Buf_mut_mut_dyn_bytes_Buf as buf_impl_remaining$bytes_Buf_mut_mut_dyn_bytes_Buf, remaining$bytes_Buf_mut_mut_ref_slice_u8 as buf_impl_remaining$bytes_Buf_mut_mut_ref_slice_u8, remaining$bytes_Buf_mut_ref_slice_u8 as buf_impl_remaining$bytes_Buf_mut_ref_slice_u8, tryGetI64Le$bytes_Buf_mut_bytes_Bytes, tryGetI64Le$bytes_Buf_mut_collections_VecDeque_u8, tryGetI64Le$bytes_Buf_mut_dyn_bytes_Buf, tryGetI64Le$bytes_Buf_mut_ref_slice_u8, tryGetU128$bytes_Buf_mut_bytes_Bytes, tryGetU128$bytes_Buf_mut_collections_VecDeque_u8, tryGetU128$bytes_Buf_mut_dyn_bytes_Buf, tryGetU128$bytes_Buf_mut_ref_slice_u8, tryGetU16$bytes_Buf_mut_bytes_Bytes, tryGetU16$bytes_Buf_mut_collections_VecDeque_u8, tryGetU16$bytes_Buf_mut_dyn_bytes_Buf, tryGetU16$bytes_Buf_mut_ref_slice_u8, tryGetU8$bytes_Buf_mut_bytes_Bytes, tryGetU8$bytes_Buf_mut_collections_VecDeque_u8, tryGetU8$bytes_Buf_mut_dyn_bytes_Buf, tryGetU8$bytes_Buf_mut_ref_slice_u8, advance$bytes_Buf_boxed_Box_dyn_bytes_Buf as buf_impl_advance$bytes_Buf_boxed_Box_dyn_bytes_Buf, copyToBytes$bytes_Buf_boxed_Box_dyn_bytes_Buf, copyToSlice$bytes_Buf_boxed_Box_dyn_bytes_Buf, getF32Le$bytes_Buf_boxed_Box_dyn_bytes_Buf, getF64$bytes_Buf_boxed_Box_dyn_bytes_Buf, getI128$bytes_Buf_boxed_Box_dyn_bytes_Buf, getI16Le$bytes_Buf_boxed_Box_dyn_bytes_Buf, getI16Ne$bytes_Buf_boxed_Box_dyn_bytes_Buf, getI32$bytes_Buf_boxed_Box_dyn_bytes_Buf, getI64Le$bytes_Buf_boxed_Box_dyn_bytes_Buf, getI8$bytes_Buf_boxed_Box_dyn_bytes_Buf, getIntLe$bytes_Buf_boxed_Box_dyn_bytes_Buf, getU128Le$bytes_Buf_boxed_Box_dyn_bytes_Buf, getU16$bytes_Buf_boxed_Box_dyn_bytes_Buf, getU32Le$bytes_Buf_boxed_Box_dyn_bytes_Buf, getU64$bytes_Buf_boxed_Box_dyn_bytes_Buf, getU8$bytes_Buf_boxed_Box_dyn_bytes_Buf, getUint$bytes_Buf_boxed_Box_dyn_bytes_Buf, remaining$bytes_Buf_boxed_Box_dyn_bytes_Buf as buf_impl_remaining$bytes_Buf_boxed_Box_dyn_bytes_Buf, tryGetI64Le$bytes_Buf_boxed_Box_dyn_bytes_Buf, tryGetU128$bytes_Buf_boxed_Box_dyn_bytes_Buf, tryGetU16$bytes_Buf_boxed_Box_dyn_bytes_Buf, tryGetU8$bytes_Buf_boxed_Box_dyn_bytes_Buf } from "./bytes/buf/buf_impl.ts"; +import { chunksVectored$bytes_Buf_bytes_Bytes as buf_impl_chunksVectored$bytes_Buf_bytes_Bytes, chunksVectored$bytes_Buf_bytes_BytesMut as buf_impl_chunksVectored$bytes_Buf_bytes_BytesMut, chunksVectored$bytes_Buf_ref_slice_u8 as buf_impl_chunksVectored$bytes_Buf_ref_slice_u8, copyToSlice$bytes_Buf_collections_VecDeque_u8, getU8$bytes_Buf_collections_VecDeque_u8, getI8$bytes_Buf_collections_VecDeque_u8, getUint$bytes_Buf_collections_VecDeque_u8, getIntLe$bytes_Buf_collections_VecDeque_u8, getF32Le$bytes_Buf_collections_VecDeque_u8, getF64$bytes_Buf_collections_VecDeque_u8, tryGetU8$bytes_Buf_bytes_Bytes, tryGetU8$bytes_Buf_bytes_BytesMut, tryGetU8$bytes_Buf_collections_VecDeque_u8, tryGetU8$bytes_Buf_ref_slice_u8, take$bytes_Buf_bytes_Bytes as buf_impl_take$bytes_Buf_bytes_Bytes, take$bytes_Buf_ref_slice_u8 as buf_impl_take$bytes_Buf_ref_slice_u8, chain$bytes_Buf_boxed_Box_dyn_bytes_Buf_bytes_Bytes, chain$bytes_Buf_bytes_Bytes_bytes_buf_Chain_buf_Provided_ref_slice_u8, chain$bytes_Buf_bytes_Bytes_ref_slice_u8, chain$bytes_Buf_ref_slice_u8_bytes_Bytes, chain$bytes_Buf_ref_slice_u8_bytes_BytesMut, advance$bytes_Buf_mut_bytes_Bytes as buf_impl_advance$bytes_Buf_mut_bytes_Bytes, advance$bytes_Buf_mut_collections_VecDeque_u8 as buf_impl_advance$bytes_Buf_mut_collections_VecDeque_u8, advance$bytes_Buf_mut_dyn_bytes_Buf as buf_impl_advance$bytes_Buf_mut_dyn_bytes_Buf, advance$bytes_Buf_mut_ref_slice_u8 as buf_impl_advance$bytes_Buf_mut_ref_slice_u8, chunksVectored$bytes_Buf_mut_ref_slice_u8 as buf_impl_chunksVectored$bytes_Buf_mut_ref_slice_u8, copyToBytes$bytes_Buf_mut_bytes_Bytes, copyToBytes$bytes_Buf_mut_collections_VecDeque_u8, copyToBytes$bytes_Buf_mut_dyn_bytes_Buf, copyToBytes$bytes_Buf_mut_ref_slice_u8, copyToSlice$bytes_Buf_mut_bytes_Bytes, copyToSlice$bytes_Buf_mut_collections_VecDeque_u8, copyToSlice$bytes_Buf_mut_dyn_bytes_Buf, copyToSlice$bytes_Buf_mut_ref_slice_u8, getF32Le$bytes_Buf_mut_bytes_Bytes, getF32Le$bytes_Buf_mut_collections_VecDeque_u8, getF32Le$bytes_Buf_mut_dyn_bytes_Buf, getF32Le$bytes_Buf_mut_ref_slice_u8, getF64$bytes_Buf_mut_bytes_Bytes, getF64$bytes_Buf_mut_collections_VecDeque_u8, getF64$bytes_Buf_mut_dyn_bytes_Buf, getF64$bytes_Buf_mut_ref_slice_u8, getI128$bytes_Buf_mut_bytes_Bytes, getI128$bytes_Buf_mut_collections_VecDeque_u8, getI128$bytes_Buf_mut_dyn_bytes_Buf, getI128$bytes_Buf_mut_ref_slice_u8, getI16Le$bytes_Buf_mut_bytes_Bytes, getI16Le$bytes_Buf_mut_collections_VecDeque_u8, getI16Le$bytes_Buf_mut_dyn_bytes_Buf, getI16Le$bytes_Buf_mut_ref_slice_u8, getI32$bytes_Buf_mut_bytes_Bytes, getI32$bytes_Buf_mut_collections_VecDeque_u8, getI32$bytes_Buf_mut_dyn_bytes_Buf, getI32$bytes_Buf_mut_ref_slice_u8, getI64Le$bytes_Buf_mut_bytes_Bytes, getI64Le$bytes_Buf_mut_collections_VecDeque_u8, getI64Le$bytes_Buf_mut_dyn_bytes_Buf, getI64Le$bytes_Buf_mut_ref_slice_u8, getI8$bytes_Buf_mut_bytes_Bytes, getI8$bytes_Buf_mut_collections_VecDeque_u8, getI8$bytes_Buf_mut_dyn_bytes_Buf, getI8$bytes_Buf_mut_ref_slice_u8, getIntLe$bytes_Buf_mut_bytes_Bytes, getIntLe$bytes_Buf_mut_collections_VecDeque_u8, getIntLe$bytes_Buf_mut_dyn_bytes_Buf, getIntLe$bytes_Buf_mut_ref_slice_u8, getU128Le$bytes_Buf_mut_bytes_Bytes, getU128Le$bytes_Buf_mut_collections_VecDeque_u8, getU128Le$bytes_Buf_mut_dyn_bytes_Buf, getU128Le$bytes_Buf_mut_ref_slice_u8, getU16$bytes_Buf_mut_bytes_Bytes, getU16$bytes_Buf_mut_collections_VecDeque_u8, getU16$bytes_Buf_mut_dyn_bytes_Buf, getU16$bytes_Buf_mut_ref_slice_u8, getU32Le$bytes_Buf_mut_bytes_Bytes, getU32Le$bytes_Buf_mut_collections_VecDeque_u8, getU32Le$bytes_Buf_mut_dyn_bytes_Buf, getU32Le$bytes_Buf_mut_ref_slice_u8, getU64$bytes_Buf_mut_bytes_Bytes, getU64$bytes_Buf_mut_collections_VecDeque_u8, getU64$bytes_Buf_mut_dyn_bytes_Buf, getU64$bytes_Buf_mut_ref_slice_u8, getU8$bytes_Buf_mut_bytes_Bytes, getU8$bytes_Buf_mut_collections_VecDeque_u8, getU8$bytes_Buf_mut_dyn_bytes_Buf, getU8$bytes_Buf_mut_ref_slice_u8, getUint$bytes_Buf_mut_bytes_Bytes, getUint$bytes_Buf_mut_collections_VecDeque_u8, getUint$bytes_Buf_mut_dyn_bytes_Buf, getUint$bytes_Buf_mut_ref_slice_u8, hasRemaining$bytes_Buf_mut_boxed_Box_dyn_bytes_Buf, hasRemaining$bytes_Buf_mut_bytes_Bytes, hasRemaining$bytes_Buf_mut_bytes_BytesMut, hasRemaining$bytes_Buf_mut_dyn_buf_Leased, hasRemaining$bytes_Buf_mut_dyn_bytes_Buf, hasRemaining$bytes_Buf_mut_mut_bytes_Bytes, hasRemaining$bytes_Buf_mut_mut_collections_VecDeque_u8, hasRemaining$bytes_Buf_mut_mut_dyn_bytes_Buf, hasRemaining$bytes_Buf_mut_mut_ref_slice_u8, hasRemaining$bytes_Buf_mut_ref_slice_u8, remaining$bytes_Buf_mut_boxed_Box_dyn_bytes_Buf as buf_impl_remaining$bytes_Buf_mut_boxed_Box_dyn_bytes_Buf, remaining$bytes_Buf_mut_bytes_Bytes as buf_impl_remaining$bytes_Buf_mut_bytes_Bytes, remaining$bytes_Buf_mut_bytes_BytesMut as buf_impl_remaining$bytes_Buf_mut_bytes_BytesMut, remaining$bytes_Buf_mut_dyn_buf_Leased as buf_impl_remaining$bytes_Buf_mut_dyn_buf_Leased, remaining$bytes_Buf_mut_dyn_bytes_Buf as buf_impl_remaining$bytes_Buf_mut_dyn_bytes_Buf, remaining$bytes_Buf_mut_mut_bytes_Bytes as buf_impl_remaining$bytes_Buf_mut_mut_bytes_Bytes, remaining$bytes_Buf_mut_mut_collections_VecDeque_u8 as buf_impl_remaining$bytes_Buf_mut_mut_collections_VecDeque_u8, remaining$bytes_Buf_mut_mut_dyn_bytes_Buf as buf_impl_remaining$bytes_Buf_mut_mut_dyn_bytes_Buf, remaining$bytes_Buf_mut_mut_ref_slice_u8 as buf_impl_remaining$bytes_Buf_mut_mut_ref_slice_u8, remaining$bytes_Buf_mut_ref_slice_u8 as buf_impl_remaining$bytes_Buf_mut_ref_slice_u8, tryGetI64Le$bytes_Buf_mut_bytes_Bytes, tryGetI64Le$bytes_Buf_mut_collections_VecDeque_u8, tryGetI64Le$bytes_Buf_mut_dyn_bytes_Buf, tryGetI64Le$bytes_Buf_mut_ref_slice_u8, tryGetU128$bytes_Buf_mut_bytes_Bytes, tryGetU128$bytes_Buf_mut_collections_VecDeque_u8, tryGetU128$bytes_Buf_mut_dyn_bytes_Buf, tryGetU128$bytes_Buf_mut_ref_slice_u8, tryGetU16$bytes_Buf_mut_bytes_Bytes, tryGetU16$bytes_Buf_mut_collections_VecDeque_u8, tryGetU16$bytes_Buf_mut_dyn_bytes_Buf, tryGetU16$bytes_Buf_mut_ref_slice_u8, tryGetU8$bytes_Buf_mut_bytes_Bytes, tryGetU8$bytes_Buf_mut_collections_VecDeque_u8, tryGetU8$bytes_Buf_mut_dyn_bytes_Buf, tryGetU8$bytes_Buf_mut_ref_slice_u8, advance$bytes_Buf_boxed_Box_dyn_bytes_Buf as buf_impl_advance$bytes_Buf_boxed_Box_dyn_bytes_Buf, chunksVectored$bytes_Buf_boxed_Box_dyn_bytes_Buf as buf_impl_chunksVectored$bytes_Buf_boxed_Box_dyn_bytes_Buf, copyToBytes$bytes_Buf_boxed_Box_dyn_bytes_Buf, copyToSlice$bytes_Buf_boxed_Box_dyn_bytes_Buf, getF32Le$bytes_Buf_boxed_Box_dyn_bytes_Buf, getF64$bytes_Buf_boxed_Box_dyn_bytes_Buf, getI128$bytes_Buf_boxed_Box_dyn_bytes_Buf, getI16Le$bytes_Buf_boxed_Box_dyn_bytes_Buf, getI16Ne$bytes_Buf_boxed_Box_dyn_bytes_Buf, getI32$bytes_Buf_boxed_Box_dyn_bytes_Buf, getI64Le$bytes_Buf_boxed_Box_dyn_bytes_Buf, getI8$bytes_Buf_boxed_Box_dyn_bytes_Buf, getIntLe$bytes_Buf_boxed_Box_dyn_bytes_Buf, getU128Le$bytes_Buf_boxed_Box_dyn_bytes_Buf, getU16$bytes_Buf_boxed_Box_dyn_bytes_Buf, getU32Le$bytes_Buf_boxed_Box_dyn_bytes_Buf, getU64$bytes_Buf_boxed_Box_dyn_bytes_Buf, getU8$bytes_Buf_boxed_Box_dyn_bytes_Buf, getUint$bytes_Buf_boxed_Box_dyn_bytes_Buf, remaining$bytes_Buf_boxed_Box_dyn_bytes_Buf as buf_impl_remaining$bytes_Buf_boxed_Box_dyn_bytes_Buf, tryGetI64Le$bytes_Buf_boxed_Box_dyn_bytes_Buf, tryGetU128$bytes_Buf_boxed_Box_dyn_bytes_Buf, tryGetU16$bytes_Buf_boxed_Box_dyn_bytes_Buf, tryGetU8$bytes_Buf_boxed_Box_dyn_bytes_Buf } from "./bytes/buf/buf_impl.ts"; import type * as Buf from "./bytes/buf/buf_impl.Buf.ts"; import { advanceMut$bytes_BufMut_mut_Vec_u8, chunkMut$bytes_BufMut_mut_Vec_u8, putI16Le$bytes_BufMut_mut_Vec_u8, putI16Le$bytes_BufMut_mut_bytes_BytesMut, putI32Le$bytes_BufMut_mut_Vec_u8, putI32Le$bytes_BufMut_mut_bytes_BytesMut, putI64$bytes_BufMut_mut_Vec_u8, putI64$bytes_BufMut_mut_bytes_BytesMut, putI8$bytes_BufMut_mut_Vec_u8, putI8$bytes_BufMut_mut_bytes_BytesMut, putSlice$bytes_BufMut_mut_Vec_u8, putSlice$bytes_BufMut_mut_bytes_BytesMut, putU16$bytes_BufMut_mut_Vec_u8, putU16$bytes_BufMut_mut_bytes_BytesMut, putU32$bytes_BufMut_mut_Vec_u8, putU32$bytes_BufMut_mut_bytes_BytesMut, putU32Le$bytes_BufMut_mut_Vec_u8, putU64Le$bytes_BufMut_mut_Vec_u8, putU64Le$bytes_BufMut_mut_bytes_BytesMut, putU8$bytes_BufMut_mut_Vec_u8, putU8$bytes_BufMut_mut_bytes_BytesMut, remainingMut$bytes_BufMut_mut_Vec_u8, remainingMut$bytes_BufMut_mut_boxed_Box_Vec_u8, remainingMut$bytes_BufMut_mut_boxed_Box_bytes_BytesMut, remainingMut$bytes_BufMut_mut_boxed_Box_mut_bytes_BytesMut, remainingMut$bytes_BufMut_mut_bytes_BytesMut, remainingMut$bytes_BufMut_mut_mut_Vec_u8, remainingMut$bytes_BufMut_mut_mut_bytes_BytesMut, advanceMut$bytes_BufMut_boxed_Box_mut_bytes_BytesMut, chunkMut$bytes_BufMut_boxed_Box_mut_bytes_BytesMut, putI16Le$bytes_BufMut_boxed_Box_Vec_u8, putI16Le$bytes_BufMut_boxed_Box_bytes_BytesMut, putI32Le$bytes_BufMut_boxed_Box_Vec_u8, putI32Le$bytes_BufMut_boxed_Box_bytes_BytesMut, putI64$bytes_BufMut_boxed_Box_Vec_u8, putI64$bytes_BufMut_boxed_Box_bytes_BytesMut, putI8$bytes_BufMut_boxed_Box_Vec_u8, putI8$bytes_BufMut_boxed_Box_bytes_BytesMut, putSlice$bytes_BufMut_boxed_Box_Vec_u8, putSlice$bytes_BufMut_boxed_Box_bytes_BytesMut, putSlice$bytes_BufMut_boxed_Box_mut_bytes_BytesMut, putU16$bytes_BufMut_boxed_Box_Vec_u8, putU16$bytes_BufMut_boxed_Box_bytes_BytesMut, putU32$bytes_BufMut_boxed_Box_Vec_u8, putU32$bytes_BufMut_boxed_Box_bytes_BytesMut, putU32Le$bytes_BufMut_boxed_Box_mut_bytes_BytesMut, putU64Le$bytes_BufMut_boxed_Box_Vec_u8, putU64Le$bytes_BufMut_boxed_Box_bytes_BytesMut, putU8$bytes_BufMut_boxed_Box_Vec_u8, putU8$bytes_BufMut_boxed_Box_bytes_BytesMut } from "./bytes/buf/buf_mut.ts"; import * as Chain from "./bytes/buf/chain.Chain.ts"; import * as Take from "./bytes/buf/take.Take.ts"; import * as UninitSlice from "./bytes/buf/uninit_slice.UninitSlice.ts"; -import { remaining$bytes_Buf_collections_VecDeque_u8 as vec_deque_remaining$bytes_Buf_collections_VecDeque_u8, chunk$bytes_Buf_collections_VecDeque_u8 as vec_deque_chunk$bytes_Buf_collections_VecDeque_u8, advance$bytes_Buf_collections_VecDeque_u8 as vec_deque_advance$bytes_Buf_collections_VecDeque_u8 } from "./bytes/buf/vec_deque.ts"; +import { remaining$bytes_Buf_collections_VecDeque_u8 as vec_deque_remaining$bytes_Buf_collections_VecDeque_u8, chunk$bytes_Buf_collections_VecDeque_u8 as vec_deque_chunk$bytes_Buf_collections_VecDeque_u8, chunksVectored$bytes_Buf_collections_VecDeque_u8 as vec_deque_chunksVectored$bytes_Buf_collections_VecDeque_u8, advance$bytes_Buf_collections_VecDeque_u8 as vec_deque_advance$bytes_Buf_collections_VecDeque_u8 } from "./bytes/buf/vec_deque.ts"; import type * as TryGetError from "./bytes.TryGetError.ts"; import { then$0abhnvu } from "./core/bool.ts"; import { clone$1i3gmk3 as option_clone$1i3gmk3 } from "./core/option.ts"; @@ -3391,7 +3391,7 @@ export function chunkWrite(chunk: rs.ByteSlice, op: rs.u8, n: rs.u8, out: rs.Byt } } if (_20 === 1) { - UninitSlice.copyFromSlice(UninitSlice.indexMut$ops_IndexMut_ops_RangeTo_usize(chunk, { end: k }, { file: "fixtures/stock/src/buf.rs", line: 700, col: 19 }), rs.byteVecSlice(src)); + UninitSlice.copyFromSlice(UninitSlice.indexMut$ops_IndexMut_ops_RangeTo_usize(chunk, { end: k }, { file: "fixtures/stock/src/buf.rs", line: 701, col: 19 }), rs.byteVecSlice(src)); break b1; } if (_20 === 2) { @@ -3403,46 +3403,46 @@ export function chunkWrite(chunk: rs.ByteSlice, op: rs.u8, n: rs.u8, out: rs.Byt break b1; } if (_20 === 4) { - UninitSlice.copyFromSlice(UninitSlice.indexMut$ops_IndexMut_ops_RangeTo_usize(UninitSlice.indexMut$ops_IndexMut_ops_RangeFrom_usize(chunk, new rs.RangeFrom(half, rs.usizeStep), { file: "fixtures/stock/src/buf.rs", line: 708, col: 18 }), { end: rs.usizeSub(k, half) }, { file: "fixtures/stock/src/buf.rs", line: 708, col: 26 }), rs.byteSliceRange(rs.byteVecSlice(src), half)); - UninitSlice.copyFromSlice(UninitSlice.indexMut$ops_IndexMut_ops_Range_usize(chunk, new rs.Range(0, half), { file: "fixtures/stock/src/buf.rs", line: 709, col: 18 }), rs.byteSliceRange(rs.byteVecSlice(src), 0, half)); + UninitSlice.copyFromSlice(UninitSlice.indexMut$ops_IndexMut_ops_RangeTo_usize(UninitSlice.indexMut$ops_IndexMut_ops_RangeFrom_usize(chunk, new rs.RangeFrom(half, rs.usizeStep), { file: "fixtures/stock/src/buf.rs", line: 709, col: 18 }), { end: rs.usizeSub(k, half) }, { file: "fixtures/stock/src/buf.rs", line: 709, col: 26 }), rs.byteSliceRange(rs.byteVecSlice(src), half)); + UninitSlice.copyFromSlice(UninitSlice.indexMut$ops_IndexMut_ops_Range_usize(chunk, new rs.Range(0, half), { file: "fixtures/stock/src/buf.rs", line: 710, col: 18 }), rs.byteSliceRange(rs.byteVecSlice(src), 0, half)); break b1; } if (_20 === 5) { if (k > 0) { const _66: { end: rs.usize; inclusive: true } = { end: rs.usizeSub(k, 1), inclusive: true }; - UninitSlice.copyFromSlice(UninitSlice.indexMut$ops_IndexMut_ops_RangeToInclusive_usize(chunk, _66, { file: "fixtures/stock/src/buf.rs", line: 712, col: 18 }), rs.byteVecSlice(src)); + UninitSlice.copyFromSlice(UninitSlice.indexMut$ops_IndexMut_ops_RangeToInclusive_usize(chunk, _66, { file: "fixtures/stock/src/buf.rs", line: 713, col: 18 }), rs.byteVecSlice(src)); const _73: rs.RangeInclusive = new rs.RangeInclusive(half, half, rs.usizeStep); - UninitSlice.writeByte(UninitSlice.indexMut$ops_IndexMut_ops_RangeInclusive_usize(chunk, _73, { file: "fixtures/stock/src/buf.rs", line: 713, col: 18 }), 0, ~n & 0xff); + UninitSlice.writeByte(UninitSlice.indexMut$ops_IndexMut_ops_RangeInclusive_usize(chunk, _73, { file: "fixtures/stock/src/buf.rs", line: 714, col: 18 }), 0, ~n & 0xff); break b1; } } else { if (_20 === 6) { - UninitSlice.copyFromSlice(UninitSlice.indexMut$ops_IndexMut_ops_RangeTo_usize(UninitSlice.indexMut$ops_IndexMut_ops_RangeFull(chunk, undefined, { file: "fixtures/stock/src/buf.rs", line: 715, col: 19 }), { end: k }, { file: "fixtures/stock/src/buf.rs", line: 715, col: 23 }), rs.byteVecSlice(src)); + UninitSlice.copyFromSlice(UninitSlice.indexMut$ops_IndexMut_ops_RangeTo_usize(UninitSlice.indexMut$ops_IndexMut_ops_RangeFull(chunk, undefined, { file: "fixtures/stock/src/buf.rs", line: 716, col: 19 }), { end: k }, { file: "fixtures/stock/src/buf.rs", line: 716, col: 23 }), rs.byteVecSlice(src)); break b1; } if (_20 === 7) { - UninitSlice.writeByte(UninitSlice.indexMut$ops_IndexMut_ops_RangeFrom_usize(chunk, new rs.RangeFrom(k, rs.usizeStep), { file: "fixtures/stock/src/buf.rs", line: 718, col: 18 }), 0, n); - UninitSlice.copyFromSlice(UninitSlice.indexMut$ops_IndexMut_ops_RangeTo_usize(chunk, { end: k }, { file: "fixtures/stock/src/buf.rs", line: 719, col: 18 }), rs.byteVecSlice(src)); + UninitSlice.writeByte(UninitSlice.indexMut$ops_IndexMut_ops_RangeFrom_usize(chunk, new rs.RangeFrom(k, rs.usizeStep), { file: "fixtures/stock/src/buf.rs", line: 719, col: 18 }), 0, n); + UninitSlice.copyFromSlice(UninitSlice.indexMut$ops_IndexMut_ops_RangeTo_usize(chunk, { end: k }, { file: "fixtures/stock/src/buf.rs", line: 720, col: 18 }), rs.byteVecSlice(src)); return rs.usizeAdd(k, 1); } if (_20 === 8) { - UninitSlice.copyFromSlice(UninitSlice.indexMut$ops_IndexMut_ops_RangeTo_usize(chunk, { end: k }, { file: "fixtures/stock/src/buf.rs", line: 723, col: 19 }), rs.byteSliceFrom(rs.bytes(3).fill(n))); + UninitSlice.copyFromSlice(UninitSlice.indexMut$ops_IndexMut_ops_RangeTo_usize(chunk, { end: k }, { file: "fixtures/stock/src/buf.rs", line: 724, col: 19 }), rs.byteSliceFrom(rs.bytes(3).fill(n))); break b1; } if (_20 === 9) { const _94: rs.u8 = rs.u8Rem(n, 3); if (_94 === 0) { const _100: { end: rs.usize } = { end: rs.usizeAdd(room, 1) }; - rs.byteVecPush(out, UninitSlice.len(UninitSlice.index$ops_Index_ops_RangeTo_usize(chunk, _100, { file: "fixtures/stock/src/buf.rs", line: 726, col: 32 })) & 0xff); + rs.byteVecPush(out, UninitSlice.len(UninitSlice.index$ops_Index_ops_RangeTo_usize(chunk, _100, { file: "fixtures/stock/src/buf.rs", line: 727, col: 32 })) & 0xff); break b1; } if (_94 === 1) { const _104: rs.Range = new rs.Range(rs.usizeAdd(k, 1), k); - UninitSlice.writeByte(UninitSlice.indexMut$ops_IndexMut_ops_Range_usize(chunk, _104, { file: "fixtures/stock/src/buf.rs", line: 727, col: 23 }), 0, n); + UninitSlice.writeByte(UninitSlice.indexMut$ops_IndexMut_ops_Range_usize(chunk, _104, { file: "fixtures/stock/src/buf.rs", line: 728, col: 23 }), 0, n); break b1; } const _108: rs.RangeFrom = new rs.RangeFrom(rs.usizeAdd(room, 1), rs.usizeStep); - UninitSlice.writeByte(UninitSlice.indexMut$ops_IndexMut_ops_RangeFrom_usize(chunk, _108, { file: "fixtures/stock/src/buf.rs", line: 728, col: 23 }), 0, n); + UninitSlice.writeByte(UninitSlice.indexMut$ops_IndexMut_ops_RangeFrom_usize(chunk, _108, { file: "fixtures/stock/src/buf.rs", line: 729, col: 23 }), 0, n); break b1; } } @@ -4625,6 +4625,95 @@ export function chained$dyn_bytes_Buf(at: rs.usize[], buf: Buf.Buf, pick: rs.u8, return readAll$dyn_bytes_Buf(buf, ops, out); } +/** + * `chunks_vectored` of each buffer into as many slots as its input picks: a `Bytes`, a + * `BytesMut`, a `&[u8]`, buffers in pieces, a `VecDeque` that wraps, a `Take` and a + * `Chain` of them, and through a `&mut` and a `dyn Buf`. Then the slots it filled, read, + * printed, and advanced, one and all together, which panics past what they hold. + */ +export function vectored(data: rs.ByteSlice, out: rs.ByteVec): void { + let n!: rs.usize; + if (data.length >= 4) { + const input: rs.ByteSlice = rs.byteSliceRange(data, 4); + const cut: rs.usize = rs.usizeRem(data.data[data.start + 1] as rs.usize, rs.usizeAdd(input.length, 1)); + const bytes: rs.ByteSlice = rs.bytesCopyFromSlice(input); + const owned: rs.BytesMut = rs.bytesMutFrom(input); + const pieces: Pieces.Pieces = Pieces.new(input.data, input.start, input.length, cut); + const provided: Provided.Provided = { _0: Pieces.new(input.data, input.start, input.length, cut) }; + const deque: rs.VecDeque = rs.dequeFromVec(rs.iterToVec(rs.iterSlice(rs.byteSliceView(input)), undefined, 1, true), 1, true) as rs.VecDeque; + rs.dequeRotate(deque, cut); + const take: Take.Take = Pieces.take$bytes_Buf(Pieces.new(input.data, input.start, input.length, cut), rs.usizeRem(data.data[data.start + 3] as rs.usize, rs.usizeAdd(input.length, 2))); + if (cut > input.length) { + rs.panic("mid > len"); + } + const b: rs.ByteSlice = new rs.ByteSlice(input.data, input.start + cut, input.length - cut); + const chain: Chain.Chain, rs.ByteSlice> = Chain.chain$bytes_Buf_buf_Pieces_bytes_Bytes_ref_slice_u8(Pieces.chain$bytes_Buf_bytes_Bytes(Pieces.new(input.data, input.start, cut, rs.usizeDiv(cut, 2)), rs.bytesCopyFromSlice(b)), rs.byteSliceRange(b, 0)); + let slice: rs.ByteSlice = input; + const boxed: Buf.Buf = new of$buf_Pieces(Pieces.new(input.data, input.start, input.length, cut)); + const _53: rs.ByteSlice = rs.byteSliceFrom(Uint8Array.of()); + const dst2: rs.Slice = rs.sliceRange(rs.sliceFrom(Array.from({ length: 5 }, (): rs.ByteSlice => { + return _53; + })), 0, rs.usizeRem(data.data[data.start + 2] as rs.usize, 6)); + const _64: rs.u8 = rs.u8Rem(data.data[data.start], 11); + if (_64 === 0) { + n = buf_impl_chunksVectored$bytes_Buf_bytes_Bytes(bytes, dst2); + } else if (_64 === 1) { + n = buf_impl_chunksVectored$bytes_Buf_bytes_BytesMut(owned, dst2); + } else if (_64 === 2) { + n = buf_impl_chunksVectored$bytes_Buf_ref_slice_u8(input, dst2); + } else if (_64 === 3) { + n = Pieces.chunksVectored$bytes_Buf(pieces, dst2); + } else if (_64 === 4) { + n = Provided.chunksVectored$bytes_Buf(provided, dst2); + } else if (_64 === 5) { + n = new of$bytes_buf_Chain_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(chain).chunksVectored$Buf(dst2); + } else if (_64 === 6) { + n = Take.chunksVectored$bytes_Buf_buf_Pieces(take, dst2); + } else if (_64 === 7) { + n = Chain.chunksVectored$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(chain, dst2); + } else if (_64 === 8) { + n = buf_impl_chunksVectored$bytes_Buf_mut_ref_slice_u8(rs.place(() => slice, (value) => slice = value), dst2); + } else if (_64 === 9) { + n = vec_deque_chunksVectored$bytes_Buf_collections_VecDeque_u8(deque, dst2); + } else { + n = buf_impl_chunksVectored$bytes_Buf_boxed_Box_dyn_bytes_Buf(boxed, dst2); + } + rs.byteVecPush(out, n & 0xff); + for (const _86 of rs.sliceItems(rs.sliceRange(dst2, 0, n))) { + rs.byteVecPush(out, _86.length & 0xff); + rs.byteVecExtendFromSlice(out, _86); + } + const part2 = rs.sliceRange(dst2, 0, n); + rs.byteVecExtendFromSlice(out, rs.stringAsBytes(rs.fmtFormat([(f: rs.Formatter) => rs.fmtList(rs.sliceItems(part2), f, (value: rs.ByteSlice, f: rs.Formatter) => rs.fmtList(rs.byteSliceView(value), f, rs.u8Debug))]).v)); + const total: rs.usize = rs.iterSum(rs.iterMap(rs.iterSlice(rs.sliceItems(rs.sliceRange(dst2, 0, n))), (chunk: rs.ByteSlice): rs.usize => { + return chunk.length; + }), rs.usizeAdd, 0); + const skip: rs.usize = rs.usizeRem(data.data[data.start + 3] as rs.usize, rs.usizeAdd(total, 2)); + const _126: rs.Place | undefined = rs.sliceFirstMut(dst2); + if (_126 !== undefined) { + let one: rs.ByteSlice = _126.v; + const _132: rs.usize = rs.min(skip, rs.usizeAdd(one.length, rs.u8Rem(rs.u8Div(data.data[data.start], 11), 2) as rs.usize)); + rs.ioSliceAdvance(rs.place(() => one, (value2) => one = value2), _132); + rs.byteVecExtendFromSlice(out, one); + } + let left: rs.Slice = rs.sliceRange(dst2, 0, n); + rs.ioSliceAdvanceSlices(rs.place(() => left, (value3) => left = value3), skip); + rs.byteVecPush(out, left.length & 0xff); + const iter2: rs.Iter = rs.iterSlice(rs.sliceItems(left)); + while (true) { + const _159: rs.ByteSlice | rs.Done = iter2.next(); + if (_159 === rs.DONE) { + break; + } + rs.byteVecExtendFromSlice(out, _159); + } + rs.drop(boxed); + lib_drop$bytes_buf_Chain_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(chain); + owned[Symbol.dispose](); + rs.bytesDrop(bytes); + } +} + /** * The bytes of a case's input, taken from the front. * A `Bytes` of a `String`, which takes its storage, of the room its first bytes pick past diff --git a/ts/fixtures/stock/expected/bytes/buf/buf_impl.Buf.ts b/ts/fixtures/stock/expected/bytes/buf/buf_impl.Buf.ts index 3a010cfb3..99a02f240 100644 --- a/ts/fixtures/stock/expected/bytes/buf/buf_impl.Buf.ts +++ b/ts/fixtures/stock/expected/bytes/buf/buf_impl.Buf.ts @@ -30,6 +30,6 @@ import type * as TryGetError from "../../bytes.TryGetError.ts"; * ``` */ export type Buf = - | { remaining$Buf: () => rs.usize; chunk$Buf: () => rs.ByteSlice; advance$Buf: (a0: rs.usize) => void; hasRemaining$Buf: () => boolean; copyToSlice$Buf: (a0: rs.ByteSlice) => void; getU8$Buf: () => rs.u8; getI8$Buf: () => rs.i8; getU16$Buf: () => rs.u16; getI16Le$Buf: () => rs.i16; getI16Ne$Buf: () => rs.i16; getU32Le$Buf: () => rs.u32; getI32$Buf: () => rs.i32; getU64$Buf: () => rs.u64; getI64Le$Buf: () => rs.i64; getU128Le$Buf: () => rs.u128; getI128$Buf: () => rs.i128; getUint$Buf: (a0: rs.usize) => rs.u64; getIntLe$Buf: (a0: rs.usize) => rs.i64; getF32Le$Buf: () => rs.f32; getF64$Buf: () => rs.f64; tryGetU8$Buf: () => rs.Result; tryGetU16$Buf: () => rs.Result; tryGetI64Le$Buf: () => rs.Result; tryGetU128$Buf: () => rs.Result; copyToBytes$Buf: (a0: rs.usize) => rs.ByteSlice }; + | { remaining$Buf: () => rs.usize; chunk$Buf: () => rs.ByteSlice; chunksVectored$Buf: (a0: rs.Slice) => rs.usize; advance$Buf: (a0: rs.usize) => void; hasRemaining$Buf: () => boolean; copyToSlice$Buf: (a0: rs.ByteSlice) => void; getU8$Buf: () => rs.u8; getI8$Buf: () => rs.i8; getU16$Buf: () => rs.u16; getI16Le$Buf: () => rs.i16; getI16Ne$Buf: () => rs.i16; getU32Le$Buf: () => rs.u32; getI32$Buf: () => rs.i32; getU64$Buf: () => rs.u64; getI64Le$Buf: () => rs.i64; getU128Le$Buf: () => rs.u128; getI128$Buf: () => rs.i128; getUint$Buf: (a0: rs.usize) => rs.u64; getIntLe$Buf: (a0: rs.usize) => rs.i64; getF32Le$Buf: () => rs.f32; getF64$Buf: () => rs.f64; tryGetU8$Buf: () => rs.Result; tryGetU16$Buf: () => rs.Result; tryGetI64Le$Buf: () => rs.Result; tryGetU128$Buf: () => rs.Result; copyToBytes$Buf: (a0: rs.usize) => rs.ByteSlice }; //# sourceMappingURL=buf_impl.Buf.ts.map diff --git a/ts/fixtures/stock/expected/bytes/buf/buf_impl.ts b/ts/fixtures/stock/expected/bytes/buf/buf_impl.ts index 6ff9d72a6..64dafae09 100644 --- a/ts/fixtures/stock/expected/bytes/buf/buf_impl.ts +++ b/ts/fixtures/stock/expected/bytes/buf/buf_impl.ts @@ -21,6 +21,132 @@ export function signExtend(val: rs.u64, nbytes: rs.usize): rs.i64 { return 0; } +/** + * Fills `dst` with potentially multiple slices starting at `self`'s + * current position. + * + * If the `Buf` is backed by disjoint slices of bytes, `chunk_vectored` enables + * fetching more than one slice at once. `dst` is a slice of `IoSlice` + * references, enabling the slice to be directly used with [`writev`] + * without any further conversion. The sum of the lengths of all the + * buffers written to `dst` will be less than or equal to `Buf::remaining()`. + * + * The entries in `dst` will be overwritten, but the data **contained** by + * the slices **will not** be modified. The return value is the number of + * slices written to `dst`. If `Buf::remaining()` is non-zero, then this + * writes at least one non-empty slice to `dst`. + * + * This is a lower level function. Most operations are done with other + * functions. + * + * # Implementer notes + * + * This function should never panic. Once the end of the buffer is reached, + * i.e., `Buf::remaining` returns 0, calls to `chunk_vectored` must return 0 + * without mutating `dst`. + * + * Implementations should also take care to properly handle being called + * with `dst` being a zero length slice. + * + * [`writev`]: http://man7.org/linux/man-pages/man2/readv.2.html + */ +export function chunksVectored$bytes_Buf_bytes_Bytes(self: rs.ByteSlice, dst: rs.Slice): rs.usize { + if (!(dst.length === 0)) { + if (!(self.length !== 0)) { + return 0; + } + const _6: rs.ByteSlice = self; + rs.idx(dst, 0); + dst.data[dst.start] = _6; + return 1; + } + return 0; +} + +/** + * Fills `dst` with potentially multiple slices starting at `self`'s + * current position. + * + * If the `Buf` is backed by disjoint slices of bytes, `chunk_vectored` enables + * fetching more than one slice at once. `dst` is a slice of `IoSlice` + * references, enabling the slice to be directly used with [`writev`] + * without any further conversion. The sum of the lengths of all the + * buffers written to `dst` will be less than or equal to `Buf::remaining()`. + * + * The entries in `dst` will be overwritten, but the data **contained** by + * the slices **will not** be modified. The return value is the number of + * slices written to `dst`. If `Buf::remaining()` is non-zero, then this + * writes at least one non-empty slice to `dst`. + * + * This is a lower level function. Most operations are done with other + * functions. + * + * # Implementer notes + * + * This function should never panic. Once the end of the buffer is reached, + * i.e., `Buf::remaining` returns 0, calls to `chunk_vectored` must return 0 + * without mutating `dst`. + * + * Implementations should also take care to properly handle being called + * with `dst` being a zero length slice. + * + * [`writev`]: http://man7.org/linux/man-pages/man2/readv.2.html + */ +export function chunksVectored$bytes_Buf_bytes_BytesMut(self: rs.BytesMut, dst: rs.Slice): rs.usize { + if (!(dst.length === 0)) { + if (!(self.length !== 0)) { + return 0; + } + const _6: rs.ByteSlice = rs.bytesMutView(self); + rs.idx(dst, 0); + dst.data[dst.start] = _6; + return 1; + } + return 0; +} + +/** + * Fills `dst` with potentially multiple slices starting at `self`'s + * current position. + * + * If the `Buf` is backed by disjoint slices of bytes, `chunk_vectored` enables + * fetching more than one slice at once. `dst` is a slice of `IoSlice` + * references, enabling the slice to be directly used with [`writev`] + * without any further conversion. The sum of the lengths of all the + * buffers written to `dst` will be less than or equal to `Buf::remaining()`. + * + * The entries in `dst` will be overwritten, but the data **contained** by + * the slices **will not** be modified. The return value is the number of + * slices written to `dst`. If `Buf::remaining()` is non-zero, then this + * writes at least one non-empty slice to `dst`. + * + * This is a lower level function. Most operations are done with other + * functions. + * + * # Implementer notes + * + * This function should never panic. Once the end of the buffer is reached, + * i.e., `Buf::remaining` returns 0, calls to `chunk_vectored` must return 0 + * without mutating `dst`. + * + * Implementations should also take care to properly handle being called + * with `dst` being a zero length slice. + * + * [`writev`]: http://man7.org/linux/man-pages/man2/readv.2.html + */ +export function chunksVectored$bytes_Buf_ref_slice_u8(self: rs.ByteSlice, dst: rs.Slice): rs.usize { + if (!(dst.length === 0)) { + if (!(self.length !== 0)) { + return 0; + } + const _6: rs.ByteSlice = self; + rs.idx(dst, 0); + dst.data[dst.start] = _6; + return 1; + } + return 0; +} + /** * Returns true if there are any more bytes to consume * @@ -1192,6 +1318,39 @@ export function chunk$bytes_Buf_mut_ref_slice_u8(self: rs.Place): return self.v; } +/** + * Fills `dst` with potentially multiple slices starting at `self`'s + * current position. + * + * If the `Buf` is backed by disjoint slices of bytes, `chunk_vectored` enables + * fetching more than one slice at once. `dst` is a slice of `IoSlice` + * references, enabling the slice to be directly used with [`writev`] + * without any further conversion. The sum of the lengths of all the + * buffers written to `dst` will be less than or equal to `Buf::remaining()`. + * + * The entries in `dst` will be overwritten, but the data **contained** by + * the slices **will not** be modified. The return value is the number of + * slices written to `dst`. If `Buf::remaining()` is non-zero, then this + * writes at least one non-empty slice to `dst`. + * + * This is a lower level function. Most operations are done with other + * functions. + * + * # Implementer notes + * + * This function should never panic. Once the end of the buffer is reached, + * i.e., `Buf::remaining` returns 0, calls to `chunk_vectored` must return 0 + * without mutating `dst`. + * + * Implementations should also take care to properly handle being called + * with `dst` being a zero length slice. + * + * [`writev`]: http://man7.org/linux/man-pages/man2/readv.2.html + */ +export function chunksVectored$bytes_Buf_mut_ref_slice_u8(self: rs.Place, dst: rs.Slice): rs.usize { + return chunksVectored$bytes_Buf_ref_slice_u8(self.v, dst); +} + /** * Consumes `len` bytes inside self and returns new instance of `Bytes` * with this data. @@ -3976,6 +4135,39 @@ export function chunk$bytes_Buf_boxed_Box_dyn_bytes_Buf(self: Buf.Buf): rs.ByteS return self.chunk$Buf(); } +/** + * Fills `dst` with potentially multiple slices starting at `self`'s + * current position. + * + * If the `Buf` is backed by disjoint slices of bytes, `chunk_vectored` enables + * fetching more than one slice at once. `dst` is a slice of `IoSlice` + * references, enabling the slice to be directly used with [`writev`] + * without any further conversion. The sum of the lengths of all the + * buffers written to `dst` will be less than or equal to `Buf::remaining()`. + * + * The entries in `dst` will be overwritten, but the data **contained** by + * the slices **will not** be modified. The return value is the number of + * slices written to `dst`. If `Buf::remaining()` is non-zero, then this + * writes at least one non-empty slice to `dst`. + * + * This is a lower level function. Most operations are done with other + * functions. + * + * # Implementer notes + * + * This function should never panic. Once the end of the buffer is reached, + * i.e., `Buf::remaining` returns 0, calls to `chunk_vectored` must return 0 + * without mutating `dst`. + * + * Implementations should also take care to properly handle being called + * with `dst` being a zero length slice. + * + * [`writev`]: http://man7.org/linux/man-pages/man2/readv.2.html + */ +export function chunksVectored$bytes_Buf_boxed_Box_dyn_bytes_Buf(self: Buf.Buf, dst: rs.Slice): rs.usize { + return self.chunksVectored$Buf(dst); +} + /** * Consumes `len` bytes inside self and returns new instance of `Bytes` * with this data. diff --git a/ts/fixtures/stock/expected/bytes/buf/chain.Chain.ts b/ts/fixtures/stock/expected/bytes/buf/chain.Chain.ts index df3ac44e8..a6a20ac00 100644 --- a/ts/fixtures/stock/expected/bytes/buf/chain.Chain.ts +++ b/ts/fixtures/stock/expected/bytes/buf/chain.Chain.ts @@ -5,7 +5,7 @@ import { out$u8 } from "../../lib.ts"; import * as Pieces from "../../buf.Pieces.ts"; import * as Provided from "../../buf.Provided.ts"; import { panicAdvance, panicDoesNotFit } from "../../bytes.ts"; -import { signExtend, take$bytes_Buf_mut_bytes_Bytes as buf_impl_take$bytes_Buf_mut_bytes_Bytes, take$bytes_Buf_mut_bytes_BytesMut as buf_impl_take$bytes_Buf_mut_bytes_BytesMut, take$bytes_Buf_mut_mut_ref_slice_u8 as buf_impl_take$bytes_Buf_mut_mut_ref_slice_u8, take$bytes_Buf_mut_ref_slice_u8 as buf_impl_take$bytes_Buf_mut_ref_slice_u8, advance$bytes_Buf_mut_boxed_Box_dyn_bytes_Buf as buf_impl_advance$bytes_Buf_mut_boxed_Box_dyn_bytes_Buf, advance$bytes_Buf_mut_bytes_Bytes as buf_impl_advance$bytes_Buf_mut_bytes_Bytes, advance$bytes_Buf_mut_ref_slice_u8 as buf_impl_advance$bytes_Buf_mut_ref_slice_u8, chunk$bytes_Buf_mut_boxed_Box_dyn_bytes_Buf as buf_impl_chunk$bytes_Buf_mut_boxed_Box_dyn_bytes_Buf, chunk$bytes_Buf_mut_bytes_Bytes as buf_impl_chunk$bytes_Buf_mut_bytes_Bytes, chunk$bytes_Buf_mut_ref_slice_u8 as buf_impl_chunk$bytes_Buf_mut_ref_slice_u8, copyToBytes$bytes_Buf_mut_boxed_Box_dyn_bytes_Buf, copyToBytes$bytes_Buf_mut_bytes_Bytes, copyToBytes$bytes_Buf_mut_ref_slice_u8, hasRemaining$bytes_Buf_mut_boxed_Box_dyn_bytes_Buf, hasRemaining$bytes_Buf_mut_bytes_Bytes, hasRemaining$bytes_Buf_mut_ref_slice_u8, remaining$bytes_Buf_mut_boxed_Box_dyn_bytes_Buf as buf_impl_remaining$bytes_Buf_mut_boxed_Box_dyn_bytes_Buf, remaining$bytes_Buf_mut_bytes_Bytes as buf_impl_remaining$bytes_Buf_mut_bytes_Bytes, remaining$bytes_Buf_mut_ref_slice_u8 as buf_impl_remaining$bytes_Buf_mut_ref_slice_u8, advance$bytes_Buf_boxed_Box_dyn_bytes_Buf as buf_impl_advance$bytes_Buf_boxed_Box_dyn_bytes_Buf, chunk$bytes_Buf_boxed_Box_dyn_bytes_Buf as buf_impl_chunk$bytes_Buf_boxed_Box_dyn_bytes_Buf, copyToBytes$bytes_Buf_boxed_Box_dyn_bytes_Buf, hasRemaining$bytes_Buf_boxed_Box_dyn_bytes_Buf, remaining$bytes_Buf_boxed_Box_dyn_bytes_Buf as buf_impl_remaining$bytes_Buf_boxed_Box_dyn_bytes_Buf } from "../../bytes/buf/buf_impl.ts"; +import { signExtend, chunksVectored$bytes_Buf_bytes_Bytes as buf_impl_chunksVectored$bytes_Buf_bytes_Bytes, chunksVectored$bytes_Buf_ref_slice_u8 as buf_impl_chunksVectored$bytes_Buf_ref_slice_u8, take$bytes_Buf_mut_bytes_Bytes as buf_impl_take$bytes_Buf_mut_bytes_Bytes, take$bytes_Buf_mut_bytes_BytesMut as buf_impl_take$bytes_Buf_mut_bytes_BytesMut, take$bytes_Buf_mut_mut_ref_slice_u8 as buf_impl_take$bytes_Buf_mut_mut_ref_slice_u8, take$bytes_Buf_mut_ref_slice_u8 as buf_impl_take$bytes_Buf_mut_ref_slice_u8, advance$bytes_Buf_mut_boxed_Box_dyn_bytes_Buf as buf_impl_advance$bytes_Buf_mut_boxed_Box_dyn_bytes_Buf, advance$bytes_Buf_mut_bytes_Bytes as buf_impl_advance$bytes_Buf_mut_bytes_Bytes, advance$bytes_Buf_mut_ref_slice_u8 as buf_impl_advance$bytes_Buf_mut_ref_slice_u8, chunk$bytes_Buf_mut_boxed_Box_dyn_bytes_Buf as buf_impl_chunk$bytes_Buf_mut_boxed_Box_dyn_bytes_Buf, chunk$bytes_Buf_mut_bytes_Bytes as buf_impl_chunk$bytes_Buf_mut_bytes_Bytes, chunk$bytes_Buf_mut_ref_slice_u8 as buf_impl_chunk$bytes_Buf_mut_ref_slice_u8, chunksVectored$bytes_Buf_mut_ref_slice_u8 as buf_impl_chunksVectored$bytes_Buf_mut_ref_slice_u8, copyToBytes$bytes_Buf_mut_boxed_Box_dyn_bytes_Buf, copyToBytes$bytes_Buf_mut_bytes_Bytes, copyToBytes$bytes_Buf_mut_ref_slice_u8, hasRemaining$bytes_Buf_mut_boxed_Box_dyn_bytes_Buf, hasRemaining$bytes_Buf_mut_bytes_Bytes, hasRemaining$bytes_Buf_mut_ref_slice_u8, remaining$bytes_Buf_mut_boxed_Box_dyn_bytes_Buf as buf_impl_remaining$bytes_Buf_mut_boxed_Box_dyn_bytes_Buf, remaining$bytes_Buf_mut_bytes_Bytes as buf_impl_remaining$bytes_Buf_mut_bytes_Bytes, remaining$bytes_Buf_mut_ref_slice_u8 as buf_impl_remaining$bytes_Buf_mut_ref_slice_u8, advance$bytes_Buf_boxed_Box_dyn_bytes_Buf as buf_impl_advance$bytes_Buf_boxed_Box_dyn_bytes_Buf, chunk$bytes_Buf_boxed_Box_dyn_bytes_Buf as buf_impl_chunk$bytes_Buf_boxed_Box_dyn_bytes_Buf, chunksVectored$bytes_Buf_boxed_Box_dyn_bytes_Buf as buf_impl_chunksVectored$bytes_Buf_boxed_Box_dyn_bytes_Buf, copyToBytes$bytes_Buf_boxed_Box_dyn_bytes_Buf, hasRemaining$bytes_Buf_boxed_Box_dyn_bytes_Buf, remaining$bytes_Buf_boxed_Box_dyn_bytes_Buf as buf_impl_remaining$bytes_Buf_boxed_Box_dyn_bytes_Buf } from "../../bytes/buf/buf_impl.ts"; import type * as Buf from "../../bytes/buf/buf_impl.Buf.ts"; import { new_$mut_bytes_buf_Chain_buf_Provided_ref_slice_u8 as take_new_$mut_bytes_buf_Chain_buf_Provided_ref_slice_u8 } from "../../bytes/buf/take.ts"; import * as Take from "../../bytes/buf/take.Take.ts"; @@ -58,6 +58,29 @@ export function hasRemaining$bytes_Buf_buf_Pieces_buf_Provided(self: Chain 0; } +/** + * Returns true if there are any more bytes to consume + * + * This is equivalent to `self.remaining() != 0`. + * + * # Examples + * + * ``` + * use bytes::Buf; + * + * let mut buf = &b"a"[..]; + * + * assert!(buf.has_remaining()); + * + * buf.get_u8(); + * + * assert!(!buf.has_remaining()); + * ``` + */ +export function hasRemaining$bytes_Buf_buf_Pieces_bytes_Bytes(self: Chain): boolean { + return remaining$bytes_Buf_buf_Pieces_bytes_Bytes(self) > 0; +} + /** * Returns true if there are any more bytes to consume * @@ -173,6 +196,29 @@ export function hasRemaining$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_b return remaining$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_Bytes_ref_slice_u8(self) > 0; } +/** + * Returns true if there are any more bytes to consume + * + * This is equivalent to `self.remaining() != 0`. + * + * # Examples + * + * ``` + * use bytes::Buf; + * + * let mut buf = &b"a"[..]; + * + * assert!(buf.has_remaining()); + * + * buf.get_u8(); + * + * assert!(!buf.has_remaining()); + * ``` + */ +export function hasRemaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self: Chain, rs.ByteSlice>): boolean { + return remaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self) > 0; +} + /** * Returns true if there are any more bytes to consume * @@ -439,6 +485,35 @@ export function copyToSlice$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_by }); } +/** + * Copies bytes from `self` into `dst`. + * + * The cursor is advanced by the number of bytes copied. `self` must have + * enough remaining bytes to fill `dst`. + * + * # Examples + * + * ``` + * use bytes::Buf; + * + * let mut buf = &b"hello world"[..]; + * let mut dst = [0; 5]; + * + * buf.copy_to_slice(&mut dst); + * assert_eq!(&b"hello"[..], &dst); + * assert_eq!(6, buf.remaining()); + * ``` + * + * # Panics + * + * This function panics if `self.remaining() < dst.len()`. + */ +export function copyToSlice$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self: Chain, rs.ByteSlice>, dst: rs.ByteSlice): void { + result_unwrapOrElse$1fg63zn(tryCopyToSlice$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self, dst), (error: TryGetError.TryGetError): undefined => { + panicAdvance(error); + }); +} + /** * Copies bytes from `self` into `dst`. * @@ -700,6 +775,35 @@ export function getU8$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_By panicAdvance({ requested: 1, available: 0 }); } +/** + * Gets an unsigned 8 bit integer from `self`. + * + * The current position is advanced by 1. + * + * # Examples + * + * ``` + * use bytes::Buf; + * + * let mut buf = &b"\x08 hello"[..]; + * assert_eq!(8, buf.get_u8()); + * ``` + * + * # Panics + * + * This function panics if there is no more remaining data in `self`. + */ +export function getU8$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self: Chain, rs.ByteSlice>): rs.u8 { + if (!(remaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8_mut(self) < 1)) { + const _7: rs.ByteSlice = chunk$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8_mut(self); + rs.idx(_7, 0); + const ret: rs.u8 = _7.data[_7.start]; + advance$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self, 1); + return ret; + } + panicAdvance({ requested: 1, available: 0 }); +} + /** * Gets an unsigned 8 bit integer from `self`. * @@ -961,6 +1065,35 @@ export function getI8$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_By panicAdvance({ requested: 1, available: 0 }); } +/** + * Gets a signed 8 bit integer from `self`. + * + * The current position is advanced by 1. + * + * # Examples + * + * ``` + * use bytes::Buf; + * + * let mut buf = &b"\x08 hello"[..]; + * assert_eq!(8, buf.get_i8()); + * ``` + * + * # Panics + * + * This function panics if there is no more remaining data in `self`. + */ +export function getI8$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self: Chain, rs.ByteSlice>): rs.i8 { + if (!(remaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8_mut(self) < 1)) { + const _8: rs.ByteSlice = chunk$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8_mut(self); + rs.idx(_8, 0); + const ret: rs.i8 = (_8.data[_8.start] << 24) >> 24; + advance$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self, 1); + return ret; + } + panicAdvance({ requested: 1, available: 0 }); +} + /** * Gets a signed 8 bit integer from `self`. * @@ -1276,6 +1409,44 @@ export function getUint$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_ }); } +/** + * Gets an unsigned n-byte integer from `self` in big-endian byte order. + * + * The current position is advanced by `nbytes`. + * + * # Examples + * + * ``` + * use bytes::Buf; + * + * let mut buf = &b"\x01\x02\x03 hello"[..]; + * assert_eq!(0x010203, buf.get_uint(3)); + * ``` + * + * # Panics + * + * This function panics if there is not enough remaining data in `self`, or + * if `nbytes` is greater than 8. + */ +export function getUint$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self: Chain, rs.ByteSlice>, nbytes: rs.usize): rs.u64 { + return result_unwrapOrElse$1b4ownx(((): rs.Result => { + const _2: rs.usize | undefined = rs.usizeCheckedSub(8, nbytes); + if (_2 === undefined) { + panicDoesNotFit(8, nbytes); + } else { + const sliceAt: rs.usize = _2; + const buf: Uint8Array = rs.bytes(8); + const _9: rs.Result = tryCopyToSlice$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self, rs.byteSliceRange(rs.byteSliceFrom(buf), sliceAt)); + if (_9.ok) { + return rs.Ok(rs.u64FromBeBytes(buf)); + } + return _9; + } + })(), (error: TryGetError.TryGetError): rs.u64 => { + panicAdvance(error); + }); +} + /** * Gets an unsigned n-byte integer from `self` in big-endian byte order. * @@ -1612,6 +1783,43 @@ export function getUintLe$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_byte }); } +/** + * Gets an unsigned n-byte integer from `self` in little-endian byte order. + * + * The current position is advanced by `nbytes`. + * + * # Examples + * + * ``` + * use bytes::Buf; + * + * let mut buf = &b"\x03\x02\x01 hello"[..]; + * assert_eq!(0x010203, buf.get_uint_le(3)); + * ``` + * + * # Panics + * + * This function panics if there is not enough remaining data in `self`, or + * if `nbytes` is greater than 8. + */ +export function getUintLe$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self: Chain, rs.ByteSlice>, nbytes: rs.usize): rs.u64 { + return result_unwrapOrElse$1b4ownx(((): rs.Result => { + const buf: Uint8Array = rs.bytes(8); + const _32: rs.ByteSlice | undefined = rs.byteSliceGetRange(rs.byteSliceFrom(buf), 0, nbytes); + if (_32 === undefined) { + panicDoesNotFit(8, nbytes); + } else { + const _12: rs.Result = tryCopyToSlice$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self, _32); + if (_12.ok) { + return rs.Ok(rs.u64FromBeBytes(buf.slice().reverse())); + } + return _12; + } + })(), (error: TryGetError.TryGetError): rs.u64 => { + panicAdvance(error); + }); +} + /** * Gets an unsigned n-byte integer from `self` in little-endian byte order. * @@ -1861,6 +2069,29 @@ export function getIntLe$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes return signExtend(getUintLe$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_Bytes_ref_slice_u8(self, nbytes), nbytes); } +/** + * Gets a signed n-byte integer from `self` in little-endian byte order. + * + * The current position is advanced by `nbytes`. + * + * # Examples + * + * ``` + * use bytes::Buf; + * + * let mut buf = &b"\x03\x02\x01 hello"[..]; + * assert_eq!(0x010203, buf.get_int_le(3)); + * ``` + * + * # Panics + * + * This function panics if there is not enough remaining data in `self`, or + * if `nbytes` is greater than 8. + */ +export function getIntLe$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self: Chain, rs.ByteSlice>, nbytes: rs.usize): rs.i64 { + return signExtend(getUintLe$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self, nbytes), nbytes); +} + /** * Gets a signed n-byte integer from `self` in little-endian byte order. * @@ -2068,6 +2299,29 @@ export function getF32Le$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes return rs.f32FromBits(rs.bufGet(self, 4, true, rs.u32FromBeBytes, remaining$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_Bytes_ref_slice_u8, chunk$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_Bytes_ref_slice_u8, advance$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_Bytes_ref_slice_u8 as (a0: Chain, rs.ByteSlice>, a1: rs.usize) => undefined, copyToSlice$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_Bytes_ref_slice_u8 as (a0: Chain, rs.ByteSlice>, a1: rs.ByteSlice) => undefined)); } +/** + * Gets an IEEE754 single-precision (4 bytes) floating point number from + * `self` in little-endian byte order. + * + * The current position is advanced by 4. + * + * # Examples + * + * ``` + * use bytes::Buf; + * + * let mut buf = &b"\x9A\x99\x99\x3F hello"[..]; + * assert_eq!(1.2f32, buf.get_f32_le()); + * ``` + * + * # Panics + * + * This function panics if there is not enough remaining data in `self`. + */ +export function getF32Le$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self: Chain, rs.ByteSlice>): rs.f32 { + return rs.f32FromBits(rs.bufGet(self, 4, true, rs.u32FromBeBytes, remaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, chunk$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, advance$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain, rs.ByteSlice>, a1: rs.usize) => undefined, copyToSlice$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain, rs.ByteSlice>, a1: rs.ByteSlice) => undefined)); +} + /** * Gets an IEEE754 single-precision (4 bytes) floating point number from * `self` in little-endian byte order. @@ -2275,6 +2529,29 @@ export function getF64$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_B return rs.f64FromBits(rs.bufGet(self, 8, false, rs.u64FromBeBytes, remaining$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_Bytes_ref_slice_u8, chunk$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_Bytes_ref_slice_u8, advance$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_Bytes_ref_slice_u8 as (a0: Chain, rs.ByteSlice>, a1: rs.usize) => undefined, copyToSlice$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_Bytes_ref_slice_u8 as (a0: Chain, rs.ByteSlice>, a1: rs.ByteSlice) => undefined)); } +/** + * Gets an IEEE754 double-precision (8 bytes) floating point number from + * `self` in big-endian byte order. + * + * The current position is advanced by 8. + * + * # Examples + * + * ``` + * use bytes::Buf; + * + * let mut buf = &b"\x3F\xF3\x33\x33\x33\x33\x33\x33 hello"[..]; + * assert_eq!(1.2f64, buf.get_f64()); + * ``` + * + * # Panics + * + * This function panics if there is not enough remaining data in `self`. + */ +export function getF64$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self: Chain, rs.ByteSlice>): rs.f64 { + return rs.f64FromBits(rs.bufGet(self, 8, false, rs.u64FromBeBytes, remaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, chunk$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, advance$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain, rs.ByteSlice>, a1: rs.usize) => undefined, copyToSlice$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain, rs.ByteSlice>, a1: rs.ByteSlice) => undefined)); +} + /** * Gets an IEEE754 double-precision (8 bytes) floating point number from * `self` in big-endian byte order. @@ -2652,10 +2929,56 @@ export function tryCopyToSlice$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf * assert_eq!(11, buf.remaining()); * ``` */ -export function tryCopyToSlice$bytes_Buf_bytes_buf_Chain_ref_slice_u8_bytes_Bytes_buf_Pieces(self: Chain, Pieces.Pieces>, dst: rs.ByteSlice): rs.Result { - if (!(remaining$bytes_Buf_bytes_buf_Chain_ref_slice_u8_bytes_Bytes_buf_Pieces_mut(self) < dst.length)) { +export function tryCopyToSlice$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self: Chain, rs.ByteSlice>, dst: rs.ByteSlice): rs.Result { + if (!(remaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8_mut(self) < dst.length)) { while (!(dst.length === 0)) { - const src: rs.ByteSlice = chunk$bytes_Buf_bytes_buf_Chain_ref_slice_u8_bytes_Bytes_buf_Pieces_mut(self); + const src: rs.ByteSlice = chunk$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8_mut(self); + const cnt: rs.usize = rs.min(src.length, dst.length); + rs.byteSliceCopyFromSlice(rs.byteSliceRange(dst, 0, cnt), rs.byteSliceRange(src, 0, cnt)); + dst = rs.byteSliceRange(dst, cnt); + advance$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self, cnt); + } + return rs.OK; + } + return rs.Err({ requested: dst.length, available: remaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8_mut(self) }); +} + +/** + * Copies bytes from `self` into `dst`. + * + * The cursor is advanced by the number of bytes copied. `self` must have + * enough remaining bytes to fill `dst`. + * + * Returns `Err(TryGetError)` when there are not enough + * remaining bytes to read the value. + * + * # Examples + * + * ``` + * use bytes::Buf; + * + * let mut buf = &b"hello world"[..]; + * let mut dst = [0; 5]; + * + * assert_eq!(Ok(()), buf.try_copy_to_slice(&mut dst)); + * assert_eq!(&b"hello"[..], &dst); + * assert_eq!(6, buf.remaining()); + * ``` + * + * ``` + * use bytes::{Buf, TryGetError}; + * + * let mut buf = &b"hello world"[..]; + * let mut dst = [0; 12]; + * + * assert_eq!(Err(TryGetError{requested: 12, available: 11}), buf.try_copy_to_slice(&mut dst)); + * assert_eq!(11, buf.remaining()); + * ``` + */ +export function tryCopyToSlice$bytes_Buf_bytes_buf_Chain_ref_slice_u8_bytes_Bytes_buf_Pieces(self: Chain, Pieces.Pieces>, dst: rs.ByteSlice): rs.Result { + if (!(remaining$bytes_Buf_bytes_buf_Chain_ref_slice_u8_bytes_Bytes_buf_Pieces_mut(self) < dst.length)) { + while (!(dst.length === 0)) { + const src: rs.ByteSlice = chunk$bytes_Buf_bytes_buf_Chain_ref_slice_u8_bytes_Bytes_buf_Pieces_mut(self); const cnt: rs.usize = rs.min(src.length, dst.length); rs.byteSliceCopyFromSlice(rs.byteSliceRange(dst, 0, cnt), rs.byteSliceRange(src, 0, cnt)); dst = rs.byteSliceRange(dst, cnt); @@ -2980,6 +3303,43 @@ export function tryGetU8$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes return undefined; } +/** + * Gets an unsigned 8 bit integer from `self`. + * + * The current position is advanced by 1. + * + * Returns `Err(TryGetError)` when there are not enough + * remaining bytes to read the value. + * + * # Examples + * + * ``` + * use bytes::Buf; + * + * let mut buf = &b"\x08 hello"[..]; + * assert_eq!(Ok(0x08_u8), buf.try_get_u8()); + * assert_eq!(6, buf.remaining()); + * ``` + * + * ``` + * use bytes::{Buf, TryGetError}; + * + * let mut buf = &b""[..]; + * assert_eq!(Err(TryGetError{requested: 1, available: 0}), buf.try_get_u8()); + * ``` + */ +export function tryGetU8$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self: Chain, rs.ByteSlice>): rs.u8 | undefined { + if (!(remaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8_mut(self) < 1)) { + const _9: rs.ByteSlice = chunk$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8_mut(self); + rs.idx(_9, 0); + const ret: rs.u8 = _9.data[_9.start]; + advance$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self, 1); + return ret; + } + out$u8.err = { requested: 1, available: remaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8_mut(self) }; + return undefined; +} + /** * Gets an unsigned 8 bit integer from `self`. * @@ -3139,6 +3499,27 @@ export function chain$bytes_Buf_boxed_Box_dyn_bytes_Buf_bytes_Bytes_ref_slice_u8 return new$bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_Bytes_ref_slice_u8(self, next); } +/** + * Creates an adaptor which will chain this buffer with another. + * + * The returned `Buf` instance will first consume all bytes from `self`. + * Afterwards the output is equivalent to the output of next. + * + * # Examples + * + * ``` + * use bytes::Buf; + * + * let mut chain = b"hello "[..].chain(&b"world"[..]); + * + * let full = chain.copy_to_bytes(11); + * assert_eq!(full.chunk(), b"hello world"); + * ``` + */ +export function chain$bytes_Buf_buf_Pieces_bytes_Bytes_ref_slice_u8(self: Chain, next: rs.ByteSlice): Chain, rs.ByteSlice> { + return new$bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self, next); +} + /** * Creates an adaptor which will chain this buffer with another. * @@ -3196,6 +3577,42 @@ export function advance$bytes_Buf_boxed_Box_dyn_bytes_Buf_bytes_Bytes_mut(self: advance$bytes_Buf_boxed_Box_dyn_bytes_Buf_bytes_Bytes(self.v, cnt); } +/** + * Advance the internal cursor of the Buf + * + * The next call to `chunk()` will return a slice starting `cnt` bytes + * further into the underlying buffer. + * + * # Examples + * + * ``` + * use bytes::Buf; + * + * let mut buf = &b"hello world"[..]; + * + * assert_eq!(buf.chunk(), &b"hello world"[..]); + * + * buf.advance(6); + * + * assert_eq!(buf.chunk(), &b"world"[..]); + * ``` + * + * # Panics + * + * This function **may** panic if `cnt > self.remaining()`. + * + * # Implementer notes + * + * It is recommended for implementations of `advance` to panic if `cnt > + * self.remaining()`. If the implementation does not panic, the call must + * behave as if `cnt == self.remaining()`. + * + * A call with `cnt == 0` should never panic and be a no-op. + */ +export function advance$bytes_Buf_buf_Pieces_bytes_Bytes_mut(self: rs.Place>, cnt: rs.usize): void { + advance$bytes_Buf_buf_Pieces_bytes_Bytes(self.v, cnt); +} + /** * Advance the internal cursor of the Buf * @@ -3336,6 +3753,40 @@ export function chunk$bytes_Buf_buf_Pieces_buf_Provided_mut(self: Chain): rs.ByteSlice { + return chunk$bytes_Buf_buf_Pieces_bytes_Bytes(self); +} + /** * Returns a slice starting at the current position and of length between 0 * and `Buf::remaining()`. Note that this *can* return a shorter slice (this @@ -3540,6 +3991,40 @@ export function chunk$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_By return chunk$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_Bytes_ref_slice_u8(self); } +/** + * Returns a slice starting at the current position and of length between 0 + * and `Buf::remaining()`. Note that this *can* return a shorter slice (this + * allows non-continuous internal representation). + * + * This is a lower level function. Most operations are done with other + * functions. + * + * # Examples + * + * ``` + * use bytes::Buf; + * + * let mut buf = &b"hello world"[..]; + * + * assert_eq!(buf.chunk(), &b"hello world"[..]); + * + * buf.advance(6); + * + * assert_eq!(buf.chunk(), &b"world"[..]); + * ``` + * + * # Implementer notes + * + * This function should never panic. `chunk()` should return an empty + * slice **if and only if** `remaining()` returns 0. In other words, + * `chunk()` returning an empty slice implies that `remaining()` will + * return 0 and `remaining()` returning 0 implies that `chunk()` will + * return an empty slice. + */ +export function chunk$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8_mut(self: Chain, rs.ByteSlice>): rs.ByteSlice { + return chunk$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self); +} + /** * Returns a slice starting at the current position and of length between 0 * and `Buf::remaining()`. Note that this *can* return a shorter slice (this @@ -3701,6 +4186,31 @@ export function copyToBytes$bytes_Buf_boxed_Box_dyn_bytes_Buf_bytes_Bytes_mut(se return copyToBytes$bytes_Buf_boxed_Box_dyn_bytes_Buf_bytes_Bytes(self.v, len); } +/** + * Consumes `len` bytes inside self and returns new instance of `Bytes` + * with this data. + * + * This function may be optimized by the underlying type to avoid actual + * copies. For example, `Bytes` implementation will do a shallow copy + * (ref-count increment). + * + * # Examples + * + * ``` + * use bytes::Buf; + * + * let bytes = (&b"hello world"[..]).copy_to_bytes(5); + * assert_eq!(&bytes[..], &b"hello"[..]); + * ``` + * + * # Panics + * + * This function panics if `len > self.remaining()`. + */ +export function copyToBytes$bytes_Buf_buf_Pieces_bytes_Bytes_mut(self: rs.Place>, len: rs.usize): rs.ByteSlice { + return copyToBytes$bytes_Buf_buf_Pieces_bytes_Bytes(self.v, len); +} + /** * Consumes `len` bytes inside self and returns new instance of `Bytes` * with this data. @@ -3797,6 +4307,29 @@ export function hasRemaining$bytes_Buf_buf_Pieces_buf_Provided_mut(self: Chain

): boolean { + return hasRemaining$bytes_Buf_buf_Pieces_bytes_Bytes(self); +} + /** * Returns true if there are any more bytes to consume * @@ -4047,8 +4580,8 @@ export function remaining$bytes_Buf_buf_Pieces_buf_Provided_mut(self: Chain): rs.usize { - return remaining$bytes_Buf_buf_Provided_bytes_Bytes(self); +export function remaining$bytes_Buf_buf_Pieces_bytes_Bytes_mut(self: Chain): rs.usize { + return remaining$bytes_Buf_buf_Pieces_bytes_Bytes(self); } /** @@ -4078,8 +4611,8 @@ export function remaining$bytes_Buf_buf_Provided_bytes_Bytes_mut(self: Chain>): rs.usize { - return remaining$bytes_Buf_buf_Provided_mut_ref_slice_u8(self); +export function remaining$bytes_Buf_buf_Provided_bytes_Bytes_mut(self: Chain): rs.usize { + return remaining$bytes_Buf_buf_Provided_bytes_Bytes(self); } /** @@ -4109,8 +4642,8 @@ export function remaining$bytes_Buf_buf_Provided_mut_ref_slice_u8_mut(self: Chai * not change unless a call is made to `advance` or any other function that * is documented to change the `Buf`'s current position. */ -export function remaining$bytes_Buf_buf_Provided_ref_slice_u8_mut(self: Chain): rs.usize { - return remaining$bytes_Buf_buf_Provided_ref_slice_u8(self); +export function remaining$bytes_Buf_buf_Provided_mut_ref_slice_u8_mut(self: Chain>): rs.usize { + return remaining$bytes_Buf_buf_Provided_mut_ref_slice_u8(self); } /** @@ -4140,8 +4673,8 @@ export function remaining$bytes_Buf_buf_Provided_ref_slice_u8_mut(self: Chain>): rs.usize { - return remaining$bytes_Buf_bytes_Bytes_bytes_buf_Chain_buf_Provided_ref_slice_u8(self); +export function remaining$bytes_Buf_buf_Provided_ref_slice_u8_mut(self: Chain): rs.usize { + return remaining$bytes_Buf_buf_Provided_ref_slice_u8(self); } /** @@ -4171,8 +4704,8 @@ export function remaining$bytes_Buf_bytes_Bytes_bytes_buf_Chain_buf_Provided_ref * not change unless a call is made to `advance` or any other function that * is documented to change the `Buf`'s current position. */ -export function remaining$bytes_Buf_bytes_Bytes_ref_slice_u8_mut(self: Chain): rs.usize { - return remaining$bytes_Buf_bytes_Bytes_ref_slice_u8(self); +export function remaining$bytes_Buf_bytes_Bytes_bytes_buf_Chain_buf_Provided_ref_slice_u8_mut(self: Chain>): rs.usize { + return remaining$bytes_Buf_bytes_Bytes_bytes_buf_Chain_buf_Provided_ref_slice_u8(self); } /** @@ -4202,10 +4735,72 @@ export function remaining$bytes_Buf_bytes_Bytes_ref_slice_u8_mut(self: Chain, rs.ByteSlice>): rs.usize { +export function remaining$bytes_Buf_bytes_Bytes_ref_slice_u8_mut(self: Chain): rs.usize { + return remaining$bytes_Buf_bytes_Bytes_ref_slice_u8(self); +} + +/** + * Returns the number of bytes between the current position and the end of + * the buffer. + * + * This value is greater than or equal to the length of the slice returned + * by `chunk()`. + * + * # Examples + * + * ``` + * use bytes::Buf; + * + * let mut buf = &b"hello world"[..]; + * + * assert_eq!(buf.remaining(), 11); + * + * buf.get_u8(); + * + * assert_eq!(buf.remaining(), 10); + * ``` + * + * # Implementer notes + * + * Implementations of `remaining` should ensure that the return value does + * not change unless a call is made to `advance` or any other function that + * is documented to change the `Buf`'s current position. + */ +export function remaining$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_Bytes_ref_slice_u8_mut(self: Chain, rs.ByteSlice>): rs.usize { return remaining$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_Bytes_ref_slice_u8(self); } +/** + * Returns the number of bytes between the current position and the end of + * the buffer. + * + * This value is greater than or equal to the length of the slice returned + * by `chunk()`. + * + * # Examples + * + * ``` + * use bytes::Buf; + * + * let mut buf = &b"hello world"[..]; + * + * assert_eq!(buf.remaining(), 11); + * + * buf.get_u8(); + * + * assert_eq!(buf.remaining(), 10); + * ``` + * + * # Implementer notes + * + * Implementations of `remaining` should ensure that the return value does + * not change unless a call is made to `advance` or any other function that + * is documented to change the `Buf`'s current position. + */ +export function remaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8_mut(self: Chain, rs.ByteSlice>): rs.usize { + return remaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self); +} + /** * Returns the number of bytes between the current position and the end of * the buffer. @@ -4377,6 +4972,10 @@ export function new$buf_Pieces_buf_Provided(a: Pieces.Pieces, b: Provided.Provid return new Chain(a, b); } +export function new$buf_Pieces_bytes_Bytes(a: Pieces.Pieces, b: rs.ByteSlice): Chain { + return new Chain(a, b); +} + export function new$buf_Provided_bytes_Bytes(a: Provided.Provided, b: rs.ByteSlice): Chain { return new Chain(a, b); } @@ -4401,6 +5000,10 @@ export function new$bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_Bytes_ref_slic return new Chain(a, b); } +export function new$bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(a: Chain, b: rs.ByteSlice): Chain, rs.ByteSlice> { + return new Chain(a, b); +} + export function new$bytes_buf_Chain_ref_slice_u8_bytes_Bytes_buf_Pieces(a: Chain, b: Pieces.Pieces): Chain, Pieces.Pieces> { return new Chain(a, b); } @@ -4479,6 +5082,37 @@ export function remaining$bytes_Buf_buf_Pieces_buf_Provided(self: Chain): rs.usize { + return rs.usizeSaturatingAdd(Pieces.remaining$bytes_Buf(self.a), self.b.length); +} + /** * Returns the number of bytes between the current position and the end of * the buffer. @@ -4665,6 +5299,37 @@ export function remaining$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_byte return rs.usizeSaturatingAdd(remaining$bytes_Buf_boxed_Box_dyn_bytes_Buf_bytes_Bytes(self.a), self.b.length); } +/** + * Returns the number of bytes between the current position and the end of + * the buffer. + * + * This value is greater than or equal to the length of the slice returned + * by `chunk()`. + * + * # Examples + * + * ``` + * use bytes::Buf; + * + * let mut buf = &b"hello world"[..]; + * + * assert_eq!(buf.remaining(), 11); + * + * buf.get_u8(); + * + * assert_eq!(buf.remaining(), 10); + * ``` + * + * # Implementer notes + * + * Implementations of `remaining` should ensure that the return value does + * not change unless a call is made to `advance` or any other function that + * is documented to change the `Buf`'s current position. + */ +export function remaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self: Chain, rs.ByteSlice>): rs.usize { + return rs.usizeSaturatingAdd(remaining$bytes_Buf_buf_Pieces_bytes_Bytes(self.a), self.b.length); +} + /** * Returns the number of bytes between the current position and the end of * the buffer. @@ -4863,6 +5528,43 @@ export function chunk$bytes_Buf_buf_Pieces_buf_Provided(self: Chain): rs.ByteSlice { + if (!Pieces.hasRemaining$bytes_Buf(self.a)) { + return self.b; + } + return Pieces.chunk$bytes_Buf(self.a); +} + /** * Returns a slice starting at the current position and of length between 0 * and `Buf::remaining()`. Note that this *can* return a shorter slice (this @@ -5085,6 +5787,43 @@ export function chunk$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_By return chunk$bytes_Buf_boxed_Box_dyn_bytes_Buf_bytes_Bytes(self.a); } +/** + * Returns a slice starting at the current position and of length between 0 + * and `Buf::remaining()`. Note that this *can* return a shorter slice (this + * allows non-continuous internal representation). + * + * This is a lower level function. Most operations are done with other + * functions. + * + * # Examples + * + * ``` + * use bytes::Buf; + * + * let mut buf = &b"hello world"[..]; + * + * assert_eq!(buf.chunk(), &b"hello world"[..]); + * + * buf.advance(6); + * + * assert_eq!(buf.chunk(), &b"world"[..]); + * ``` + * + * # Implementer notes + * + * This function should never panic. `chunk()` should return an empty + * slice **if and only if** `remaining()` returns 0. In other words, + * `chunk()` returning an empty slice implies that `remaining()` will + * return 0 and `remaining()` returning 0 implies that `chunk()` will + * return an empty slice. + */ +export function chunk$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self: Chain, rs.ByteSlice>): rs.ByteSlice { + if (!hasRemaining$bytes_Buf_buf_Pieces_bytes_Bytes(self.a)) { + return self.b; + } + return chunk$bytes_Buf_buf_Pieces_bytes_Bytes(self.a); +} + /** * Returns a slice starting at the current position and of length between 0 * and `Buf::remaining()`. Note that this *can* return a shorter slice (this @@ -5329,6 +6068,54 @@ export function advance$bytes_Buf_buf_Pieces_buf_Provided(self: Chain self.remaining()`. + * + * # Implementer notes + * + * It is recommended for implementations of `advance` to panic if `cnt > + * self.remaining()`. If the implementation does not panic, the call must + * behave as if `cnt == self.remaining()`. + * + * A call with `cnt == 0` should never panic and be a no-op. + */ +export function advance$bytes_Buf_buf_Pieces_bytes_Bytes(self: Chain, cnt: rs.usize): void { + const aRem: rs.usize = Pieces.remaining$bytes_Buf(self.a); + b0: { + if (aRem !== 0) { + if (!(aRem >= cnt)) { + Pieces.advance$bytes_Buf(self.a, aRem); + cnt = rs.usizeSub(cnt, aRem); + } else { + Pieces.advance$bytes_Buf(self.a, cnt); + break b0; + } + } + rs.bytesAdvance(rs.place(() => self.b, (value) => self.b = value), cnt); + } +} + /** * Advance the internal cursor of the Buf * @@ -5617,6 +6404,54 @@ export function advance$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_ } } +/** + * Advance the internal cursor of the Buf + * + * The next call to `chunk()` will return a slice starting `cnt` bytes + * further into the underlying buffer. + * + * # Examples + * + * ``` + * use bytes::Buf; + * + * let mut buf = &b"hello world"[..]; + * + * assert_eq!(buf.chunk(), &b"hello world"[..]); + * + * buf.advance(6); + * + * assert_eq!(buf.chunk(), &b"world"[..]); + * ``` + * + * # Panics + * + * This function **may** panic if `cnt > self.remaining()`. + * + * # Implementer notes + * + * It is recommended for implementations of `advance` to panic if `cnt > + * self.remaining()`. If the implementation does not panic, the call must + * behave as if `cnt == self.remaining()`. + * + * A call with `cnt == 0` should never panic and be a no-op. + */ +export function advance$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self: Chain, rs.ByteSlice>, cnt: rs.usize): void { + const aRem: rs.usize = remaining$bytes_Buf_buf_Pieces_bytes_Bytes(self.a); + b0: { + if (aRem !== 0) { + if (!(aRem >= cnt)) { + advance$bytes_Buf_buf_Pieces_bytes_Bytes(self.a, aRem); + cnt = rs.usizeSub(cnt, aRem); + } else { + advance$bytes_Buf_buf_Pieces_bytes_Bytes(self.a, cnt); + break b0; + } + } + rs.byteSliceAdvance(rs.place(() => self.b, (value) => self.b = value), cnt); + } +} + /** * Advance the internal cursor of the Buf * @@ -5809,6 +6644,181 @@ export function advance$bytes_Buf_ref_slice_u8_bytes_BytesMut(self: Chain, dst: rs.Slice): rs.usize { + const n: rs.usize = buf_impl_chunksVectored$bytes_Buf_boxed_Box_dyn_bytes_Buf(self.a, dst); + const _7: rs.Slice = rs.sliceRange(dst, n); + return rs.usizeAdd(n, buf_impl_chunksVectored$bytes_Buf_bytes_Bytes(self.b, _7)); +} + +/** + * Fills `dst` with potentially multiple slices starting at `self`'s + * current position. + * + * If the `Buf` is backed by disjoint slices of bytes, `chunk_vectored` enables + * fetching more than one slice at once. `dst` is a slice of `IoSlice` + * references, enabling the slice to be directly used with [`writev`] + * without any further conversion. The sum of the lengths of all the + * buffers written to `dst` will be less than or equal to `Buf::remaining()`. + * + * The entries in `dst` will be overwritten, but the data **contained** by + * the slices **will not** be modified. The return value is the number of + * slices written to `dst`. If `Buf::remaining()` is non-zero, then this + * writes at least one non-empty slice to `dst`. + * + * This is a lower level function. Most operations are done with other + * functions. + * + * # Implementer notes + * + * This function should never panic. Once the end of the buffer is reached, + * i.e., `Buf::remaining` returns 0, calls to `chunk_vectored` must return 0 + * without mutating `dst`. + * + * Implementations should also take care to properly handle being called + * with `dst` being a zero length slice. + * + * [`writev`]: http://man7.org/linux/man-pages/man2/readv.2.html + */ +export function chunksVectored$bytes_Buf_buf_Pieces_bytes_Bytes(self: Chain, dst: rs.Slice): rs.usize { + const n: rs.usize = Pieces.chunksVectored$bytes_Buf(self.a, dst); + const _7: rs.Slice = rs.sliceRange(dst, n); + return rs.usizeAdd(n, buf_impl_chunksVectored$bytes_Buf_bytes_Bytes(self.b, _7)); +} + +/** + * Fills `dst` with potentially multiple slices starting at `self`'s + * current position. + * + * If the `Buf` is backed by disjoint slices of bytes, `chunk_vectored` enables + * fetching more than one slice at once. `dst` is a slice of `IoSlice` + * references, enabling the slice to be directly used with [`writev`] + * without any further conversion. The sum of the lengths of all the + * buffers written to `dst` will be less than or equal to `Buf::remaining()`. + * + * The entries in `dst` will be overwritten, but the data **contained** by + * the slices **will not** be modified. The return value is the number of + * slices written to `dst`. If `Buf::remaining()` is non-zero, then this + * writes at least one non-empty slice to `dst`. + * + * This is a lower level function. Most operations are done with other + * functions. + * + * # Implementer notes + * + * This function should never panic. Once the end of the buffer is reached, + * i.e., `Buf::remaining` returns 0, calls to `chunk_vectored` must return 0 + * without mutating `dst`. + * + * Implementations should also take care to properly handle being called + * with `dst` being a zero length slice. + * + * [`writev`]: http://man7.org/linux/man-pages/man2/readv.2.html + */ +export function chunksVectored$bytes_Buf_buf_Provided_mut_ref_slice_u8(self: Chain>, dst: rs.Slice): rs.usize { + const n: rs.usize = Provided.chunksVectored$bytes_Buf(self.a, dst); + const _7: rs.Slice = rs.sliceRange(dst, n); + return rs.usizeAdd(n, buf_impl_chunksVectored$bytes_Buf_mut_ref_slice_u8(self.b, _7)); +} + +/** + * Fills `dst` with potentially multiple slices starting at `self`'s + * current position. + * + * If the `Buf` is backed by disjoint slices of bytes, `chunk_vectored` enables + * fetching more than one slice at once. `dst` is a slice of `IoSlice` + * references, enabling the slice to be directly used with [`writev`] + * without any further conversion. The sum of the lengths of all the + * buffers written to `dst` will be less than or equal to `Buf::remaining()`. + * + * The entries in `dst` will be overwritten, but the data **contained** by + * the slices **will not** be modified. The return value is the number of + * slices written to `dst`. If `Buf::remaining()` is non-zero, then this + * writes at least one non-empty slice to `dst`. + * + * This is a lower level function. Most operations are done with other + * functions. + * + * # Implementer notes + * + * This function should never panic. Once the end of the buffer is reached, + * i.e., `Buf::remaining` returns 0, calls to `chunk_vectored` must return 0 + * without mutating `dst`. + * + * Implementations should also take care to properly handle being called + * with `dst` being a zero length slice. + * + * [`writev`]: http://man7.org/linux/man-pages/man2/readv.2.html + */ +export function chunksVectored$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_Bytes_ref_slice_u8(self: Chain, rs.ByteSlice>, dst: rs.Slice): rs.usize { + const n: rs.usize = chunksVectored$bytes_Buf_boxed_Box_dyn_bytes_Buf_bytes_Bytes(self.a, dst); + const _7: rs.Slice = rs.sliceRange(dst, n); + return rs.usizeAdd(n, buf_impl_chunksVectored$bytes_Buf_ref_slice_u8(self.b, _7)); +} + +/** + * Fills `dst` with potentially multiple slices starting at `self`'s + * current position. + * + * If the `Buf` is backed by disjoint slices of bytes, `chunk_vectored` enables + * fetching more than one slice at once. `dst` is a slice of `IoSlice` + * references, enabling the slice to be directly used with [`writev`] + * without any further conversion. The sum of the lengths of all the + * buffers written to `dst` will be less than or equal to `Buf::remaining()`. + * + * The entries in `dst` will be overwritten, but the data **contained** by + * the slices **will not** be modified. The return value is the number of + * slices written to `dst`. If `Buf::remaining()` is non-zero, then this + * writes at least one non-empty slice to `dst`. + * + * This is a lower level function. Most operations are done with other + * functions. + * + * # Implementer notes + * + * This function should never panic. Once the end of the buffer is reached, + * i.e., `Buf::remaining` returns 0, calls to `chunk_vectored` must return 0 + * without mutating `dst`. + * + * Implementations should also take care to properly handle being called + * with `dst` being a zero length slice. + * + * [`writev`]: http://man7.org/linux/man-pages/man2/readv.2.html + */ +export function chunksVectored$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self: Chain, rs.ByteSlice>, dst: rs.Slice): rs.usize { + const n: rs.usize = chunksVectored$bytes_Buf_buf_Pieces_bytes_Bytes(self.a, dst); + const _7: rs.Slice = rs.sliceRange(dst, n); + return rs.usizeAdd(n, buf_impl_chunksVectored$bytes_Buf_ref_slice_u8(self.b, _7)); +} + /** * Consumes `len` bytes inside self and returns new instance of `Bytes` * with this data. @@ -5892,6 +6902,48 @@ export function copyToBytes$bytes_Buf_buf_Pieces_buf_Provided(self: Chain self.remaining()`. + */ +export function copyToBytes$bytes_Buf_buf_Pieces_bytes_Bytes(self: Chain, len: rs.usize): rs.ByteSlice { + let _0!: rs.ByteSlice; + const aRem: rs.usize = Pieces.remaining$bytes_Buf(self.a); + if (!(aRem >= len)) { + if (!(aRem === 0)) { + if (!(rs.usizeSub(len, aRem) <= self.b.length)) { + rs.panicFmt(["`len` greater than remaining"]); + return _0; + } + const ret: rs.BytesMut = rs.bytesMutWithCapacity(len); + rs.bytesMutPutBuf(ret, { v: self.a }, (p: rs.Place) => Pieces.hasRemaining$bytes_Buf_mut(p.v), (p: rs.Place) => Pieces.remaining$bytes_Buf_mut(p.v), (p: rs.Place) => Pieces.chunk$bytes_Buf_mut(p.v), Pieces.advance$bytes_Buf_mut as (a0: rs.Place, a1: rs.usize) => undefined, Pieces.copyToBytes$bytes_Buf_mut); + const _24: rs.usize = rs.usizeSub(len, aRem); + const _22: Take.Take> = buf_impl_take$bytes_Buf_mut_bytes_Bytes(rs.place(() => self.b, (value2) => self.b = value2), _24); + rs.bytesMutPutBuf(ret, _22, Take.hasRemaining$bytes_Buf_mut_bytes_Bytes, Take.remaining$bytes_Buf_mut_bytes_Bytes, Take.chunk$bytes_Buf_mut_bytes_Bytes, Take.advance$bytes_Buf_mut_bytes_Bytes as (a0: Take.Take>, a1: rs.usize) => undefined, Take.copyToBytes$bytes_Buf_mut_bytes_Bytes); + return rs.bytesMutFreeze(ret); + } + return rs.bytesSplitTo(rs.place(() => self.b, (value) => self.b = value), len); + } + return Pieces.copyToBytes$bytes_Buf(self.a, len); +} + /** * Consumes `len` bytes inside self and returns new instance of `Bytes` * with this data. @@ -6143,6 +7195,48 @@ export function copyToBytes$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_by return copyToBytes$bytes_Buf_boxed_Box_dyn_bytes_Buf_bytes_Bytes(self.a, len); } +/** + * Consumes `len` bytes inside self and returns new instance of `Bytes` + * with this data. + * + * This function may be optimized by the underlying type to avoid actual + * copies. For example, `Bytes` implementation will do a shallow copy + * (ref-count increment). + * + * # Examples + * + * ``` + * use bytes::Buf; + * + * let bytes = (&b"hello world"[..]).copy_to_bytes(5); + * assert_eq!(&bytes[..], &b"hello"[..]); + * ``` + * + * # Panics + * + * This function panics if `len > self.remaining()`. + */ +export function copyToBytes$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(self: Chain, rs.ByteSlice>, len: rs.usize): rs.ByteSlice { + let _0!: rs.ByteSlice; + const aRem: rs.usize = remaining$bytes_Buf_buf_Pieces_bytes_Bytes(self.a); + if (!(aRem >= len)) { + if (!(aRem === 0)) { + if (!(rs.usizeSub(len, aRem) <= self.b.length)) { + rs.panicFmt(["`len` greater than remaining"]); + return _0; + } + const ret: rs.BytesMut = rs.bytesMutWithCapacity(len); + rs.bytesMutPutBuf(ret, { v: self.a }, (p: rs.Place>) => hasRemaining$bytes_Buf_buf_Pieces_bytes_Bytes_mut(p.v), (p: rs.Place>) => remaining$bytes_Buf_buf_Pieces_bytes_Bytes_mut(p.v), (p: rs.Place>) => chunk$bytes_Buf_buf_Pieces_bytes_Bytes_mut(p.v), advance$bytes_Buf_buf_Pieces_bytes_Bytes_mut as (a0: rs.Place>, a1: rs.usize) => undefined, copyToBytes$bytes_Buf_buf_Pieces_bytes_Bytes_mut); + const _24: rs.usize = rs.usizeSub(len, aRem); + const _22: Take.Take> = buf_impl_take$bytes_Buf_mut_ref_slice_u8(rs.place(() => self.b, (value2) => self.b = value2), _24); + rs.bytesMutPutBuf(ret, _22, Take.hasRemaining$bytes_Buf_mut_ref_slice_u8, Take.remaining$bytes_Buf_mut_ref_slice_u8, Take.chunk$bytes_Buf_mut_ref_slice_u8, Take.advance$bytes_Buf_mut_ref_slice_u8 as (a0: Take.Take>, a1: rs.usize) => undefined, Take.copyToBytes$bytes_Buf_mut_ref_slice_u8); + return rs.bytesMutFreeze(ret); + } + return rs.byteSliceCopyToBytes(rs.place(() => self.b, (value) => self.b = value), len); + } + return copyToBytes$bytes_Buf_buf_Pieces_bytes_Bytes(self.a, len); +} + /** * Consumes `len` bytes inside self and returns new instance of `Bytes` * with this data. diff --git a/ts/fixtures/stock/expected/bytes/buf/take.Take.ts b/ts/fixtures/stock/expected/bytes/buf/take.Take.ts index 9f079a887..01b38a0d8 100644 --- a/ts/fixtures/stock/expected/bytes/buf/take.Take.ts +++ b/ts/fixtures/stock/expected/bytes/buf/take.Take.ts @@ -5,7 +5,7 @@ import { out$u8 } from "../../lib.ts"; import * as Pieces from "../../buf.Pieces.ts"; import * as Provided from "../../buf.Provided.ts"; import { panicAdvance, panicDoesNotFit } from "../../bytes.ts"; -import { signExtend, advance$bytes_Buf_mut_bytes_Bytes as buf_impl_advance$bytes_Buf_mut_bytes_Bytes, advance$bytes_Buf_mut_bytes_BytesMut as buf_impl_advance$bytes_Buf_mut_bytes_BytesMut, advance$bytes_Buf_mut_mut_ref_slice_u8 as buf_impl_advance$bytes_Buf_mut_mut_ref_slice_u8, advance$bytes_Buf_mut_ref_slice_u8 as buf_impl_advance$bytes_Buf_mut_ref_slice_u8, chunk$bytes_Buf_mut_bytes_Bytes as buf_impl_chunk$bytes_Buf_mut_bytes_Bytes, chunk$bytes_Buf_mut_bytes_BytesMut as buf_impl_chunk$bytes_Buf_mut_bytes_BytesMut, chunk$bytes_Buf_mut_mut_ref_slice_u8 as buf_impl_chunk$bytes_Buf_mut_mut_ref_slice_u8, chunk$bytes_Buf_mut_ref_slice_u8 as buf_impl_chunk$bytes_Buf_mut_ref_slice_u8, copyToBytes$bytes_Buf_mut_bytes_Bytes as buf_impl_copyToBytes$bytes_Buf_mut_bytes_Bytes, copyToBytes$bytes_Buf_mut_bytes_BytesMut as buf_impl_copyToBytes$bytes_Buf_mut_bytes_BytesMut, copyToBytes$bytes_Buf_mut_mut_ref_slice_u8 as buf_impl_copyToBytes$bytes_Buf_mut_mut_ref_slice_u8, copyToBytes$bytes_Buf_mut_ref_slice_u8 as buf_impl_copyToBytes$bytes_Buf_mut_ref_slice_u8, remaining$bytes_Buf_mut_bytes_Bytes as buf_impl_remaining$bytes_Buf_mut_bytes_Bytes, remaining$bytes_Buf_mut_bytes_BytesMut as buf_impl_remaining$bytes_Buf_mut_bytes_BytesMut, remaining$bytes_Buf_mut_mut_ref_slice_u8 as buf_impl_remaining$bytes_Buf_mut_mut_ref_slice_u8, remaining$bytes_Buf_mut_ref_slice_u8 as buf_impl_remaining$bytes_Buf_mut_ref_slice_u8 } from "../../bytes/buf/buf_impl.ts"; +import { signExtend, chunksVectored$bytes_Buf_bytes_Bytes as buf_impl_chunksVectored$bytes_Buf_bytes_Bytes, chunksVectored$bytes_Buf_ref_slice_u8 as buf_impl_chunksVectored$bytes_Buf_ref_slice_u8, advance$bytes_Buf_mut_bytes_Bytes as buf_impl_advance$bytes_Buf_mut_bytes_Bytes, advance$bytes_Buf_mut_bytes_BytesMut as buf_impl_advance$bytes_Buf_mut_bytes_BytesMut, advance$bytes_Buf_mut_mut_ref_slice_u8 as buf_impl_advance$bytes_Buf_mut_mut_ref_slice_u8, advance$bytes_Buf_mut_ref_slice_u8 as buf_impl_advance$bytes_Buf_mut_ref_slice_u8, chunk$bytes_Buf_mut_bytes_Bytes as buf_impl_chunk$bytes_Buf_mut_bytes_Bytes, chunk$bytes_Buf_mut_bytes_BytesMut as buf_impl_chunk$bytes_Buf_mut_bytes_BytesMut, chunk$bytes_Buf_mut_mut_ref_slice_u8 as buf_impl_chunk$bytes_Buf_mut_mut_ref_slice_u8, chunk$bytes_Buf_mut_ref_slice_u8 as buf_impl_chunk$bytes_Buf_mut_ref_slice_u8, copyToBytes$bytes_Buf_mut_bytes_Bytes as buf_impl_copyToBytes$bytes_Buf_mut_bytes_Bytes, copyToBytes$bytes_Buf_mut_bytes_BytesMut as buf_impl_copyToBytes$bytes_Buf_mut_bytes_BytesMut, copyToBytes$bytes_Buf_mut_mut_ref_slice_u8 as buf_impl_copyToBytes$bytes_Buf_mut_mut_ref_slice_u8, copyToBytes$bytes_Buf_mut_ref_slice_u8 as buf_impl_copyToBytes$bytes_Buf_mut_ref_slice_u8, remaining$bytes_Buf_mut_bytes_Bytes as buf_impl_remaining$bytes_Buf_mut_bytes_Bytes, remaining$bytes_Buf_mut_bytes_BytesMut as buf_impl_remaining$bytes_Buf_mut_bytes_BytesMut, remaining$bytes_Buf_mut_mut_ref_slice_u8 as buf_impl_remaining$bytes_Buf_mut_mut_ref_slice_u8, remaining$bytes_Buf_mut_ref_slice_u8 as buf_impl_remaining$bytes_Buf_mut_ref_slice_u8 } from "../../bytes/buf/buf_impl.ts"; import * as Chain from "../../bytes/buf/chain.Chain.ts"; import type * as TryGetError from "../../bytes.TryGetError.ts"; import { min$00xoube } from "../../core/cmp.ts"; @@ -2556,4 +2556,178 @@ export function copyToBytes$bytes_Buf_ref_slice_u8(self: Take, len } } +/** + * Fills `dst` with potentially multiple slices starting at `self`'s + * current position. + * + * If the `Buf` is backed by disjoint slices of bytes, `chunk_vectored` enables + * fetching more than one slice at once. `dst` is a slice of `IoSlice` + * references, enabling the slice to be directly used with [`writev`] + * without any further conversion. The sum of the lengths of all the + * buffers written to `dst` will be less than or equal to `Buf::remaining()`. + * + * The entries in `dst` will be overwritten, but the data **contained** by + * the slices **will not** be modified. The return value is the number of + * slices written to `dst`. If `Buf::remaining()` is non-zero, then this + * writes at least one non-empty slice to `dst`. + * + * This is a lower level function. Most operations are done with other + * functions. + * + * # Implementer notes + * + * This function should never panic. Once the end of the buffer is reached, + * i.e., `Buf::remaining` returns 0, calls to `chunk_vectored` must return 0 + * without mutating `dst`. + * + * Implementations should also take care to properly handle being called + * with `dst` being a zero length slice. + * + * [`writev`]: http://man7.org/linux/man-pages/man2/readv.2.html + */ +export function chunksVectored$bytes_Buf_buf_Pieces(self: Take, dst: rs.Slice): rs.usize { + if (!(self.limit === 0)) { + const _6: rs.ByteSlice = rs.byteSliceFrom(Uint8Array.of()); + const slices: rs.ByteSlice[] = Array.from({ length: 16 }, (): rs.ByteSlice => { + return _6; + }); + const _11: rs.Slice = rs.sliceRange(rs.sliceFrom(slices), 0, rs.min(dst.length, 16)); + const cnt: rs.usize = Pieces.chunksVectored$bytes_Buf(self.inner, _11); + let limit: rs.usize = self.limit; + const iter: rs.Iter<[rs.usize, [rs.Place, rs.ByteSlice]]> = rs.iterEnumerate(rs.iterZip(rs.iterSliceMut(rs.sliceRange(dst, 0, cnt)), rs.iterSlice(slices), [false, false])); + while (true) { + const _28: [rs.usize, [rs.Place, rs.ByteSlice]] | rs.Done = iter.next(); + if (_28 === rs.DONE) { + break; + } + const i: rs.usize = _28[0]; + const _34: rs.ByteSlice | undefined = rs.byteSliceGetRange(_28[1][1], 0, limit); + if (_34 !== undefined) { + _28[1][0].v = _34; + return rs.usizeAdd(i, 1); + } + _28[1][0].v = _28[1][1]; + limit = rs.usizeSub(limit, _28[1][1].length); + } + return cnt; + } + return 0; +} + +/** + * Fills `dst` with potentially multiple slices starting at `self`'s + * current position. + * + * If the `Buf` is backed by disjoint slices of bytes, `chunk_vectored` enables + * fetching more than one slice at once. `dst` is a slice of `IoSlice` + * references, enabling the slice to be directly used with [`writev`] + * without any further conversion. The sum of the lengths of all the + * buffers written to `dst` will be less than or equal to `Buf::remaining()`. + * + * The entries in `dst` will be overwritten, but the data **contained** by + * the slices **will not** be modified. The return value is the number of + * slices written to `dst`. If `Buf::remaining()` is non-zero, then this + * writes at least one non-empty slice to `dst`. + * + * This is a lower level function. Most operations are done with other + * functions. + * + * # Implementer notes + * + * This function should never panic. Once the end of the buffer is reached, + * i.e., `Buf::remaining` returns 0, calls to `chunk_vectored` must return 0 + * without mutating `dst`. + * + * Implementations should also take care to properly handle being called + * with `dst` being a zero length slice. + * + * [`writev`]: http://man7.org/linux/man-pages/man2/readv.2.html + */ +export function chunksVectored$bytes_Buf_bytes_Bytes(self: Take, dst: rs.Slice): rs.usize { + if (!(self.limit === 0)) { + const _6: rs.ByteSlice = rs.byteSliceFrom(Uint8Array.of()); + const slices: rs.ByteSlice[] = Array.from({ length: 16 }, (): rs.ByteSlice => { + return _6; + }); + const _11: rs.Slice = rs.sliceRange(rs.sliceFrom(slices), 0, rs.min(dst.length, 16)); + const cnt: rs.usize = buf_impl_chunksVectored$bytes_Buf_bytes_Bytes(self.inner, _11); + let limit: rs.usize = self.limit; + const iter: rs.Iter<[rs.usize, [rs.Place, rs.ByteSlice]]> = rs.iterEnumerate(rs.iterZip(rs.iterSliceMut(rs.sliceRange(dst, 0, cnt)), rs.iterSlice(slices), [false, false])); + while (true) { + const _28: [rs.usize, [rs.Place, rs.ByteSlice]] | rs.Done = iter.next(); + if (_28 === rs.DONE) { + break; + } + const i: rs.usize = _28[0]; + const _34: rs.ByteSlice | undefined = rs.byteSliceGetRange(_28[1][1], 0, limit); + if (_34 !== undefined) { + _28[1][0].v = _34; + return rs.usizeAdd(i, 1); + } + _28[1][0].v = _28[1][1]; + limit = rs.usizeSub(limit, _28[1][1].length); + } + return cnt; + } + return 0; +} + +/** + * Fills `dst` with potentially multiple slices starting at `self`'s + * current position. + * + * If the `Buf` is backed by disjoint slices of bytes, `chunk_vectored` enables + * fetching more than one slice at once. `dst` is a slice of `IoSlice` + * references, enabling the slice to be directly used with [`writev`] + * without any further conversion. The sum of the lengths of all the + * buffers written to `dst` will be less than or equal to `Buf::remaining()`. + * + * The entries in `dst` will be overwritten, but the data **contained** by + * the slices **will not** be modified. The return value is the number of + * slices written to `dst`. If `Buf::remaining()` is non-zero, then this + * writes at least one non-empty slice to `dst`. + * + * This is a lower level function. Most operations are done with other + * functions. + * + * # Implementer notes + * + * This function should never panic. Once the end of the buffer is reached, + * i.e., `Buf::remaining` returns 0, calls to `chunk_vectored` must return 0 + * without mutating `dst`. + * + * Implementations should also take care to properly handle being called + * with `dst` being a zero length slice. + * + * [`writev`]: http://man7.org/linux/man-pages/man2/readv.2.html + */ +export function chunksVectored$bytes_Buf_ref_slice_u8(self: Take, dst: rs.Slice): rs.usize { + if (!(self.limit === 0)) { + const _6: rs.ByteSlice = rs.byteSliceFrom(Uint8Array.of()); + const slices: rs.ByteSlice[] = Array.from({ length: 16 }, (): rs.ByteSlice => { + return _6; + }); + const _11: rs.Slice = rs.sliceRange(rs.sliceFrom(slices), 0, rs.min(dst.length, 16)); + const cnt: rs.usize = buf_impl_chunksVectored$bytes_Buf_ref_slice_u8(self.inner, _11); + let limit: rs.usize = self.limit; + const iter: rs.Iter<[rs.usize, [rs.Place, rs.ByteSlice]]> = rs.iterEnumerate(rs.iterZip(rs.iterSliceMut(rs.sliceRange(dst, 0, cnt)), rs.iterSlice(slices), [false, false])); + while (true) { + const _28: [rs.usize, [rs.Place, rs.ByteSlice]] | rs.Done = iter.next(); + if (_28 === rs.DONE) { + break; + } + const i: rs.usize = _28[0]; + const _34: rs.ByteSlice | undefined = rs.byteSliceGetRange(_28[1][1], 0, limit); + if (_34 !== undefined) { + _28[1][0].v = _34; + return rs.usizeAdd(i, 1); + } + _28[1][0].v = _28[1][1]; + limit = rs.usizeSub(limit, _28[1][1].length); + } + return cnt; + } + return 0; +} + //# sourceMappingURL=take.Take.ts.map diff --git a/ts/fixtures/stock/expected/bytes/buf/take.ts b/ts/fixtures/stock/expected/bytes/buf/take.ts index e444c88cb..f7308a101 100644 --- a/ts/fixtures/stock/expected/bytes/buf/take.ts +++ b/ts/fixtures/stock/expected/bytes/buf/take.ts @@ -6,6 +6,10 @@ import type * as Provided from "../../buf.Provided.ts"; import type * as Chain from "../../bytes/buf/chain.Chain.ts"; import * as Take from "../../bytes/buf/take.Take.ts"; +export function new_$buf_Pieces(inner: Pieces.Pieces, limit: rs.usize): Take.Take { + return new Take.Take(inner, limit); +} + export function new_$bytes_Bytes(inner: rs.ByteSlice, limit: rs.usize): Take.Take { return new Take.Take(inner, limit); } diff --git a/ts/fixtures/stock/expected/bytes/buf/vec_deque.ts b/ts/fixtures/stock/expected/bytes/buf/vec_deque.ts index 671b359a8..460f045a6 100644 --- a/ts/fixtures/stock/expected/bytes/buf/vec_deque.ts +++ b/ts/fixtures/stock/expected/bytes/buf/vec_deque.ts @@ -71,6 +71,56 @@ export function chunk$bytes_Buf_collections_VecDeque_u8(self: rs.VecDeque return _4[1]; } +/** + * Fills `dst` with potentially multiple slices starting at `self`'s + * current position. + * + * If the `Buf` is backed by disjoint slices of bytes, `chunk_vectored` enables + * fetching more than one slice at once. `dst` is a slice of `IoSlice` + * references, enabling the slice to be directly used with [`writev`] + * without any further conversion. The sum of the lengths of all the + * buffers written to `dst` will be less than or equal to `Buf::remaining()`. + * + * The entries in `dst` will be overwritten, but the data **contained** by + * the slices **will not** be modified. The return value is the number of + * slices written to `dst`. If `Buf::remaining()` is non-zero, then this + * writes at least one non-empty slice to `dst`. + * + * This is a lower level function. Most operations are done with other + * functions. + * + * # Implementer notes + * + * This function should never panic. Once the end of the buffer is reached, + * i.e., `Buf::remaining` returns 0, calls to `chunk_vectored` must return 0 + * without mutating `dst`. + * + * Implementations should also take care to properly handle being called + * with `dst` being a zero length slice. + * + * [`writev`]: http://man7.org/linux/man-pages/man2/readv.2.html + */ +export function chunksVectored$bytes_Buf_collections_VecDeque_u8(self: rs.VecDeque, dst: rs.Slice): rs.usize { + if (!(self.n === 0)) { + if (!(dst.length === 0)) { + const _8: [rs.ByteSlice, rs.ByteSlice] = rs.dequeByteSlices(self); + const _9: rs.ByteSlice = _8[0]; + rs.idx(dst, 0); + dst.data[dst.start] = _9; + if (!(_8[1].length === 0)) { + if (!(dst.length === 1)) { + const _18: rs.ByteSlice = _8[1]; + rs.idx(dst, 1); + dst.data[dst.start + 1] = _18; + return 2; + } + } + return 1; + } + } + return 0; +} + /** * Advance the internal cursor of the Buf * diff --git a/ts/fixtures/stock/expected/harness.ts b/ts/fixtures/stock/expected/harness.ts index c1cc631be..91bd9164d 100644 --- a/ts/fixtures/stock/expected/harness.ts +++ b/ts/fixtures/stock/expected/harness.ts @@ -1,7 +1,7 @@ // Generated by rust2-ts. Do not edit. import * as rs from "./rs.ts"; -import { bytesMut, far, reclaims, reads, deques, dyns, late, vecSpares, chunks, writes, edits, owners, chains, strings } from "./buf.ts"; +import { bytesMut, far, reclaims, reads, deques, dyns, late, vecSpares, chunks, writes, edits, owners, chains, vectored, strings } from "./buf.ts"; import * as Owner from "./harness.Owner.ts"; import { map as maps_map, table, capacity, linked, linkedIters, nested, ownHasher, ownFromIter, equal, defaultHasher } from "./maps.ts"; import { ranges } from "./ranges.ts"; @@ -43,7 +43,7 @@ export function cases(): rs.Vec<[string, (a0: rs.ByteSlice, a1: rs.ByteVec) => u owners(a015.data, a015.start, a015.length, a115); }] as [string, (a0: rs.ByteSlice, a1: rs.ByteVec) => undefined], ["buf::strings", strings as (a0: rs.ByteSlice, a1: rs.ByteVec) => undefined] as [string, (a0: rs.ByteSlice, a1: rs.ByteVec) => undefined], ["ranges", ranges as (a0: rs.ByteSlice, a1: rs.ByteVec) => undefined] as [string, (a0: rs.ByteSlice, a1: rs.ByteVec) => undefined], ["buf::deques", (a016: rs.ByteSlice, a116: rs.ByteVec): undefined => { deques(a016.data, a016.start, a016.length, a116); - }] as [string, (a0: rs.ByteSlice, a1: rs.ByteVec) => undefined]]); + }] as [string, (a0: rs.ByteSlice, a1: rs.ByteVec) => undefined], ["buf::vectored", vectored as (a0: rs.ByteSlice, a1: rs.ByteVec) => undefined] as [string, (a0: rs.ByteSlice, a1: rs.ByteVec) => undefined]]); } /** Run one case. */ diff --git a/ts/fixtures/stock/expected/lib.ts b/ts/fixtures/stock/expected/lib.ts index 24485f1c2..9f919b8a4 100644 --- a/ts/fixtures/stock/expected/lib.ts +++ b/ts/fixtures/stock/expected/lib.ts @@ -4,7 +4,7 @@ import * as rs from "./rs.ts"; import * as buf_Counted from "./buf.Counted.ts"; import * as Pieces from "./buf.Pieces.ts"; import * as Provided from "./buf.Provided.ts"; -import { tryGetU8$bytes_Buf_bytes_Bytes, tryGetU8$bytes_Buf_bytes_BytesMut, tryGetU8$bytes_Buf_ref_slice_u8 } from "./bytes/buf/buf_impl.ts"; +import { chunksVectored$bytes_Buf_bytes_Bytes as buf_impl_chunksVectored$bytes_Buf_bytes_Bytes, chunksVectored$bytes_Buf_bytes_BytesMut as buf_impl_chunksVectored$bytes_Buf_bytes_BytesMut, chunksVectored$bytes_Buf_ref_slice_u8 as buf_impl_chunksVectored$bytes_Buf_ref_slice_u8, tryGetU8$bytes_Buf_bytes_Bytes, tryGetU8$bytes_Buf_bytes_BytesMut, tryGetU8$bytes_Buf_ref_slice_u8 } from "./bytes/buf/buf_impl.ts"; import type * as Buf from "./bytes/buf/buf_impl.Buf.ts"; import * as Chain from "./bytes/buf/chain.Chain.ts"; import * as Take from "./bytes/buf/take.Take.ts"; @@ -94,6 +94,10 @@ export function drop$bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_Bytes(_1: Cha rs.bytesDrop(_1.b); } +export function drop$bytes_buf_Chain_buf_Pieces_bytes_Bytes(_1: Chain.Chain): void { + rs.bytesDrop(_1.b); +} + export function drop$bytes_buf_Chain_buf_Provided_bytes_Bytes(_1: Chain.Chain): void { rs.bytesDrop(_1.b); } @@ -110,6 +114,10 @@ export function drop$bytes_buf_Chain_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_byt drop$bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_Bytes(_1.a); } +export function drop$bytes_buf_Chain_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(_1: Chain.Chain, rs.ByteSlice>): void { + drop$bytes_buf_Chain_buf_Pieces_bytes_Bytes(_1.a); +} + export function drop$bytes_buf_Chain_bytes_buf_Chain_ref_slice_u8_bytes_Bytes_buf_Pieces(_1: Chain.Chain, Pieces.Pieces>): void { drop$bytes_buf_Chain_ref_slice_u8_bytes_Bytes(_1.a); } @@ -255,6 +263,10 @@ export class of$buf_Counted { return buf_Counted.chunk$bytes_Buf(this.v); } + chunksVectored$Buf(a: rs.Slice): rs.usize { + return buf_Counted.chunksVectored$bytes_Buf(this.v, a); + } + copyToBytes$Buf(a: rs.usize): rs.ByteSlice { return rs.bufCopyToBytes(this.v, a, buf_Counted.remaining$bytes_Buf, buf_Counted.chunk$bytes_Buf, buf_Counted.advance$bytes_Buf as (a0: buf_Counted.Counted, a1: rs.usize) => undefined); } @@ -365,6 +377,10 @@ export class of$buf_Pieces { return Pieces.chunk$bytes_Buf(this.v); } + chunksVectored$Buf(a: rs.Slice): rs.usize { + return Pieces.chunksVectored$bytes_Buf(this.v, a); + } + copyToBytes$Buf(a: rs.usize): rs.ByteSlice { return Pieces.copyToBytes$bytes_Buf(this.v, a); } @@ -741,6 +757,10 @@ export class of$buf_Provided { return Provided.chunk$bytes_Buf(this.v); } + chunksVectored$Buf(a: rs.Slice): rs.usize { + return Provided.chunksVectored$bytes_Buf(this.v, a); + } + copyToBytes$Buf(a: rs.usize): rs.ByteSlice { return rs.bufCopyToBytes(this.v, a, Provided.remaining$bytes_Buf, Provided.chunk$bytes_Buf, Provided.advance$bytes_Buf as (a0: Provided.Provided, a1: rs.usize) => undefined); } @@ -855,6 +875,10 @@ export class of$bytes_Bytes { return this.v; } + chunksVectored$Buf(a: rs.Slice): rs.usize { + return buf_impl_chunksVectored$bytes_Buf_bytes_Bytes(this.v, a); + } + copyToBytes$Buf(a: rs.usize): rs.ByteSlice { return rs.bytesSplitTo(this, a); } @@ -993,6 +1017,10 @@ export class of$bytes_BytesMut { return rs.bytesMutView(this.v); } + chunksVectored$Buf(a: rs.Slice): rs.usize { + return buf_impl_chunksVectored$bytes_Buf_bytes_BytesMut(this.v, a); + } + copyToBytes$Buf(a: rs.usize): rs.ByteSlice { return rs.bytesMutFreeze(rs.bytesMutSplitTo(this.v, a)); } @@ -1127,6 +1155,10 @@ export class of$bytes_buf_Chain_buf_Provided_mut_ref_slice_u8 { return Chain.chunk$bytes_Buf_buf_Provided_mut_ref_slice_u8(this.v); } + chunksVectored$Buf(a: rs.Slice): rs.usize { + return Chain.chunksVectored$bytes_Buf_buf_Provided_mut_ref_slice_u8(this.v, a); + } + copyToBytes$Buf(a: rs.usize): rs.ByteSlice { return Chain.copyToBytes$bytes_Buf_buf_Provided_mut_ref_slice_u8(this.v, a); } @@ -1241,6 +1273,10 @@ export class of$bytes_buf_Chain_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_By return Chain.chunk$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_Bytes_ref_slice_u8(this.v); } + chunksVectored$Buf(a: rs.Slice): rs.usize { + return Chain.chunksVectored$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_Bytes_ref_slice_u8(this.v, a); + } + copyToBytes$Buf(a: rs.usize): rs.ByteSlice { return Chain.copyToBytes$bytes_Buf_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_Bytes_ref_slice_u8(this.v, a); } @@ -1336,6 +1372,124 @@ export class of$bytes_buf_Chain_bytes_buf_Chain_boxed_Box_dyn_bytes_Buf_bytes_By } } +export class of$bytes_buf_Chain_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 { + v: Chain.Chain, rs.ByteSlice>; + + constructor(v: Chain.Chain, rs.ByteSlice>) { + this.v = v; + } + + [Symbol.dispose](): void { + drop$bytes_buf_Chain_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(this.v); + } + + advance$Buf(a: rs.usize): void { + return Chain.advance$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(this.v, a); + } + + chunk$Buf(): rs.ByteSlice { + return Chain.chunk$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(this.v); + } + + chunksVectored$Buf(a: rs.Slice): rs.usize { + return Chain.chunksVectored$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(this.v, a); + } + + copyToBytes$Buf(a: rs.usize): rs.ByteSlice { + return Chain.copyToBytes$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(this.v, a); + } + + copyToSlice$Buf(a: rs.ByteSlice): void { + return Chain.copyToSlice$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(this.v, a); + } + + getF32Le$Buf(): rs.f32 { + return Chain.getF32Le$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(this.v); + } + + getF64$Buf(): rs.f64 { + return Chain.getF64$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(this.v); + } + + getI128$Buf(): rs.i128 { + return rs.bufGet(this.v, 16, false, rs.i128FromBeBytes, Chain.remaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, Chain.chunk$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, Chain.advance$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain.Chain, rs.ByteSlice>, a1: rs.usize) => undefined, Chain.copyToSlice$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain.Chain, rs.ByteSlice>, a1: rs.ByteSlice) => undefined); + } + + getI16Le$Buf(): rs.i16 { + return rs.bufGet(this.v, 2, true, rs.i16FromBeBytes, Chain.remaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, Chain.chunk$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, Chain.advance$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain.Chain, rs.ByteSlice>, a1: rs.usize) => undefined, Chain.copyToSlice$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain.Chain, rs.ByteSlice>, a1: rs.ByteSlice) => undefined); + } + + getI16Ne$Buf(): rs.i16 { + return rs.bufGet(this.v, 2, true, rs.i16FromBeBytes, Chain.remaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, Chain.chunk$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, Chain.advance$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain.Chain, rs.ByteSlice>, a1: rs.usize) => undefined, Chain.copyToSlice$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain.Chain, rs.ByteSlice>, a1: rs.ByteSlice) => undefined); + } + + getI32$Buf(): rs.i32 { + return rs.bufGet(this.v, 4, false, rs.i32FromBeBytes, Chain.remaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, Chain.chunk$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, Chain.advance$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain.Chain, rs.ByteSlice>, a1: rs.usize) => undefined, Chain.copyToSlice$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain.Chain, rs.ByteSlice>, a1: rs.ByteSlice) => undefined); + } + + getI64Le$Buf(): rs.i64 { + return rs.bufGet(this.v, 8, true, rs.i64FromBeBytes, Chain.remaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, Chain.chunk$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, Chain.advance$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain.Chain, rs.ByteSlice>, a1: rs.usize) => undefined, Chain.copyToSlice$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain.Chain, rs.ByteSlice>, a1: rs.ByteSlice) => undefined); + } + + getI8$Buf(): rs.i8 { + return Chain.getI8$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(this.v); + } + + getIntLe$Buf(a: rs.usize): rs.i64 { + return Chain.getIntLe$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(this.v, a); + } + + getU128Le$Buf(): rs.u128 { + return rs.bufGet(this.v, 16, true, rs.u128FromBeBytes, Chain.remaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, Chain.chunk$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, Chain.advance$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain.Chain, rs.ByteSlice>, a1: rs.usize) => undefined, Chain.copyToSlice$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain.Chain, rs.ByteSlice>, a1: rs.ByteSlice) => undefined); + } + + getU16$Buf(): rs.u16 { + return rs.bufGet(this.v, 2, false, rs.u16FromBeBytes, Chain.remaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, Chain.chunk$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, Chain.advance$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain.Chain, rs.ByteSlice>, a1: rs.usize) => undefined, Chain.copyToSlice$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain.Chain, rs.ByteSlice>, a1: rs.ByteSlice) => undefined); + } + + getU32Le$Buf(): rs.u32 { + return rs.bufGet(this.v, 4, true, rs.u32FromBeBytes, Chain.remaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, Chain.chunk$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, Chain.advance$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain.Chain, rs.ByteSlice>, a1: rs.usize) => undefined, Chain.copyToSlice$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain.Chain, rs.ByteSlice>, a1: rs.ByteSlice) => undefined); + } + + getU64$Buf(): rs.u64 { + return rs.bufGet(this.v, 8, false, rs.u64FromBeBytes, Chain.remaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, Chain.chunk$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, Chain.advance$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain.Chain, rs.ByteSlice>, a1: rs.usize) => undefined, Chain.copyToSlice$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain.Chain, rs.ByteSlice>, a1: rs.ByteSlice) => undefined); + } + + getU8$Buf(): rs.u8 { + return Chain.getU8$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(this.v); + } + + getUint$Buf(a: rs.usize): rs.u64 { + return Chain.getUint$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(this.v, a); + } + + hasRemaining$Buf(): boolean { + return Chain.hasRemaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(this.v); + } + + remaining$Buf(): rs.usize { + return Chain.remaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(this.v); + } + + tryGetI64Le$Buf(): rs.Result { + return rs.bufTryGet(this.v, 8, true, rs.i64FromBeBytes, Chain.remaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, Chain.chunk$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, Chain.advance$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain.Chain, rs.ByteSlice>, a1: rs.usize) => undefined, Chain.copyToSlice$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain.Chain, rs.ByteSlice>, a1: rs.ByteSlice) => undefined); + } + + tryGetU128$Buf(): rs.Result { + return rs.bufTryGet(this.v, 16, false, rs.u128FromBeBytes, Chain.remaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, Chain.chunk$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, Chain.advance$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain.Chain, rs.ByteSlice>, a1: rs.usize) => undefined, Chain.copyToSlice$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain.Chain, rs.ByteSlice>, a1: rs.ByteSlice) => undefined); + } + + tryGetU16$Buf(): rs.Result { + return rs.bufTryGet(this.v, 2, false, rs.u16FromBeBytes, Chain.remaining$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, Chain.chunk$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8, Chain.advance$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain.Chain, rs.ByteSlice>, a1: rs.usize) => undefined, Chain.copyToSlice$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8 as (a0: Chain.Chain, rs.ByteSlice>, a1: rs.ByteSlice) => undefined); + } + + tryGetU8$Buf(): rs.Result { + const part = Chain.tryGetU8$bytes_Buf_bytes_buf_Chain_buf_Pieces_bytes_Bytes_ref_slice_u8(this.v); + const result: rs.Result = part === undefined ? rs.Err(out$u8.err as TryGetError.TryGetError) : rs.Ok(part); + return result; + } +} + export class of$bytes_buf_Take_bytes_Bytes { v: Take.Take; @@ -1355,6 +1509,10 @@ export class of$bytes_buf_Take_bytes_Bytes { return Take.chunk$bytes_Buf_bytes_Bytes(this.v); } + chunksVectored$Buf(a: rs.Slice): rs.usize { + return Take.chunksVectored$bytes_Buf_bytes_Bytes(this.v, a); + } + copyToBytes$Buf(a: rs.usize): rs.ByteSlice { return Take.copyToBytes$bytes_Buf_bytes_Bytes(this.v, a); } @@ -1465,6 +1623,10 @@ export class of$bytes_buf_Take_ref_slice_u8 { return Take.chunk$bytes_Buf_ref_slice_u8(this.v); } + chunksVectored$Buf(a: rs.Slice): rs.usize { + return Take.chunksVectored$bytes_Buf_ref_slice_u8(this.v, a); + } + copyToBytes$Buf(a: rs.usize): rs.ByteSlice { return Take.copyToBytes$bytes_Buf_ref_slice_u8(this.v, a); } @@ -1575,6 +1737,10 @@ export class of$ref_slice_u8 { return this.v; } + chunksVectored$Buf(a: rs.Slice): rs.usize { + return buf_impl_chunksVectored$bytes_Buf_ref_slice_u8(this.v, a); + } + copyToBytes$Buf(a: rs.usize): rs.ByteSlice { return rs.byteSliceCopyToBytes(this, a); } @@ -1713,6 +1879,10 @@ export class ofPlace$bytes_Bytes { return this.v.v; } + chunksVectored$Buf(a: rs.Slice): rs.usize { + return buf_impl_chunksVectored$bytes_Buf_bytes_Bytes(this.v.v, a); + } + copyToBytes$Buf(a: rs.usize): rs.ByteSlice { return rs.bytesSplitTo(this.v, a); } @@ -1847,6 +2017,10 @@ export class ofPlace$ref_slice_u8 { return this.v.v; } + chunksVectored$Buf(a: rs.Slice): rs.usize { + return buf_impl_chunksVectored$bytes_Buf_ref_slice_u8(this.v.v, a); + } + copyToBytes$Buf(a: rs.usize): rs.ByteSlice { return rs.byteSliceCopyToBytes(this.v, a); } diff --git a/ts/fixtures/stock/src/buf.rs b/ts/fixtures/stock/src/buf.rs index b9eccff5c..5a9ad6d01 100644 --- a/ts/fixtures/stock/src/buf.rs +++ b/ts/fixtures/stock/src/buf.rs @@ -3,6 +3,7 @@ use std::cell::Cell; use std::collections::VecDeque; +use std::io::IoSlice; use std::rc::Rc; use std::sync::{Arc, Mutex}; @@ -1144,6 +1145,65 @@ fn chained(at: [usize; 2], buf: &mut B, pick: &u8, ops: &[u8], read_all(buf, ops, out) } +/// `chunks_vectored` of each buffer into as many slots as its input picks: a `Bytes`, a +/// `BytesMut`, a `&[u8]`, buffers in pieces, a `VecDeque` that wraps, a `Take` and a +/// `Chain` of them, and through a `&mut` and a `dyn Buf`. Then the slots it filled, read, +/// printed, and advanced, one and all together, which panics past what they hold. +pub fn vectored(data: &[u8], out: &mut Vec) { + let [kind, cut, slots, skip, input @ ..] = data else { + return; + }; + let cut = *cut as usize % (input.len() + 1); + let bytes = Bytes::copy_from_slice(input); + let owned = BytesMut::from(input); + let pieces = Pieces::new(input, cut); + let provided = Provided(Pieces::new(input, cut)); + let mut deque: VecDeque = input.iter().copied().collect(); + deque.rotate_left(cut); + let take = Pieces::new(input, cut).take(usize::from(*skip) % (input.len() + 2)); + let (a, b) = input.split_at(cut); + let chain = Pieces::new(a, a.len() / 2) + .chain(Bytes::copy_from_slice(b)) + .chain(&b[..]); + let mut slice = input; + let lent = &mut slice; + let boxed: Box = Box::new(Pieces::new(input, cut)); + let mut dst = [IoSlice::new(&[]); 5]; + let dst = &mut dst[..usize::from(*slots) % 6]; + let n = match kind % 11 { + 0 => bytes.chunks_vectored(dst), + 1 => owned.chunks_vectored(dst), + 2 => input.chunks_vectored(dst), + 3 => pieces.chunks_vectored(dst), + 4 => provided.chunks_vectored(dst), + 5 => (&chain as &dyn Buf).chunks_vectored(dst), + 6 => take.chunks_vectored(dst), + 7 => chain.chunks_vectored(dst), + 8 => lent.chunks_vectored(dst), + 9 => deque.chunks_vectored(dst), + _ => boxed.chunks_vectored(dst), + }; + out.push(n as u8); + for chunk in &dst[..n] { + out.push(chunk.len() as u8); + out.extend_from_slice(chunk); + } + out.extend_from_slice(format!("{:?}", &dst[..n]).as_bytes()); + let total: usize = dst[..n].iter().map(|chunk| chunk.len()).sum(); + let skip = usize::from(*skip) % (total + 2); + if let Some(first) = dst.first_mut() { + let mut one = *first; + one.advance(skip.min(one.len() + usize::from(kind / 11 % 2))); + out.extend_from_slice(&one); + } + let mut left = &mut dst[..n]; + IoSlice::advance_slices(&mut left, skip); + out.push(left.len() as u8); + for chunk in left.iter() { + out.extend_from_slice(chunk); + } +} + /// The bytes of a case's input, taken from the front. /// A `Bytes` of a `String`, which takes its storage, of the room its first bytes pick past /// its text: whether it is the one handle of it, and the room a `BytesMut` or a `Vec` taken diff --git a/ts/fixtures/stock/src/harness.rs b/ts/fixtures/stock/src/harness.rs index 9457e4e9c..8bf100e8f 100644 --- a/ts/fixtures/stock/src/harness.rs +++ b/ts/fixtures/stock/src/harness.rs @@ -40,6 +40,7 @@ fn cases() -> Vec<(&'static str, Case)> { ("buf::strings", crate::buf::strings), ("ranges", crate::ranges::ranges), ("buf::deques", crate::buf::deques), + ("buf::vectored", crate::buf::vectored), ] } diff --git a/ts/runtime/rs.ts b/ts/runtime/rs.ts index f43eeecb1..714031c4e 100644 --- a/ts/runtime/rs.ts +++ b/ts/runtime/rs.ts @@ -509,6 +509,32 @@ export class RawSlice { return ptrSlice(this.ptr, this.length); } + /** + * `p as *const [T; N]`: the pointer to the `n` elements from its first, which nothing + * checks until a read through it, as in Rust. Null and dangling point at nothing. + */ + array(n: number): Slice { + if (ptrNowhere(this.ptr)) return this.ptr as never; + const at = elemOf(this.ptr); + return new Slice(at.array as T[], at.index, n); + } + + /** + * `p as *const [u8; N]`, as `array` casts it, of bytes in an array of bytes. Not over + * `RawSlice`, as a null one's element type is unknown. + */ + byteArray(n: number): ByteSlice { + if (ptrNowhere(this.ptr)) return this.ptr as never; + const at = elemOf(this.ptr); + if (!(at.array instanceof Uint8Array)) { + // None of a byte in no array keeps where it points, as `ptrByteSlice`'s does. + if (n === 0) return ptrByteSlice(this.ptr as Place, 0, false); + // A byte in no array, which no `Uint8Array` can share. + throw new Error("rust2-ts: a raw or mutable slice of a byte in no array of bytes"); + } + return new ByteSlice(at.array, at.index, n); + } + /** The bytes it points at, read through it, `shared` as `ptrByteSlice` takes it. */ derefBytes(this: RawSlice, shared: boolean): ByteSlice { if (this.#made !== undefined) return this.#made; @@ -1891,6 +1917,26 @@ export function byteSliceRange(s: ByteSlice, start: number, end: number = s.leng return new ByteSlice(s.data, s.start + start, end - start); } +/** `IoSlice::advance` of the one at `p`: its bytes past the first `n`, which panics past its end. */ +export function ioSliceAdvance(p: Place, n: number, at?: Location): void { + p.v = byteSliceRange(p.v, n, undefined, at); +} + +/** + * `IoSlice::advance_slices` of the slice of them at `bufs`: past the first `n` bytes they + * lend, dropping those it passes whole, which panics past their end. + */ +export function ioSliceAdvanceSlices(bufs: Place>, n: number, at?: Location): void { + const s = bufs.v; + let [remove, left] = [0, n]; + while (remove < s.length && left >= s.data[s.start + remove].length) left -= s.data[s.start + remove++].length; + const rest = new Slice(s.data, s.start + remove, s.length - remove); + bufs.v = rest; + if (rest.length === 0) { + if (left !== 0) panic("advancing io slices beyond their length", at); + } else rest.data[rest.start] = byteSliceRange(rest.data[rest.start], left); +} + /** `get` of `start..end`: the part, or `undefined` unless it is within the slice. */ export function byteSliceGetRange(s: ByteSlice, start: number, end: number = s.length): ByteSlice | undefined { return start <= end && end <= s.length ? new ByteSlice(s.data, s.start + start, end - start) : undefined; diff --git a/ts/runtime/rs/iter.ts b/ts/runtime/rs/iter.ts index 3cb3e55b0..a687c45f3 100644 --- a/ts/runtime/rs/iter.ts +++ b/ts/runtime/rs/iter.ts @@ -5169,7 +5169,7 @@ function forward(n: T, by: number, int: Step | undefined): T { if (int === undefined) throw new Error("rust2-ts: stepping a range of no integer type"); const [sum, over] = int(n, by); if (!over) return sum; - if (int === (charStep as unknown)) panic("overflow in `Step::forward`", "char_forward"); + if (int === (charStep as unknown)) panic("overflow in `Step::forward`", "char_forward", true); return panic("attempt to add with overflow", "int_forward"); } diff --git a/ts/src/lower/caller.rs b/ts/src/lower/caller.rs index b6f93d2a9..dad6dba08 100644 --- a/ts/src/lower/caller.rs +++ b/ts/src/lower/caller.rs @@ -430,6 +430,18 @@ const CALLEES: &[(&str, &str, &str, &str)] = &[ "pub fn from_secs_f32(secs: f32)", "panic!(", ), + ( + "io::io_slice::advance", + "core/src/io/io_slice/repr_generic.rs", + "pub(crate) fn advance(&mut self, n: usize)", + "[n..]", + ), + ( + "io::io_slice::advance_slices", + "core/src/io/io_slice.rs", + "pub fn advance_slices(bufs: &mut &mut [IoSlice<'a>], n: usize)", + "assert!(", + ), ( "mem::maybe_uninit::write_copy_of_slice", "core/src/mem/maybe_uninit.rs", diff --git a/ts/src/lower/dynamic.rs b/ts/src/lower/dynamic.rs index 6944579eb..ece649121 100644 --- a/ts/src/lower/dynamic.rs +++ b/ts/src/lower/dynamic.rs @@ -233,10 +233,6 @@ impl<'tcx> Translator<'_, 'tcx> { if is_error(tcx, tr) && tcx.item_name(def_id).as_str() != "source" { continue; } - // `Buf::chunks_vectored`, whose `IoSlice` has no JS value. - if is_buf(tcx, tr) && tcx.item_name(def_id).as_str() == "chunks_vectored" { - continue; - } let name = format!("{}${}", super::camel(tcx.item_name(def_id).as_str()), tcx.item_name(tr)); if methods.iter().any(|m: &Method<'_>| m.name == name) { self.err(span, format!("`{ty}`, whose traits have two methods named `{name}`")); @@ -692,14 +688,6 @@ pub fn is_error_object(tcx: TyCtxt<'_>, ty: Ty<'_>) -> bool { principal(ty).is_some_and(|p| is_error(tcx, p)) } -/// Whether `def_id` is `bytes`' `Buf`, whose provided methods translate from its MIR for -/// a buffer the mapping doesn't name. -fn is_buf(tcx: TyCtxt<'_>, def_id: DefId) -> bool { - super::stock::is_stock(tcx, def_id) - && tcx.crate_name(def_id.krate).as_str() == "bytes" - && tcx.item_name(def_id).as_str() == "Buf" -} - /// Whether `ty` is a `dyn Any`. /// `dyn Any`, whose object's class a value of any type has. pub fn any_object(tcx: TyCtxt<'_>) -> Option> { diff --git a/ts/src/lower/fmt.rs b/ts/src/lower/fmt.rs index e381a0a8c..5ecb3087e 100644 --- a/ts/src/lower/fmt.rs +++ b/ts/src/lower/fmt.rs @@ -480,6 +480,11 @@ pub fn std_impl<'tcx>( (Std::Box | Std::NonZero | Std::Wrapping | Std::Saturating, _) => { b.fmt_call(tr, args.type_at(0), value, f, span) } + // An `IoSlice` writes the bytes it lends. + (Std::IoSlice, Trait::Debug) => { + let bytes = Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, Ty::new_slice(tcx, tcx.types.u8)); + b.fmt_call(tr, bytes, value, f, span) + } // A `Cow` writes what it derefs to. (Std::Cow, _) if let Some(borrowed) = library::cow_borrowed(tcx, ty) => { b.fmt_call(tr, borrowed, library::cow_deref(value, borrowed), f, span) diff --git a/ts/src/lower/library.rs b/ts/src/lower/library.rs index ec302b1d9..80498275c 100644 --- a/ts/src/lower/library.rs +++ b/ts/src/lower/library.rs @@ -202,6 +202,8 @@ pub enum Std { TryReserveError, /// `bytes::Bytes`: an `rs.ByteSlice`, as `&[u8]` is. Bytes, + /// `io::IoSlice`: the `rs.ByteSlice` of the `&[u8]` it wraps. + IoSlice, /// `bytes::BytesMut`: `rs.BytesMut`, a window of storage it shares with what it splits off. BytesMut, /// `rand::rngs::ThreadRng`: `rs.ThreadRng`, which holds no state. @@ -346,6 +348,7 @@ impl Std { ["char", "TryFromCharError"] => Some(Self::TryFromCharError), ["char", "decode", "DecodeUtf16Error"] => Some(Self::DecodeUtf16Error), ["str", "lossy", "Utf8Chunk"] => Some(Self::Utf8Chunk), + ["io", "io_slice", "IoSlice"] => Some(Self::IoSlice), ["fmt", "Formatter"] => Some(Self::Formatter), ["fmt", "Arguments"] => Some(Self::Arguments), ["fmt", "Error"] => Some(Self::FmtError), @@ -2024,6 +2027,10 @@ fn mapping<'tcx>( } } + // An `IoSlice` is the bytes it lends, which `advance` moves its place past the front of. + ("IoSlice", "new") => args.pop()?, + ("IoSlice", "advance") => Expr::rs("ioSliceAdvance", args), + ("IoSlice", "advance_slices") => Expr::rs("ioSliceAdvanceSlices", args), // A `NonZero` is its integer. ("NonZero", "get") => args.pop()?, ("NonZero", "new") => Expr::rs("nonZero", args), @@ -2752,7 +2759,7 @@ fn mapping<'tcx>( Some(Std::Vec) => vec_view(v, vargs.type_at(0)), // A `String` is the place of its text, as a `&mut str` of it is. Some(Std::String) if name == "deref" => v.member("v"), - Some(Std::String | Std::Box | Std::ManuallyDrop | Std::AssertUnwindSafe) => v, + Some(Std::String | Std::Box | Std::ManuallyDrop | Std::AssertUnwindSafe | Std::IoSlice) => v, Some(Std::Cow) if let Some(borrowed) = cow_borrowed(tcx, ty) => cow_deref(v, borrowed), // The greatest element of a heap, which `DerefMut` marks to sift once lent. Some(Std::PeekMut) => { diff --git a/ts/src/lower/mir/origin.rs b/ts/src/lower/mir/origin.rs index 33fd92e18..e15fe3455 100644 --- a/ts/src/lower/mir/origin.rs +++ b/ts/src/lower/mir/origin.rs @@ -14,7 +14,7 @@ use rustc_span::Spanned; use super::Fx; use crate::lower::library::{self, Std}; -use crate::lower::pointer::Pointee; +use crate::lower::pointer::{self, Pointee}; use crate::ts::{Expr, Stmt}; /// The array JS keeps what a pointer points at in. @@ -73,6 +73,11 @@ impl<'tcx> Fx<'_, '_, '_, 'tcx> { let (owner, name) = library::key(self.tcx, def_id)?; let arg = |i: usize| args.get(i).map(|a| &a.node); let pointee = gargs.types().next()?; + if matches!((owner.as_str(), name.as_str()), ("ptr" | "NonNull", "cast")) + && let Some(why) = self.lone_byte_array(arg(0)?, pointee, gargs.types().nth(1)?) + { + return Some(why); + } if self.b.t.zero_sized(pointee) || self.b.t.pointee(pointee) != Pointee::Place { return None; } @@ -424,8 +429,56 @@ impl<'tcx> Fx<'_, '_, '_, 'tcx> { pub(super) fn erased_borrow(&self, op: &Operand<'tcx>, from: ty::Ty<'tcx>, to: ty::Ty<'tcx>) -> Option { let t = &self.b.t; let erases = t.identity_pointee(to) && !t.identity_pointee(from) && t.pointee(from) == Pointee::Place; - (erases && crate::lower::pointer::unerasable(self.b, from).is_none() && self.arc_pointer(op) == Some(false)) - .then(|| crate::lower::pointer::erased_place(t.uninit_inner(from))) + (erases && pointer::unerasable(self.b, from).is_none() && self.arc_pointer(op) == Some(false)) + .then(|| pointer::erased_place(t.uninit_inner(from))) + } + + /// Why the cast of the raw slice `op` of bytes, a pointer to `from`, to one to `to`, an + /// array of some of them, would fail at run time where Rust's is defined: the body shows + /// the slice starts at a byte in no array, which no `Uint8Array` can share. + pub(super) fn lone_byte_array(&self, op: &Operand<'tcx>, from: ty::Ty<'tcx>, to: ty::Ty<'tcx>) -> Option { + let t = &self.b.t; + let (ty::Slice(from), ty::Array(to, n)) = (t.uninit_inner(from).kind(), t.uninit_inner(to).kind()) else { + return None; + }; + if !crate::lower::byte(*from) || !crate::lower::byte(*to) || n.try_to_target_usize(self.tcx) == Some(0) { + return None; + } + matches!(self.raw_start(op)?.array, Array::Lone(_)) + .then(|| "a raw or mutable slice of a byte in no array of bytes".into()) + } + + /// Where the raw slice, `NonNull` of one, or slice `op` starts, if the body shows it. + fn raw_start(&self, op: &Operand<'tcx>) -> Option> { + let local = self.traced(op)?; + if self.def_at[local].is_some() { + return match self.def_rvalue(local)? { + Rvalue::Use(op, _) + | Rvalue::Cast( + mir::CastKind::PtrToPtr + | mir::CastKind::PointerCoercion(ty::adjustment::PointerCoercion::MutToConstPointer, _), + op, + _, + ) if self.same_pointee(op, local) => self.raw_start(op), + // `&raw const *s`, of the slice `s`. + Rvalue::RawPtr(_, place) if place.projection.as_slice() == [ProjectionElem::Deref] => { + self.raw_start(&Operand::Copy(mir::Place::from(place.local))) + } + _ => self.start(op), + }; + } + let (def_id, gargs, args) = self.def_call(local)?; + // A pointer or reference to where its first argument points, as a whole. + if pointer::from_reference(self.tcx, def_id, gargs) + || pointer::derives(self.tcx, def_id) == Some(pointer::Derives::Same) + { + return self.raw_start(&args.first()?.node); + } + let (owner, name) = library::key(self.tcx, def_id)?; + match (owner.as_str(), name.as_str()) { + ("ptr" | "NonNull", "slice_from_raw_parts" | "slice_from_raw_parts_mut") => self.origin(&args[0].node), + _ => self.start(op), + } } /// The local `op` reads whole, if the body assigns it once. diff --git a/ts/src/lower/mir/rvalue.rs b/ts/src/lower/mir/rvalue.rs index 12e423ac1..2fc4f3291 100644 --- a/ts/src/lower/mir/rvalue.rs +++ b/ts/src/lower/mir/rvalue.rs @@ -471,7 +471,7 @@ impl<'m, 'b, 'a, 'tcx> Fx<'m, 'b, 'a, 'tcx> { if let (Some(a), Some(b)) = (from.builtin_deref(true), to.builtin_deref(true)) && from.is_raw_ptr() => { - if let Some(why) = self.erased_borrow(op, a, b) { + if let Some(why) = self.erased_borrow(op, a, b).or_else(|| self.lone_byte_array(op, a, b)) { return self.err(span, why); } if let Some(cast) = self.alloc_cast(op, a, b, span, out) { diff --git a/ts/src/lower/mod.rs b/ts/src/lower/mod.rs index a12bf1804..32e54876f 100644 --- a/ts/src/lower/mod.rs +++ b/ts/src/lower/mod.rs @@ -1841,7 +1841,7 @@ impl<'a, 'tcx> Translator<'a, 'tcx> { library::Std::PanicHookInfo => Type::Rs("PanicHookInfo", vec![]), library::Std::LayoutError => Type::Rs("LayoutError", vec![]), library::Std::TryReserveError => Type::Rs("TryReserveError", vec![]), - library::Std::Bytes => Type::Rs("ByteSlice", vec![]), + library::Std::Bytes | library::Std::IoSlice => Type::Rs("ByteSlice", vec![]), library::Std::BytesMut => Type::Rs("BytesMut", vec![]), library::Std::ThreadRng => Type::Rs("ThreadRng", vec![]), library::Std::ControlFlow => { diff --git a/ts/src/lower/pointer.rs b/ts/src/lower/pointer.rs index 462971d53..dc6ef7636 100644 --- a/ts/src/lower/pointer.rs +++ b/ts/src/lower/pointer.rs @@ -443,7 +443,8 @@ pub fn keeps<'tcx>(tcx: ty::TyCtxt<'tcx>, def_id: rustc_hir::def_id::DefId, args /// into, an `Arc`'s that `make_mut` replaces, a `String`'s that a drain edits as it drops, /// a `Result`'s whose payload JS copies, which `iter_mut` lends as a place that writes the /// whole `Result`, an iterator's that `by_ref` returns, what `borrow_mut` lends, the crate's -/// own iterator's that its `next` reads through, and a well-known crate's, such as a +/// own iterator's that its `next` reads through, an `IoSlice`'s and a `&mut` to a slice of +/// them, which `advance` and `advance_slices` move, and a well-known crate's, such as a /// `Bytes` that `Buf::advance` moves past its front. fn takes_place<'tcx>( t: &Translator<'_, 'tcx>, @@ -452,7 +453,7 @@ fn takes_place<'tcx>( ) -> bool { matches!( super::library::key(t.tcx, def_id), - Some((owner, name)) if matches!(owner.as_str(), "MaybeUninit" | "ManuallyDrop") + Some((owner, name)) if matches!(owner.as_str(), "MaybeUninit" | "ManuallyDrop" | "IoSlice") || matches!(owner.as_str(), "Arc" | "Rc") && name == "make_mut" || (owner.as_str(), name.as_str()) == ("String", "drain") || (owner.as_str(), name.as_str()) == ("Iterator", "by_ref") @@ -1036,8 +1037,9 @@ fn unmodeled<'tcx>(b: &Body<'_, '_, 'tcx>, ty: Ty<'tcx>, what: &str) -> Option(b: &mut Body<'_, '_, 'tcx>, p: Expr, from: Ty<'tcx>, to: Ty<'tcx>, span: Span) -> Expr { let (inner, into) = (b.t.uninit_inner(from), b.t.uninit_inner(to)); // Bytes are bytes, initialized or not, so a slice of either is the same `rs.ByteSlice`. @@ -1067,6 +1069,23 @@ pub fn cast<'tcx>(b: &mut Body<'_, '_, 'tcx>, p: Expr, from: Ty<'tcx>, to: Ty<'t let restored = Expr::rs("ptrUnerase", vec![p, key(into), align(into)]); return Expr::As(Box::new(restored), b.t.pointer_ty(into, span)); } + // A pointer to a slice as one to an array of its elements, which reinterprets nothing: + // `N` elements from its first, read through only where Rust reads. + if let (ty::Slice(from_elem), ty::Array(elem, n)) = (inner.kind(), into.kind()) + && (from_elem == elem || super::byte(*from_elem) && super::byte(*elem)) + { + let Some(n) = n.try_to_target_usize(tcx) else { + return b.err( + span, + format!("a cast from a pointer to `{from}` to one to `{to}`, of no fixed length"), + ); + }; + let array = match byte_slice(inner) { + true => "byteArray", + false => "array", + }; + return p.member(array).call(vec![Expr::lit(n.to_string())]); + } let elem = match inner.kind() { ty::Array(elem, _) | ty::Slice(elem) if b.t.uninit_inner(*elem) == into => Some(*elem), _ => None,