Skip to content

Commit 83cb3de

Browse files
kakserpomXenira
authored andcommitted
feat(array): FromZval/IntoZval impls for BTreeMap
1 parent 2a0d615 commit 83cb3de

File tree

1 file changed

+79
-10
lines changed

1 file changed

+79
-10
lines changed

src/types/array.rs

Lines changed: 79 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,6 @@
11
//! Represents an array in PHP. As all arrays in PHP are associative arrays,
22
//! they are represented by hash tables.
33

4-
use std::{
5-
collections::HashMap,
6-
convert::{TryFrom, TryInto},
7-
ffi::CString,
8-
fmt::{Debug, Display},
9-
iter::FromIterator,
10-
ptr,
11-
str::FromStr,
12-
};
13-
144
use crate::{
155
boxed::{ZBox, ZBoxable},
166
convert::{FromZval, IntoZval},
@@ -27,6 +17,15 @@ use crate::{
2717
flags::DataType,
2818
types::Zval,
2919
};
20+
use std::{
21+
collections::{BTreeMap, HashMap},
22+
convert::{TryFrom, TryInto},
23+
ffi::CString,
24+
fmt::{Debug, Display},
25+
iter::FromIterator,
26+
ptr,
27+
str::FromStr,
28+
};
3029

3130
/// A PHP hashtable.
3231
///
@@ -1288,6 +1287,76 @@ where
12881287
}
12891288
}
12901289

1290+
///////////////////////////////////////////
1291+
// BTreeMap
1292+
///////////////////////////////////////////
1293+
1294+
impl<'a, V> TryFrom<&'a ZendHashTable> for BTreeMap<String, V>
1295+
where
1296+
V: FromZval<'a>,
1297+
{
1298+
type Error = Error;
1299+
1300+
fn try_from(value: &'a ZendHashTable) -> Result<Self> {
1301+
let mut hm = BTreeMap::new();
1302+
1303+
for (key, val) in value {
1304+
hm.insert(
1305+
key.to_string(),
1306+
V::from_zval(val).ok_or_else(|| Error::ZvalConversion(val.get_type()))?,
1307+
);
1308+
}
1309+
1310+
Ok(hm)
1311+
}
1312+
}
1313+
1314+
impl<K, V> TryFrom<BTreeMap<K, V>> for ZBox<ZendHashTable>
1315+
where
1316+
K: AsRef<str>,
1317+
V: IntoZval,
1318+
{
1319+
type Error = Error;
1320+
1321+
fn try_from(value: BTreeMap<K, V>) -> Result<Self> {
1322+
let mut ht = ZendHashTable::with_capacity(
1323+
value.len().try_into().map_err(|_| Error::IntegerOverflow)?,
1324+
);
1325+
1326+
for (k, v) in value {
1327+
ht.insert(k.as_ref(), v)?;
1328+
}
1329+
1330+
Ok(ht)
1331+
}
1332+
}
1333+
1334+
impl<K, V> IntoZval for BTreeMap<K, V>
1335+
where
1336+
K: AsRef<str>,
1337+
V: IntoZval,
1338+
{
1339+
const TYPE: DataType = DataType::Array;
1340+
const NULLABLE: bool = false;
1341+
1342+
fn set_zval(self, zv: &mut Zval, _: bool) -> Result<()> {
1343+
let arr = self.try_into()?;
1344+
zv.set_hashtable(arr);
1345+
Ok(())
1346+
}
1347+
}
1348+
1349+
impl<'a, T> FromZval<'a> for BTreeMap<String, T>
1350+
where
1351+
T: FromZval<'a>,
1352+
{
1353+
const TYPE: DataType = DataType::Array;
1354+
1355+
fn from_zval(zval: &'a Zval) -> Option<Self> {
1356+
zval.array().and_then(|arr| arr.try_into().ok())
1357+
}
1358+
}
1359+
12911360
///////////////////////////////////////////
12921361
// Vec
12931362
///////////////////////////////////////////

0 commit comments

Comments
 (0)