Skip to content

Commit a4f622a

Browse files
committed
Implement array entry.
1 parent ef882eb commit a4f622a

File tree

4 files changed

+40
-18
lines changed

4 files changed

+40
-18
lines changed

phper/src/arrays.rs

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use std::{
1717
borrow::Borrow,
1818
convert::TryInto,
1919
marker::PhantomData,
20-
mem::forget,
20+
mem::{forget, ManuallyDrop},
2121
ops::{Deref, DerefMut},
2222
};
2323

@@ -40,6 +40,17 @@ pub enum InsertKey<'a> {
4040
ZStr(&'a ZStr),
4141
}
4242

43+
impl<'a> From<Key<'a>> for InsertKey<'a> {
44+
fn from(k: Key<'a>) -> Self {
45+
match k {
46+
Key::Index(i) => InsertKey::Index(i),
47+
Key::Str(s) => InsertKey::Str(s),
48+
Key::Bytes(b) => InsertKey::Bytes(b),
49+
Key::ZStr(s) => InsertKey::ZStr(s),
50+
}
51+
}
52+
}
53+
4354
#[repr(transparent)]
4455
pub struct ZArr {
4556
inner: zend_array,
@@ -115,16 +126,16 @@ impl ZArr {
115126
}
116127

117128
// Get item by key.
118-
pub fn get<'a>(&self, key: impl Into<Key<'a>>) -> Option<&ZVal> {
129+
pub fn get<'a>(&self, key: impl Into<Key<'a>>) -> Option<&'a ZVal> {
119130
self.inner_get(key).map(|v| &*v)
120131
}
121132

122133
// Get item by key.
123-
pub fn get_mut<'a>(&mut self, key: impl Into<Key<'a>>) -> Option<&mut ZVal> {
134+
pub fn get_mut<'a>(&mut self, key: impl Into<Key<'a>>) -> Option<&'a mut ZVal> {
124135
self.inner_get(key)
125136
}
126137

127-
fn inner_get<'a>(&self, key: impl Into<Key<'a>>) -> Option<&mut ZVal> {
138+
fn inner_get<'a>(&self, key: impl Into<Key<'a>>) -> Option<&'a mut ZVal> {
128139
let key = key.into();
129140
unsafe {
130141
let value = match key {
@@ -199,17 +210,19 @@ impl ZArr {
199210
}
200211
}
201212

202-
pub fn clear(&mut self) {}
203-
204213
pub fn iter(&self) -> Iter<'_> {
205214
Iter {
206215
index: 0,
207216
array: self,
208217
}
209218
}
210219

211-
pub fn entry<'a>(&mut self, _key: impl Into<Key<'a>>) -> Entry<'a> {
212-
todo!()
220+
pub fn entry<'a>(&'a mut self, key: impl Into<Key<'a>>) -> Entry<'a> {
221+
let key = key.into();
222+
match self.get_mut(key.clone()) {
223+
Some(val) => Entry::Occupied(val),
224+
None => Entry::Vacant { arr: self, key },
225+
}
213226
}
214227
}
215228

@@ -229,7 +242,12 @@ impl ToRefOwned for ZArr {
229242
type Owned = ZArray;
230243

231244
fn to_ref_owned(&mut self) -> Self::Owned {
232-
todo!()
245+
let mut val = ManuallyDrop::new(ZVal::default());
246+
unsafe {
247+
phper_zval_arr(val.as_mut_ptr(), self.as_mut_ptr());
248+
phper_z_addref_p(val.as_mut_ptr());
249+
ZArray::from_raw(val.as_mut_z_arr().unwrap().as_mut_ptr())
250+
}
233251
}
234252
}
235253

@@ -358,14 +376,20 @@ impl<'a> Iterator for Iter<'a> {
358376
}
359377
}
360378

361-
// TODO Implement it.
362379
pub enum Entry<'a> {
363-
Occupied(PhantomData<&'a ()>),
364-
Vacant(PhantomData<&'a ()>),
380+
Occupied(&'a mut ZVal),
381+
Vacant { arr: &'a mut ZArr, key: Key<'a> },
365382
}
366383

367384
impl<'a> Entry<'a> {
368-
pub fn or_insert(&mut self, _val: ZVal) -> &'a mut ZVal {
369-
todo!()
385+
pub fn or_insert(self, val: ZVal) -> &'a mut ZVal {
386+
match self {
387+
Entry::Occupied(val) => val,
388+
Entry::Vacant { arr, key } => {
389+
let insert_key: InsertKey<'_> = key.clone().into();
390+
arr.insert(insert_key, val);
391+
arr.get_mut(key).unwrap()
392+
}
393+
}
370394
}
371395
}

phper/src/errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ pub struct TypeError {
121121
}
122122

123123
#[derive(Debug, thiserror::Error, crate::Throwable, Constructor)]
124-
#[error("type error: must be of type {expect_type}, {actual_type} given")]
124+
#[error("must be of type {expect_type}, {actual_type} given")]
125125
#[throwable_class("TypeError")]
126126
pub struct ExpectTypeError {
127127
expect_type: TypeInfo,

phper/src/objects.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,11 +187,9 @@ impl ToRefOwned for ZObj {
187187

188188
fn to_ref_owned(&mut self) -> Self::Owned {
189189
let mut val = ManuallyDrop::new(ZVal::default());
190-
191190
unsafe {
192191
phper_zval_obj(val.as_mut_ptr(), self.as_mut_ptr());
193192
phper_z_addref_p(val.as_mut_ptr());
194-
phper_z_addref_p(val.as_mut_ptr());
195193
ZObject::from_raw(val.as_mut_z_obj().unwrap().as_mut_ptr())
196194
}
197195
}

tests/integration/src/arguments.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub fn integrate(module: &mut Module) {
2020
fn integrate_arguments(module: &mut Module) {
2121
module.add_function(
2222
"integrate_arguments_null",
23-
|arguments: &mut [ZVal]| arguments[0].as_null(),
23+
|arguments: &mut [ZVal]| arguments[0].expect_null(),
2424
vec![Argument::by_val("a")],
2525
);
2626

0 commit comments

Comments
 (0)