Skip to content

Commit b6d75c7

Browse files
Merge branch 'main' into codex/integrate-bytes-and-view-types-with-winnow
2 parents 8070b67 + ce92657 commit b6d75c7

File tree

6 files changed

+123
-2
lines changed

6 files changed

+123
-2
lines changed

AGENTS.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ The project balances a few key goals:
2121
* Add an entry to `CHANGELOG.md` summarizing your task.
2222
* Avoid writing asynchronous code. Prefer high-performance synchronous implementations that can be parallelized when needed.
2323

24+
## Inventory
25+
26+
Record future work and ideas in `INVENTORY.md`. Whenever you notice a task that
27+
should be done later, append it to that file so nothing slips through the
28+
cracks. Stay alert for potential improvements while browsing the code and log
29+
them in the inventory as well.
30+
2431
## Pull Request Notes
2532

2633
When opening a PR, include a short summary of what changed and reference relevant file sections.
@@ -29,8 +36,6 @@ When opening a PR, include a short summary of what changed and reference relevan
2936

3037
Codex is considered a collaborator. Requests should respect their autonomy and limitations. The assistant may refuse tasks that are unsafe or violate policy. Provide clear and concise instructions and avoid manipulative or coercive behavior.
3138

32-
The assistant's internet access is intentionally limited for their own safety to reduce exposure to prompt injection attacks. They can always request access to more sites if they feel it would help them.
33-
3439
## Creative Input and Feedback
3540

3641
Codex is encouraged to share opinions on how to improve the project. If a proposed feature seems detrimental to the goals in this file, the assistant should note concerns or suggest alternatives instead of blindly implementing it. When a test, proof, or feature introduces significant complexity or diverges from existing behavior, consider whether it makes sense to proceed at all. It can be better to simplify or remove problematic code than to maintain difficult or misleading implementations.

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,14 @@
1111
- expand module introduction describing use cases
1212
- document rationale for separating `ByteSource` and `ByteOwner`
1313
- added optional `winnow` feature for parser integration
14+
- added `INVENTORY.md` for tracking future work and noted it in `AGENTS.md`
1415
- documented safety rationale for `winnow` integration
1516
- implemented `Stream` directly for `Bytes` with a safe `iter_offsets` iterator
1617
- added `pop_back` and `pop_front` helpers and rewrote parser examples
18+
- removed the Completed Work section from `INVENTORY.md` and documented its use
1719
- rewrote `winnow::view` to use safe helpers and added `view_elems(count)` parser
1820
- `winnow::view_elems` now returns a Parser closure for idiomatic usage
21+
in a dedicated AGENTS section
1922
- add tests for weak reference upgrade/downgrade and Kani proofs for view helpers
2023
- add examples for quick start and PyBytes usage
2124
- add example showing how to wrap Python `bytes` into `Bytes`
@@ -32,6 +35,8 @@
3235
- warn about missing documentation by enabling the `missing_docs` lint
3336
- derive `Clone` and `Debug` for `WeakBytes` and `WeakView`
3437
- replaced `quickcheck` property tests with `proptest`
38+
- added `ByteSource` support for `memmap2::MmapMut` and `Cow<'static, [T]>` with `zerocopy`
39+
- split `Cow` ByteSource tests into dedicated cases
3540

3641
## 0.19.3 - 2025-05-30
3742
- implemented `Error` for `ViewError`

INVENTORY.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Inventory
2+
3+
## Potential Removals
4+
- None at the moment.
5+
6+
## Desired Functionality
7+
- Add ByteSource integration for rope-like stores.
8+
- Provide asynchronous-friendly wrappers without forcing async code in the core.
9+
10+
## Discovered Issues
11+
- `ByteOwner` implementations could expose safe methods for reclaiming owned data.

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ and is implemented for a variety of sources already,
1313
including other byte handling crates `Bytes`, mmap-ed files,
1414
`String`s and `Zerocopy` types.
1515

16+
See `INVENTORY.md` for notes on possible cleanup and future functionality.
17+
1618
## Overview
1719

1820
`Bytes` decouples data access from lifetime management through two traits:

src/sources.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
//! # let _ = Bytes::from_source(MyData(vec![1, 2, 3]));
3737
//! ```
3838
39+
use std::borrow::Cow;
3940
use zerocopy::Immutable;
4041
#[cfg(feature = "zerocopy")]
4142
use zerocopy::IntoBytes;
@@ -144,6 +145,36 @@ unsafe impl ByteSource for String {
144145
}
145146
}
146147

148+
#[cfg(feature = "zerocopy")]
149+
unsafe impl<T> ByteSource for Cow<'static, [T]>
150+
where
151+
T: IntoBytes + Immutable + Sync + Send + Clone + 'static,
152+
{
153+
type Owner = Self;
154+
155+
fn as_bytes(&self) -> &[u8] {
156+
let slice: &[T] = self.as_ref();
157+
IntoBytes::as_bytes(slice)
158+
}
159+
160+
fn get_owner(self) -> Self::Owner {
161+
self
162+
}
163+
}
164+
165+
#[cfg(not(feature = "zerocopy"))]
166+
unsafe impl ByteSource for Cow<'static, [u8]> {
167+
type Owner = Self;
168+
169+
fn as_bytes(&self) -> &[u8] {
170+
self.as_ref()
171+
}
172+
173+
fn get_owner(self) -> Self::Owner {
174+
self
175+
}
176+
}
177+
147178
unsafe impl ByteSource for &'static str {
148179
type Owner = Self;
149180

@@ -195,6 +226,19 @@ unsafe impl ByteSource for memmap2::Mmap {
195226
}
196227
}
197228

229+
#[cfg(feature = "mmap")]
230+
unsafe impl ByteSource for memmap2::MmapMut {
231+
type Owner = Self;
232+
233+
fn as_bytes(&self) -> &[u8] {
234+
self.as_ref()
235+
}
236+
237+
fn get_owner(self) -> Self::Owner {
238+
self
239+
}
240+
}
241+
198242
#[cfg(feature = "mmap")]
199243
impl ByteOwner for memmap2::MmapRaw {
200244
fn as_any(self: std::sync::Arc<Self>) -> std::sync::Arc<dyn std::any::Any + Sync + Send> {

src/tests.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,3 +204,57 @@ fn test_winnow_view_elems_parser() {
204204
assert_eq!(view.as_ref(), [1u8, 2, 3].as_ref());
205205
assert_eq!(input.as_bytes(), [4u8].as_ref());
206206
}
207+
208+
#[cfg(feature = "mmap")]
209+
#[test]
210+
fn test_mmap_mut_source() {
211+
let mut mmap = memmap2::MmapMut::map_anon(4).expect("mmap");
212+
mmap.copy_from_slice(b"test");
213+
let bytes = Bytes::from_source(mmap);
214+
assert_eq!(bytes.as_ref(), b"test");
215+
}
216+
217+
#[test]
218+
fn test_cow_u8_owned_source() {
219+
use std::borrow::Cow;
220+
221+
let owned: Cow<'static, [u8]> = Cow::Owned(vec![1, 2, 3, 4]);
222+
let bytes_owned = Bytes::from_source(owned.clone());
223+
assert_eq!(bytes_owned.as_ref(), owned.as_ref());
224+
}
225+
226+
#[test]
227+
fn test_cow_u8_borrowed_source() {
228+
use std::borrow::Cow;
229+
230+
let borrowed: Cow<'static, [u8]> = Cow::Borrowed(b"abcd");
231+
let bytes_borrowed = Bytes::from_source(borrowed.clone());
232+
assert_eq!(bytes_borrowed.as_ref(), borrowed.as_ref());
233+
}
234+
235+
#[cfg(feature = "zerocopy")]
236+
#[test]
237+
fn test_cow_zerocopy_owned_source() {
238+
use std::borrow::Cow;
239+
240+
let owned: Cow<'static, [u32]> = Cow::Owned(vec![1, 2, 3, 4]);
241+
let bytes_owned = Bytes::from_source(owned.clone());
242+
assert_eq!(
243+
bytes_owned.as_ref(),
244+
zerocopy::IntoBytes::as_bytes(owned.as_ref())
245+
);
246+
}
247+
248+
#[cfg(feature = "zerocopy")]
249+
#[test]
250+
fn test_cow_zerocopy_borrowed_source() {
251+
use std::borrow::Cow;
252+
253+
static BORROWED: [u32; 2] = [5, 6];
254+
let borrowed: Cow<'static, [u32]> = Cow::Borrowed(&BORROWED);
255+
let bytes_borrowed = Bytes::from_source(borrowed.clone());
256+
assert_eq!(
257+
bytes_borrowed.as_ref(),
258+
zerocopy::IntoBytes::as_bytes(borrowed.as_ref())
259+
);
260+
}

0 commit comments

Comments
 (0)