diff --git a/CHANGELOG.md b/CHANGELOG.md index 66f4d4e..1e52492 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased - added example combining Python bindings with winnow parsing +- added Python example demonstrating structured parsing with winnow's `view` - added `ByteSource` support for `VecDeque` when `zerocopy` is enabled and kept the deque as owner - added `ByteSource` support for `Cow<'static, T>` where `T: AsRef<[u8]>` - added `ByteArea` for staged file writes with `Section::freeze()` to return `Bytes` diff --git a/Cargo.toml b/Cargo.toml index b150812..551d889 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,3 +45,11 @@ required-features = ["pyo3"] [[example]] name = "pybytes" required-features = ["pyo3"] + +[[example]] +name = "python_winnow" +required-features = ["pyo3", "winnow"] + +[[example]] +name = "python_winnow_view" +required-features = ["pyo3", "winnow", "zerocopy"] diff --git a/INVENTORY.md b/INVENTORY.md index 8770607..d786b60 100644 --- a/INVENTORY.md +++ b/INVENTORY.md @@ -4,7 +4,7 @@ - None at the moment. ## Desired Functionality -- Python example using winnow::view to parse structured data. +- Add Kani proofs for winnow view helpers. ## Discovered Issues - None at the moment. diff --git a/README.md b/README.md index 9e0b1c6..16492d7 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,7 @@ needs these libraries installed; otherwise disable the feature during testing. - [`examples/pybytes.rs`](examples/pybytes.rs) – demonstrates the `pyo3` feature using `PyBytes` - [`examples/from_python.rs`](examples/from_python.rs) – wrap a Python `bytes` object into `Bytes` - [`examples/python_winnow.rs`](examples/python_winnow.rs) – parse Python bytes with winnow +- [`examples/python_winnow_view.rs`](examples/python_winnow_view.rs) – parse structured data from Python bytes using winnow's `view` ## Comparison diff --git a/examples/python_winnow_view.rs b/examples/python_winnow_view.rs new file mode 100644 index 0000000..5f974f3 --- /dev/null +++ b/examples/python_winnow_view.rs @@ -0,0 +1,28 @@ +#![cfg(all(feature = "pyo3", feature = "winnow", feature = "zerocopy"))] + +use anybytes::{winnow as ab_winnow, Bytes, View}; +use pyo3::{prelude::*, types::PyBytes}; +use winnow::{error::ContextError, stream::AsBytes, Parser}; +use zerocopy::{Immutable, KnownLayout, TryFromBytes}; + +#[derive(TryFromBytes, Immutable, KnownLayout)] +#[repr(C)] +struct Header { + magic: u16, + value: u16, +} + +fn main() -> PyResult<()> { + Python::with_gil(|py| { + let obj = PyBytes::new(py, &[0x34, 0x12, 0x78, 0x56]); + let mut bytes = Bytes::from_source(obj); + + let mut parser = ab_winnow::view::; + let header: View
= parser.parse_next(&mut bytes).expect("parse header"); + + assert_eq!(header.magic, 0x1234); + assert_eq!(header.value, 0x5678); + assert_eq!(bytes.as_bytes(), b"".as_ref()); + Ok(()) + }) +}