Skip to content

Commit 03ed6cf

Browse files
Add more dict functions to c-api
1 parent a9c2c52 commit 03ed6cf

1 file changed

Lines changed: 114 additions & 1 deletion

File tree

crates/capi/src/dictobject.rs

Lines changed: 114 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::PyObject;
22
use crate::object::define_py_check;
33
use crate::pystate::with_vm;
4-
use core::ffi::c_int;
4+
use core::ffi::{CStr, c_char, c_int};
55
use core::ptr::NonNull;
66
use rustpython_vm::AsObject;
77
use rustpython_vm::PyPayload;
@@ -18,6 +18,15 @@ pub extern "C" fn PyDict_New() -> *mut PyObject {
1818
with_vm(|vm| vm.ctx.new_dict())
1919
}
2020

21+
#[unsafe(no_mangle)]
22+
pub unsafe extern "C" fn PyDict_Clear(dict: *mut PyObject) {
23+
with_vm(|vm| {
24+
let dict = unsafe { &*dict }.try_downcast_ref::<PyDict>(vm)?;
25+
dict.clear();
26+
Ok(())
27+
})
28+
}
29+
2130
#[unsafe(no_mangle)]
2231
pub unsafe extern "C" fn PyDict_SetItem(
2332
dict: *mut PyObject,
@@ -32,6 +41,99 @@ pub unsafe extern "C" fn PyDict_SetItem(
3241
})
3342
}
3443

44+
#[unsafe(no_mangle)]
45+
pub unsafe extern "C" fn PyDict_SetItemString(
46+
dict: *mut PyObject,
47+
key: *const c_char,
48+
val: *mut PyObject,
49+
) -> c_int {
50+
with_vm(|vm| {
51+
let dict = unsafe { &*dict }.try_downcast_ref::<PyDict>(vm)?;
52+
let key = unsafe { CStr::from_ptr(key) }
53+
.to_str()
54+
.map_err(|_| vm.new_value_error("dictionary key must be valid UTF-8"))?;
55+
let value = unsafe { &*val }.to_owned();
56+
dict.inner_setitem(key, value, vm)
57+
})
58+
}
59+
60+
#[unsafe(no_mangle)]
61+
pub unsafe extern "C" fn PyDict_GetItem(dict: *mut PyObject, key: *mut PyObject) -> *mut PyObject {
62+
with_vm(|vm| {
63+
let dict = unsafe { &*dict }.try_downcast_ref::<PyDict>(vm)?;
64+
let key = unsafe { &*key };
65+
66+
match dict.inner_getitem_opt(key, vm) {
67+
Ok(Some(value)) => Ok(value.as_object().as_raw().cast_mut()),
68+
Ok(None) | Err(_) => Ok(core::ptr::null_mut()),
69+
}
70+
})
71+
}
72+
73+
#[unsafe(no_mangle)]
74+
pub unsafe extern "C" fn PyDict_GetItemWithError(
75+
dict: *mut PyObject,
76+
key: *mut PyObject,
77+
) -> *mut PyObject {
78+
with_vm(|vm| {
79+
let dict = unsafe { &*dict }.try_downcast_ref::<PyDict>(vm)?;
80+
let key = unsafe { &*key };
81+
82+
if let Some(value) = dict.inner_getitem_opt(key, vm)? {
83+
Ok(value.as_object().as_raw().cast_mut())
84+
} else {
85+
Ok(core::ptr::null_mut())
86+
}
87+
})
88+
}
89+
90+
#[unsafe(no_mangle)]
91+
pub unsafe extern "C" fn PyDict_GetItemString(
92+
dict: *mut PyObject,
93+
key: *const c_char,
94+
) -> *mut PyObject {
95+
with_vm(|vm| {
96+
let dict = unsafe { &*dict }.try_downcast_ref::<PyDict>(vm)?;
97+
let key = match unsafe { CStr::from_ptr(key) }.to_str() {
98+
Ok(key) => key,
99+
Err(_) => {
100+
return Ok(core::ptr::null_mut());
101+
}
102+
};
103+
104+
match dict.inner_getitem_opt(key, vm) {
105+
Ok(Some(value)) => Ok(value.as_object().as_raw().cast_mut()),
106+
Ok(None) | Err(_) => Ok(core::ptr::null_mut()),
107+
}
108+
})
109+
}
110+
111+
#[unsafe(no_mangle)]
112+
pub unsafe extern "C" fn PyDict_GetItemStringRef(
113+
dict: *mut PyObject,
114+
key: *const c_char,
115+
result: *mut *mut PyObject,
116+
) -> c_int {
117+
with_vm(|vm| {
118+
unsafe {
119+
*result = core::ptr::null_mut();
120+
}
121+
let dict = unsafe { &*dict }.try_downcast_ref::<PyDict>(vm)?;
122+
let key = unsafe { CStr::from_ptr(key) }
123+
.to_str()
124+
.map_err(|_| vm.new_value_error("dictionary key must be valid UTF-8"))?;
125+
126+
if let Some(value) = dict.inner_getitem_opt(key, vm)? {
127+
unsafe {
128+
*result = value.into_raw().as_ptr();
129+
}
130+
Ok(true)
131+
} else {
132+
Ok(false)
133+
}
134+
})
135+
}
136+
35137
#[unsafe(no_mangle)]
36138
pub unsafe extern "C" fn PyDict_GetItemRef(
37139
dict: *mut PyObject,
@@ -128,6 +230,17 @@ pub unsafe extern "C" fn PyDict_DelItem(dict: *mut PyObject, key: *mut PyObject)
128230
})
129231
}
130232

233+
#[unsafe(no_mangle)]
234+
pub unsafe extern "C" fn PyDict_DelItemString(dict: *mut PyObject, key: *const c_char) -> c_int {
235+
with_vm(|vm| {
236+
let dict = unsafe { &*dict }.try_downcast_ref::<PyDict>(vm)?;
237+
let key = unsafe { CStr::from_ptr(key) }
238+
.to_str()
239+
.map_err(|_| vm.new_value_error("dictionary key must be valid UTF-8"))?;
240+
dict.del_item(key, vm)
241+
})
242+
}
243+
131244
#[unsafe(no_mangle)]
132245
pub unsafe extern "C" fn PyDict_Items(dict: *mut PyObject) -> *mut PyObject {
133246
with_vm(|vm| {

0 commit comments

Comments
 (0)