Skip to content

Commit 2a0d615

Browse files
committed
feat(array): support Vec<(K,V)> for hashtables
Refs: #425
1 parent 1166e29 commit 2a0d615

File tree

6 files changed

+496
-8
lines changed

6 files changed

+496
-8
lines changed

guide/src/types/hashmap.md

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,17 @@ numeric key, the key is represented as a string before being inserted.
1414
Converting from a `HashMap` to a zval is valid when the key implements
1515
`AsRef<str>`, and the value implements `IntoZval`.
1616

17+
<div class="warning">
18+
19+
When using `HashMap` the order of the elements it not preserved.
20+
21+
HashMaps are unordered collections, so the order of elements may not be the same
22+
when converting from PHP to Rust and back.
23+
24+
If you need to preserve the order of elements, consider using `Vec<(K, V)>` or
25+
`Vec<ArrayKey, V)>` instead.
26+
</div>
27+
1728
## Rust example
1829

1930
```rust,no_run
@@ -49,9 +60,93 @@ var_dump(test_hashmap([
4960
Output:
5061

5162
```text
52-
k: hello v: world
5363
k: rust v: php
64+
k: hello v: world
5465
k: 0 v: okk
66+
array(3) {
67+
[0] => string(3) "php",
68+
[1] => string(5) "world",
69+
[2] => string(3) "okk"
70+
}
71+
```
72+
73+
## `Vec<(K, V)>` and `Vec<ArrayKey, V>`
74+
75+
`Vec<(K, V)>` and `Vec<ArrayKey, V>` are used to represent associative arrays in PHP
76+
where the keys can be strings or integers.
77+
78+
If using `String` or `&str` as the key type, only string keys will be accepted.
79+
80+
For `i64` keys, string keys that can be parsed as integers will be accepted, and
81+
converted to `i64`.
82+
83+
If you need to accept both string and integer keys, use `ArrayKey` as the key type.
84+
85+
### Rust example
86+
87+
```rust,no_run
88+
# #![cfg_attr(windows, feature(abi_vectorcall))]
89+
# extern crate ext_php_rs;
90+
# use ext_php_rs::prelude::*;
91+
# use ext_php_rs::types::ArrayKey;
92+
#[php_function]
93+
pub fn test_vec_kv(vec: Vec<(String, String)>) -> Vec<String> {
94+
for (k, v) in vec.iter() {
95+
println!("k: {} v: {}", k, v);
96+
}
97+
98+
vec.into_iter()
99+
.map(|(_, v)| v)
100+
.collect::<Vec<_>>()
101+
}
102+
103+
#[php_function]
104+
pub fn test_vec_arraykey(vec: Vec<(ArrayKey, String)>) -> Vec<String> {
105+
for (k, v) in vec.iter() {
106+
println!("k: {} v: {}", k, v);
107+
}
108+
109+
vec.into_iter()
110+
.map(|(_, v)| v)
111+
.collect::<Vec<_>>()
112+
}
113+
# fn main() {}
114+
```
115+
116+
## PHP example
117+
118+
```php
119+
<?php
120+
121+
declare(strict_types=1);
122+
123+
var_dump(test_vec_kv([
124+
['hello', 'world'],
125+
['rust', 'php'],
126+
['okk', 'okk'],
127+
]));
128+
129+
var_dump(test_vec_arraykey([
130+
['hello', 'world'],
131+
[1, 'php'],
132+
["2", 'okk'],
133+
]));
134+
```
135+
136+
Output:
137+
138+
```text
139+
k: hello v: world
140+
k: rust v: php
141+
k: okk v: okk
142+
array(3) {
143+
[0] => string(5) "world",
144+
[1] => string(3) "php",
145+
[2] => string(3) "okk"
146+
}
147+
k: hello v: world
148+
k: 1 v: php
149+
k: 2 v: okk
55150
array(3) {
56151
[0] => string(5) "world",
57152
[1] => string(3) "php",

0 commit comments

Comments
 (0)