Skip to content

Commit d4b0858

Browse files
authored
Add internal types documentations. (#82)
1 parent 5f4fe4c commit d4b0858

File tree

7 files changed

+204
-7
lines changed

7 files changed

+204
-7
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Z Str
2+
3+
> A string is series of characters, where a character is the same as a byte.
4+
>
5+
> Refer: <https://www.php.net/manual/en/language.types.string.php>
6+
7+
The [`&ZStr`](phper::strings::ZStr) and [`ZString`](phper::strings::ZString) are
8+
the wrapper of [`zend_string`](phper::sys::zend_string).
9+
10+
`ZStr` can be converted to `&[u8]`, `&CStr` and `&str`.
11+
12+
`ZString` can be constructed from `impl AsRef<[u8]>`, has pair of `from_raw()`
13+
and `into_raw()`, like in [`Box`].
14+
15+
```rust,no_run
16+
use phper::strings::ZString;
17+
18+
let s = ZString::new("Hello world!");
19+
20+
// Will leak memory.
21+
let ptr = s.into_raw();
22+
23+
// retake pointer.
24+
let ss = unsafe { ZString::from_raw(ptr) };
25+
26+
// `ZString` implements `PartialEq`.
27+
assert_eq!(ss, "Hello world!");
28+
```
29+
30+
`ZString` can be dereferenced to `ZStr`.
31+
32+
```rust,no_run
33+
use phper::strings::ZString;
34+
35+
let s = ZString::new("Hello world!");
36+
37+
// `to_str` is the method of `ZStr`.
38+
assert_eq!(s.to_str(), Ok("Hello world!"));
39+
```
40+
41+
`ZStr` implements `ToOwned`, can upgrade to `ZString` by value copy.
42+
43+
Because `zend_string` is reference counting type, so `ZStr` also implements
44+
[`ToRefOwned`](phper::alloc::ToRefOwned) (just like
45+
[`RefClone`](phper::alloc::RefClone) for [`ZVal`](phper::values::ZVal)), can
46+
upgrade to `ZString` by refcount increment.
47+
48+
```rust,no_run
49+
use phper::sys;
50+
use phper::strings::ZStr;
51+
use phper::alloc::ToRefOwned;
52+
53+
extern "C" {
54+
fn something() -> *mut sys::zend_string;
55+
}
56+
57+
let s = unsafe { ZStr::from_mut_ptr(something()) };
58+
59+
// By value copy.
60+
let _s = s.to_owned();
61+
62+
// By refcount increment.
63+
let _s = s.to_ref_owned();
64+
```
65+
66+
Note that neither `ZStr` nor `ZString` implement `Send` and `Sync`, because PHP
67+
is single-threaded.
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Z Arr
2+
3+
> An array in PHP is actually an ordered map. A map is a type that associates
4+
> values to keys. This type is optimized for several different uses; it can be
5+
> treated as an array, list (vector), hash table (an implementation of a map),
6+
> dictionary, collection, stack, queue, and probably more. As array values can
7+
> be other arrays, trees and multidimensional arrays are also possible.
8+
>
9+
> Refer: <https://www.php.net/manual/en/language.types.array.php>
10+
11+
*In fact, I don't agree with PHP's practice of mixing list and map. I prefer*
12+
*python to separate list and dictionary as two types. For example, when*
13+
*serializing into json, the serialization function has to judge whether the key*
14+
*of the array starts from 0 and increment by 1 to confirm whether the array is*
15+
*a list. I think it is a waste of performance.*
16+
17+
The [`&ZArr`](phper::arrays::ZArr) and [`ZArray`](phper::arrays::ZArray) are
18+
the wrapper of [`zend_array`](phper::sys::zend_array) (same as `Hashtable`).
19+
20+
[`&ZArr`](phper::arrays::ZArr) acts like [`HashMap`](std::collections::HashMap),
21+
also has api `insert()`, `get()`, `remove()`, but it's key type is
22+
[`Key`](phper::arrays::Key) and value type is [`ZVal`](phper::values::ZVal).
23+
24+
Notice that phper prefer to use [`Symtables`](https://www.phpinternalsbook.com/php5/hashtables/array_api.html#symtables) api `zend_symtable_*`,
25+
so `get(42)` and `get("42")` should be considered the same.
26+
27+
`ZArray` can be dereferenced to `ZArr`.
28+
29+
```rust,no_run
30+
use phper::arrays::{ZArray, InsertKey};
31+
use phper::values::ZVal;
32+
33+
let mut arr = ZArray::new();
34+
35+
arr.insert(InsertKey::NextIndex, ZVal::default());
36+
arr.insert(10, ZVal::from(100));
37+
arr.insert("foo", ZVal::from("bar"));
38+
39+
let _i = arr.get("10");
40+
41+
arr.remove("foo");
42+
```
43+
44+
`ZArr` can be iterated by `iter()`.
45+
46+
```rust,no_run
47+
use phper::arrays::ZArray;
48+
use phper::values::ZVal;
49+
50+
let arr = ZArray::new();
51+
52+
for (_k, _v) in arr.iter() {
53+
}
54+
```
55+
56+
`ZArr` implements `ToOwned`, can upgrade to `ZArray` by value copy via
57+
`zend_array_dup`.
58+
59+
Because `zend_array` is reference counting type, so `ZArr` also implements
60+
[`ToRefOwned`](phper::alloc::ToRefOwned) (just like
61+
[`RefClone`](phper::alloc::RefClone) for [`ZVal`](phper::values::ZVal)), can
62+
upgrade to `ZArray` by refcount increment.
63+
64+
```rust,no_run
65+
use phper::sys;
66+
use phper::arrays::ZArr;
67+
use phper::alloc::ToRefOwned;
68+
69+
extern "C" {
70+
fn something() -> *mut sys::zend_array;
71+
}
72+
73+
let arr = unsafe { ZArr::from_mut_ptr(something()) };
74+
75+
// By value copy.
76+
let _arr = arr.to_owned();
77+
78+
// By refcount increment.
79+
let _arr = arr.to_ref_owned();
80+
```
81+
82+
Note that neither `ZArr` nor `ZArray` implement `Send` and `Sync`, because PHP
83+
is single-threaded.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Z Obj
2+
3+
TODO
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Internal types
2+
3+
## DST & Owned Type
4+
5+
In Rust, there are many types that appear in pairs, like [str](str) / [String](String),
6+
[OsStr](std::ffi::OsStr) / [OsString](std::ffi::OsString),
7+
[CStr](std::ffi::CStr) / [CString](std::ffi::CString).
8+
9+
For example:
10+
11+
- [str](str): Dynamically sized type, implements `!Sized`, usually used with reference
12+
notation, as `&str`.
13+
- [String](String): Ownership type, encapsulates a pointer to a heap memory allocation.
14+
15+
PHPER follows this design, there are the following types:
16+
17+
- [ZStr](phper::strings::ZStr) / [ZString](phper::strings::ZString)
18+
- [ZArr](phper::arrays::ZArr) / [ZArray](phper::arrays::ZArray)
19+
- [ZObj](phper::objects::ZObj) / [ZObject](phper::objects::ZObject)
20+
21+
## Mapping relationship
22+
23+
Here is the mapping relationship of Rust type and base PHP type.
24+
25+
| Rust type | PHP type |
26+
| ---------------- | -------- |
27+
| `()` | null |
28+
| `bool` | bool |
29+
| `i64` | long |
30+
| `f64` | double |
31+
| `ZStr / ZString` | string |
32+
| `ZArr / ZArray` | array |
33+
| `ZObj / ZObject` | object |
34+
| `ZRes` | resource |
35+
36+
*Why is there no ZResource? Because Resource is a relatively old type, it*
37+
*is generally replaced by Class now, and the role of ZRes is only compatible*
38+
*with old extension resources.*
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Class and object
2+
3+
TODO

phper-doc/doc/_07_module/index.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Module
2+
3+
TODO

phper-doc/src/lib.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,23 +32,23 @@ pub mod _03_integrate_with_pecl {}
3232
#[doc = include_str!("../doc/_04_zval/index.md")]
3333
pub mod _04_zval {}
3434

35-
/// TODO
35+
#[doc = include_str!("../doc/_05_internal_types/index.md")]
3636
pub mod _05_internal_types {
3737

38-
/// TODO
38+
#[doc = include_str!("../doc/_05_internal_types/_01_z_str/index.md")]
3939
pub mod _01_z_str {}
4040

41-
/// TODO
41+
#[doc = include_str!("../doc/_05_internal_types/_02_z_arr/index.md")]
4242
pub mod _02_z_arr {}
4343

44-
/// TODO
45-
pub mod _03_z_arr {}
44+
#[doc = include_str!("../doc/_05_internal_types/_03_z_obj/index.md")]
45+
pub mod _03_z_obj {}
4646
}
4747

48-
/// TODO
48+
#[doc = include_str!("../doc/_06_class_and_object/index.md")]
4949
pub mod _06_class_and_object {}
5050

51-
/// TODO
51+
#[doc = include_str!("../doc/_07_module/index.md")]
5252
pub mod _07_module {
5353

5454
/// TODO

0 commit comments

Comments
 (0)