Skip to content

Commit 9dbd1b1

Browse files
committed
feat(array): BTreeMap conversion
1 parent 25f508f commit 9dbd1b1

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
use std::{collections::BTreeMap, convert::TryFrom};
2+
3+
use crate::{
4+
boxed::ZBox,
5+
convert::{FromZval, IntoZval},
6+
error::{Error, Result},
7+
flags::DataType,
8+
types::Zval,
9+
};
10+
11+
use super::super::ZendHashTable;
12+
13+
impl<'a, V> TryFrom<&'a ZendHashTable> for BTreeMap<String, V>
14+
where
15+
V: FromZval<'a>,
16+
{
17+
type Error = Error;
18+
19+
fn try_from(value: &'a ZendHashTable) -> Result<Self> {
20+
let mut hm = BTreeMap::new();
21+
22+
for (key, val) in value {
23+
hm.insert(
24+
key.to_string(),
25+
V::from_zval(val).ok_or_else(|| Error::ZvalConversion(val.get_type()))?,
26+
);
27+
}
28+
29+
Ok(hm)
30+
}
31+
}
32+
33+
impl<K, V> TryFrom<BTreeMap<K, V>> for ZBox<ZendHashTable>
34+
where
35+
K: AsRef<str>,
36+
V: IntoZval,
37+
{
38+
type Error = Error;
39+
40+
fn try_from(value: BTreeMap<K, V>) -> Result<Self> {
41+
let mut ht = ZendHashTable::with_capacity(
42+
value.len().try_into().map_err(|_| Error::IntegerOverflow)?,
43+
);
44+
45+
for (k, v) in value {
46+
ht.insert(k.as_ref(), v)?;
47+
}
48+
49+
Ok(ht)
50+
}
51+
}
52+
53+
impl<K, V> IntoZval for BTreeMap<K, V>
54+
where
55+
K: AsRef<str>,
56+
V: IntoZval,
57+
{
58+
const TYPE: DataType = DataType::Array;
59+
const NULLABLE: bool = false;
60+
61+
fn set_zval(self, zv: &mut Zval, _: bool) -> Result<()> {
62+
let arr = self.try_into()?;
63+
zv.set_hashtable(arr);
64+
Ok(())
65+
}
66+
}
67+
68+
impl<'a, T> FromZval<'a> for BTreeMap<String, T>
69+
where
70+
T: FromZval<'a>,
71+
{
72+
const TYPE: DataType = DataType::Array;
73+
74+
fn from_zval(zval: &'a Zval) -> Option<Self> {
75+
zval.array().and_then(|arr| arr.try_into().ok())
76+
}
77+
}

src/types/array/conversions/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@
99
//! - `HashMap<K, V>` ↔ `ZendHashTable` (via `hash_map` module)
1010
//! - `Vec<T>` and `Vec<(K, V)>` ↔ `ZendHashTable` (via `vec` module)
1111
12+
mod btree_map;
1213
mod hash_map;
1314
mod vec;

0 commit comments

Comments
 (0)