Skip to content

Commit 085a547

Browse files
committed
feat(array): FromZval/IntoZval impls for BTreeMap
1 parent 1166e29 commit 085a547

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
///
@@ -1165,6 +1164,76 @@ where
11651164
}
11661165
}
11671166

1167+
///////////////////////////////////////////
1168+
// BTreeMap
1169+
///////////////////////////////////////////
1170+
1171+
impl<'a, V> TryFrom<&'a ZendHashTable> for BTreeMap<String, V>
1172+
where
1173+
V: FromZval<'a>,
1174+
{
1175+
type Error = Error;
1176+
1177+
fn try_from(value: &'a ZendHashTable) -> Result<Self> {
1178+
let mut hm = BTreeMap::new();
1179+
1180+
for (key, val) in value {
1181+
hm.insert(
1182+
key.to_string(),
1183+
V::from_zval(val).ok_or_else(|| Error::ZvalConversion(val.get_type()))?,
1184+
);
1185+
}
1186+
1187+
Ok(hm)
1188+
}
1189+
}
1190+
1191+
impl<K, V> TryFrom<BTreeMap<K, V>> for ZBox<ZendHashTable>
1192+
where
1193+
K: AsRef<str>,
1194+
V: IntoZval,
1195+
{
1196+
type Error = Error;
1197+
1198+
fn try_from(value: BTreeMap<K, V>) -> Result<Self> {
1199+
let mut ht = ZendHashTable::with_capacity(
1200+
value.len().try_into().map_err(|_| Error::IntegerOverflow)?,
1201+
);
1202+
1203+
for (k, v) in value {
1204+
ht.insert(k.as_ref(), v)?;
1205+
}
1206+
1207+
Ok(ht)
1208+
}
1209+
}
1210+
1211+
impl<K, V> IntoZval for BTreeMap<K, V>
1212+
where
1213+
K: AsRef<str>,
1214+
V: IntoZval,
1215+
{
1216+
const TYPE: DataType = DataType::Array;
1217+
const NULLABLE: bool = false;
1218+
1219+
fn set_zval(self, zv: &mut Zval, _: bool) -> Result<()> {
1220+
let arr = self.try_into()?;
1221+
zv.set_hashtable(arr);
1222+
Ok(())
1223+
}
1224+
}
1225+
1226+
impl<'a, T> FromZval<'a> for BTreeMap<String, T>
1227+
where
1228+
T: FromZval<'a>,
1229+
{
1230+
const TYPE: DataType = DataType::Array;
1231+
1232+
fn from_zval(zval: &'a Zval) -> Option<Self> {
1233+
zval.array().and_then(|arr| arr.try_into().ok())
1234+
}
1235+
}
1236+
11681237
///////////////////////////////////////////
11691238
// Vec
11701239
///////////////////////////////////////////

0 commit comments

Comments
 (0)