Added section on exceptions to guide (#81)

This commit is contained in:
David 2021-09-28 02:55:54 +13:00 committed by GitHub
parent daef57ba91
commit aed061d7be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 65 additions and 25 deletions

View File

@ -21,3 +21,4 @@
- [Structs](./macros/structs.md)
- [`impl`s](./macros/impl.md)
- [Constants](./macros/constant.md)
- [Exceptions](./exceptions.md)

48
guide/src/exceptions.md Normal file
View File

@ -0,0 +1,48 @@
# Exceptions
Exceptions can be thrown from Rust to PHP. The inverse (catching a PHP exception
in Rust) is currently being worked on.
## Throwing exceptions
[`PhpException`] is the type that represents an exception. It contains the
message contained in the exception, the type of exception and a status code to
go along with the exception.
You can create a new exception with the `new()`, `default()`, or
`from_class::<T>()` methods. `Into<PhpException>` is implemented for `String`
and `&str`, which creates an exception of the type `Exception` with a code of 0.
It may be useful to implement `Into<PhpException>` for your error type.
Calling the `throw()` method on a `PhpException` attempts to throw the exception
in PHP. This function can fail if the type of exception is invalid (i.e. does
not implement `Exception` or `Throwable`). Upon success, nothing will be
returned.
`IntoZval` is also implemented for `Result<T, E>`, where `T: IntoZval` and
`E: Into<PhpException>`. If the result contains the error variant, the exception
is thrown. This allows you to return a result from a PHP function annotated with
the `#[php_function]` attribute.
### Examples
```rust
# extern crate ext_php_rs;
use ext_php_rs::prelude::*;
use std::convert::TryInto;
// Trivial example - PHP represents all integers as `u64` on 64-bit systems
// so the `u32` would be converted back to `u64`, but that's okay for an example.
#[php_function]
pub fn something_fallible(n: u64) -> PhpResult<u32> {
let n: u32 = n.try_into().map_err(|_| "Could not convert into u32")?;
Ok(n)
}
#[php_module]
pub fn module(module: ModuleBuilder) -> ModuleBuilder {
module
}
```
[`PhpException`]: https://docs.rs/ext-php-rs/0.5.0/ext_php_rs/php/exceptions/struct.PhpException.html

View File

@ -88,21 +88,8 @@ pub fn greet(name: String, age: Option<i32>, description: Option<String>) -> Str
}
```
## Throwing exceptions
## Returning `Result<T, E>`
Exceptions can be thrown from inside a function which returns a `Result<T, E>`,
where `E` implements `Into<PhpException>`. The `PhpException` class allows you
to customise the type of exception thrown, along with the exception code and
message.
By default, `String` and `&str` are both implemented with `Into<PhpException>`,
and in both cases a regular `Exception` is thrown.
```rust
# extern crate ext_php_rs;
# use ext_php_rs::prelude::*;
#[php_function]
pub fn example_exception() -> Result<i64, &'static str> {
Err("Bad!!!")
}
```
You can also return a `Result` from the function. The error variant will be
translated into an exception and thrown. See the section on
[exceptions](../exceptions.md) for more details.

View File

@ -1,19 +1,24 @@
# Closure
Rust closures can be passed to PHP through a wrapper class `PhpClosure`. The
Rust closure must be static (i.e. can only reference things with a `static`
Rust closure must be static (i.e. can only reference things with a `'static`
lifetime, so not `self` in methods), and can take up to 8 parameters, all of
which must implement `FromZval`. The return type must implement `IntoZval`.
Passing closures from Rust to PHP is feature-gated behind the `closure` feature.
Enable it in your `Cargo.toml`:
```toml
ext-php-rs = { version = "...", features = ["closure"] }
```
PHP callables (which includes closures) can be passed to Rust through the
`Callable` type. When calling a callable, you must provide it with a `Vec` of
arguemnts, all of which must implement `IntoZval` and `Clone`.
| `T` parameter | `&T` parameter | `T` Return type | `&T` Return type | PHP representation |
| ------------- | -------------- | -------------------------------------- | ---------------- | ------------------------------------------------------------------------------------------ |
| `Callable` | No | `Closure` and `Callable` for functions | No | Callables are implemented in PHP, closures are represented as an instance of `PhpClosure`. |
| `T` parameter | `&T` parameter | `T` Return type | `&T` Return type | PHP representation |
| ------------- | -------------- | ----------------------------------- | ---------------- | ------------------------------------------------------------------------------------------ |
| `Callable` | No | `Closure`, `Callable` for functions | No | Callables are implemented in PHP, closures are represented as an instance of `PhpClosure`. |
Internally, when you enable the `closure` feature, a class `PhpClosure` is
registered alongside your other classes:

View File

@ -4,7 +4,7 @@
| `T` parameter | `&T` parameter | `T` Return type | PHP representation |
| ------------- | -------------- | --------------- | ------------------ |
| Yes | No | Yes | `ZendHashTable` |
| Yes | No | Yes | `HashTable` |
Converting from a zval to a `HashMap` is valid when the key is a `String`, and
the value implements `FromZval`. The key and values are copied into Rust types

View File

@ -31,5 +31,4 @@ Return types can also include:
as an exception.
For a type to be returnable, it must implement `IntoZval`, while for it to be
valid as a parameter, it must implement `FromZval` (and `TryFrom<&Zval>` by
proxy).
valid as a parameter, it must implement `FromZval`.

View File

@ -6,7 +6,7 @@ vector. The internal representation of a PHP array is discussed below.
| `T` parameter | `&T` parameter | `T` Return type | PHP representation |
| ------------- | -------------- | --------------- | ------------------ |
| Yes | No | Yes | `ZendHashTable` |
| Yes | No | Yes | `HashTable` |
Internally, PHP arrays are hash tables where the key can be an unsigned long or
a string. Zvals are contained inside arrays therefore the data does not have to