1
1
use crate :: { byond_string_internal, static_global:: byond, value:: ByondValue , Error } ;
2
2
/// List stuff goes here, Keep in mind that all indexing method starts at zero instead of one like byondland
3
3
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 > {
6
6
use std:: cell:: RefCell ;
7
7
if !self . is_list ( ) {
8
8
return Err ( Error :: NotAList ) ;
@@ -43,6 +43,49 @@ impl ByondValue {
43
43
} )
44
44
}
45
45
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
+
46
89
/// Writes an array to the list
47
90
pub fn write_list ( & self , list : & [ ByondValue ] ) -> Result < ( ) , Error > {
48
91
unsafe {
@@ -78,7 +121,7 @@ impl ByondValue {
78
121
}
79
122
80
123
/// 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 > {
82
125
let mut result = ByondValue :: new ( ) ;
83
126
unsafe {
84
127
map_byond_error ! ( byond( ) . Byond_ReadListIndex ( & self . 0 , & index. 0 , & mut result. 0 ) ) ?;
@@ -87,7 +130,7 @@ impl ByondValue {
87
130
}
88
131
89
132
/// 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 (
91
134
& mut self ,
92
135
index : & ByondValue ,
93
136
value : & ByondValue ,
0 commit comments