From 3c3abd51ba41749bc289895e3c4155743363051e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Mar 2026 06:24:37 +0000 Subject: [PATCH 1/2] Initial plan From db5c02d54f003da350cf9cd76f90aa0f42f6f797 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Mar 2026 06:27:03 +0000 Subject: [PATCH 2/2] docs: add FromZVal and FromZValMut section in zval guide Co-authored-by: jmjoy <8677974+jmjoy@users.noreply.github.com> --- phper-doc/doc/_04_zval/index.md | 35 +++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/phper-doc/doc/_04_zval/index.md b/phper-doc/doc/_04_zval/index.md index 3967f976..7a63b7bb 100644 --- a/phper-doc/doc/_04_zval/index.md +++ b/phper-doc/doc/_04_zval/index.md @@ -73,6 +73,41 @@ fn say_hello(arguments: &mut [ZVal]) -> phper::Result<()> { } ``` +### Generic conversion via `FromZVal` / `FromZValMut` + +Besides calling `expect_*` directly, you can also use generic conversion traits: + +- [`phper::values::FromZVal`]: converts from `&ZVal`. +- [`phper::values::FromZValMut`]: converts from `&mut ZVal`. + +And call [`phper::values::ZVal::expect_type`] / +[`phper::values::ZVal::expect_mut_type`] to perform conversion. + +```rust,no_run +use phper::values::{FromZVal, FromZValMut, ZVal}; + +fn expect_immutable<'a, T: FromZVal<'a>>(val: &'a ZVal) -> phper::Result { + val.expect_type() +} + +fn expect_mutable<'a, T: FromZValMut<'a>>(val: &'a mut ZVal) -> phper::Result { + val.expect_mut_type() +} + +fn demo() -> phper::Result<()> { + let z = ZVal::from(123i64); + let immutable: i64 = expect_immutable(&z)?; + assert_eq!(immutable, 123); + + let mut z = ZVal::from(456i64); + let mutable: &mut i64 = expect_mutable(&mut z)?; + *mutable += 1; + assert_eq!(z.expect_long()?, 457); + + Ok(()) +} +``` + ## Value copy & reference counting copy The [`phper::values::ZVal`] both implements [`std::clone::Clone`] and