Skip to content

Commit 7c54477

Browse files
committed
thins
1 parent f86bbe8 commit 7c54477

File tree

1 file changed

+47
-4
lines changed
  • crates/byondapi-rs/src/value

1 file changed

+47
-4
lines changed

crates/byondapi-rs/src/value/list.rs

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use crate::{byond_string_internal, static_global::byond, value::ByondValue, Error};
22
/// List stuff goes here, Keep in mind that all indexing method starts at zero instead of one like byondland
33
impl ByondValue {
4-
/// Gets an array of all the list elements, this means keys for assoc lists and values for regular lists
5-
pub fn get_list(&self) -> Result<Vec<ByondValue>, Error> {
4+
/// Gets an array of all the list keys, this means keys for assoc lists and values for regular lists
5+
pub fn get_list_keys(&self) -> Result<Vec<ByondValue>, Error> {
66
use std::cell::RefCell;
77
if !self.is_list() {
88
return Err(Error::NotAList);
@@ -43,6 +43,49 @@ impl ByondValue {
4343
})
4444
}
4545

46+
/// Gets an array of all the list elements, this means both keys and values for assoc lists and values for regular lists
47+
/// Reads items as key,value pairs from an associative list, storing them sequentially as key1, value1, key2, value2, etc.
48+
pub fn get_list(&self) -> Result<Vec<ByondValue>, Error> {
49+
use std::cell::RefCell;
50+
if !self.is_list() {
51+
return Err(Error::NotAList);
52+
}
53+
54+
thread_local! {
55+
static BUFFER: RefCell<Vec<ByondValue>> = RefCell::new(Vec::with_capacity(1));
56+
}
57+
58+
BUFFER.with_borrow_mut(|buff| -> Result<Vec<ByondValue>, Error> {
59+
let mut len = buff.capacity() as u32;
60+
61+
// Safety: buffer capacity is passed to byond, which makes sure it writes in-bound
62+
let initial_res =
63+
unsafe { byond().Byond_ReadListAssoc(&self.0, buff.as_mut_ptr().cast(), &mut len) };
64+
match (initial_res, len) {
65+
(false, 1..) => {
66+
buff.reserve_exact(len as usize);
67+
// Safety: buffer capacity is passed to byond, which makes sure it writes in-bound
68+
unsafe {
69+
map_byond_error!(byond().Byond_ReadListAssoc(
70+
&self.0,
71+
buff.as_mut_ptr().cast(),
72+
&mut len
73+
))?
74+
};
75+
// Safety: buffer should be written to at this point
76+
unsafe { buff.set_len(len as usize) };
77+
Ok(std::mem::take(buff))
78+
}
79+
(true, _) => {
80+
// Safety: buffer should be written to at this point
81+
unsafe { buff.set_len(len as usize) };
82+
Ok(std::mem::take(buff))
83+
}
84+
(false, 0) => Err(Error::get_last_byond_error()),
85+
}
86+
})
87+
}
88+
4689
/// Writes an array to the list
4790
pub fn write_list(&self, list: &[ByondValue]) -> Result<(), Error> {
4891
unsafe {
@@ -78,7 +121,7 @@ impl ByondValue {
78121
}
79122

80123
/// Reads a value by key through the ref. Fails if the index doesn't exist
81-
pub fn read_list_index_internal(&self, index: &ByondValue) -> Result<ByondValue, Error> {
124+
fn read_list_index_internal(&self, index: &ByondValue) -> Result<ByondValue, Error> {
82125
let mut result = ByondValue::new();
83126
unsafe {
84127
map_byond_error!(byond().Byond_ReadListIndex(&self.0, &index.0, &mut result.0))?;
@@ -87,7 +130,7 @@ impl ByondValue {
87130
}
88131

89132
/// Writes a value by key through the ref. Dunno why it can fail
90-
pub fn write_list_index_internal(
133+
fn write_list_index_internal(
91134
&mut self,
92135
index: &ByondValue,
93136
value: &ByondValue,

0 commit comments

Comments
 (0)