1use std::{
10 cell::Cell,
11 collections::HashMap,
12 ffi::{CStr, CString, c_char, c_void},
13 hash::Hash,
14 ptr,
15};
16
17use anyhow::{Error, anyhow};
18
19use crate::{
20 borrow_string, borrow_var, create_raw_string, shared::{PtrMagic, get_current_arena_id, object::{apply_ref_count_alloc, apply_ref_count_delete, get_object}, pxs_Runtime, remove_var_from_arena, save_var_in_arena}
21};
22
23macro_rules! write_func {
25 ($ (($func_name:ident, $field_name:ident, $ret_type:ty, $tag_variant:path) ),* $(,)?) => {
26 $(
27 #[doc = concat!("Returns the ", stringify!($ret_type), " value if the tag is ", stringify!($tag_variant), ".")]
28 pub fn $func_name(&self) -> Result<$ret_type, Error> {
29 if self.tag == $tag_variant {
30 unsafe {
31 Ok(self.value.$field_name)
32 }
33 } else {
34 Err(anyhow!("Var is not the expected type of {:#?}. It is instead a: {:#?}", $tag_variant, self.tag))
35 }
36 }
37 )*
38 };
39}
40
41macro_rules! write_new_methods {
43 ($($t:ty, $func:ident, $vt:expr, $vn:ident);*) => {
44 $(
45 pub fn $func(val:$t) -> Self {
46 Self::new(
47 $vt,
48 pxs_VarValue { $vn: val },
49 default_deleter
50 )
51 }
52 )*
53 };
54}
55
56macro_rules! write_is_methods {
58 ($($func:ident, $vt:expr);*) => {
59 $(
60 pub fn $func(&self) -> bool {
61 self.tag == $vt
62 }
63 )*
64 };
65}
66
67#[repr(C)]
82#[derive(Debug, PartialEq, Clone, Copy)]
83#[allow(non_camel_case_types)]
84pub enum pxs_VarType {
85 pxs_Int64,
86 pxs_UInt64,
87 pxs_String,
88 pxs_Bool,
89 pxs_Float64,
90 pxs_Null,
92 pxs_Object,
94 pxs_HostObject,
97 pxs_List,
99 pxs_Function,
101 pxs_Factory,
103 pxs_Exception,
105 pxs_Map,
108}
109
110#[allow(non_camel_case_types)]
114pub struct pxs_VarObject {
115 object_val: *mut c_void,
116 host_ptr: i32
117}
118
119impl PtrMagic for pxs_VarObject {}
120
121impl pxs_VarObject {
122 pub fn new(val: *mut c_void, host_ptr: i32) -> Self {
123 Self {
124 object_val: val,
125 host_ptr: host_ptr
126 }
127 }
128
129 pub fn get_raw(&self) -> *mut c_void {
131 self.object_val
132 }
133
134 pub fn new_as_host(val: *mut c_void, host_ptr: i32) -> Self {
136 Self::new(val, host_ptr)
137 }
138
139 pub fn new_lang_only(val: *mut c_void) -> Self {
141 Self::new(val, -1)
142 }
143}
144
145impl Clone for pxs_VarObject {
146 fn clone(&self) -> Self {
147 if self.host_ptr != -1 {
149 apply_ref_count_alloc(self.host_ptr);
150 }
151
152 Self {
153 object_val: self.object_val,
154 host_ptr: self.host_ptr
155 }
156 }
157}
158
159impl Drop for pxs_VarObject {
160 fn drop(&mut self) {
161 if self.host_ptr == -1 {
162 return;
163 }
164
165 apply_ref_count_delete(self.host_ptr);
167 }
168}
169
170#[allow(non_camel_case_types)]
174pub struct pxs_VarMap {
175 map: HashMap<pxs_Var, pxs_Var>,
177}
178
179impl PtrMagic for pxs_VarMap {}
180
181impl pxs_VarMap {
182 pub fn new() -> Self {
184 Self {
185 map: HashMap::new(),
186 }
187 }
188
189 pub fn add_item(&mut self, mut key: pxs_Var, mut value: pxs_Var) {
193 key.remove_from_arena();
194 value.remove_from_arena();
195 let _ = self.map.insert(key, value);
197 }
198
199 pub fn del_item(&mut self, key: &pxs_Var) {
203 let _ = self.map.remove(key);
204 }
205
206 pub fn len(&self) -> usize {
208 self.map.len()
209 }
210
211 pub fn get_item(&self, key: &pxs_Var) -> Option<&pxs_Var> {
213 self.map.get(key)
214 }
215
216 pub fn keys(&self) -> Vec<&pxs_Var> {
218 self.map.keys().collect()
219 }
220}
221
222#[allow(non_camel_case_types)]
227pub struct pxs_FactoryHolder {
228 pub callback: super::func::pxs_Func,
229 pub args: *mut pxs_Var,
230}
231
232impl pxs_FactoryHolder {
233 pub fn get_args(&self, rt: pxs_Runtime) -> pxs_Var {
236 let args = self.args;
237 assert!(!args.is_null(), "Factory args must not be null");
239 unsafe {
240 let args_clone = pxs_Var::from_borrow(self.args).clone();
242 assert!(args_clone.is_list(), "Factory args must be a list");
244 let args_list = args_clone.get_list().unwrap();
246 args_list.vars.insert(0, pxs_Var::new_i64(rt.into_i64()));
247
248 args_clone
249 }
250 }
251
252 pub fn call(&self, rt: pxs_Runtime) -> pxs_Var {
254 let args = self.get_args(rt);
255 let args_raw = args.into_raw();
257
258 let res = unsafe { (self.callback)(args_raw) };
259 let var = if res.is_null() {
260 pxs_Var::new_null()
261 } else {
262 pxs_Var::from_raw(res)
263 };
264 let _ = pxs_Var::from_raw(args_raw);
266
267 var
269 }
270}
271
272impl PtrMagic for pxs_FactoryHolder {
273 fn into_raw(self) -> *mut Self {
274 let args = unsafe{pxs_Var::from_borrow(self.args)};
276 let list = args.get_list().unwrap();
277 for v in list.vars.iter_mut() {
278 v.remove_from_arena();
279 }
280 args.remove_from_arena();
281 Box::into_raw(Box::new(self))
282 }
283}
284
285impl Drop for pxs_FactoryHolder {
286 fn drop(&mut self) {
287 if self.args.is_null() {
288 return;
289 }
290
291 let _ = pxs_Var::from_raw(self.args);
293 }
294}
295
296#[allow(non_camel_case_types)]
325pub struct pxs_VarList {
326 pub vars: Vec<pxs_Var>,
327}
328
329impl PtrMagic for pxs_VarList {
330 fn into_raw(mut self) -> *mut Self {
331 for v in self.vars.iter_mut() {
333 v.remove_from_arena();
334 }
335 Box::into_raw(Box::new(self))
336 }
337}
338
339impl pxs_VarList {
340 pub fn new() -> Self {
342 pxs_VarList { vars: vec![] }
343 }
344
345 fn get_rindex(&self, index: i32) -> i32 {
346 if index < 0 {
347 (self.vars.len() as i32) + index
348 } else {
349 index
350 }
351 }
352
353 pub fn add_item(&mut self, mut item: pxs_Var) {
355 item.remove_from_arena();
356 self.vars.push(item);
357 }
358
359 pub fn get_item(&self, index: i32) -> Option<&pxs_Var> {
361 let r_index = self.get_rindex(index);
363
364 if r_index < 0 {
365 None
366 } else {
367 self.vars.get(r_index as usize)
368 }
369 }
370
371 pub fn set_item(&mut self, mut item: pxs_Var, index: i32) -> bool {
375 item.remove_from_arena();
376 let r_index = self.get_rindex(index);
378
379 if r_index < 0 {
380 return false;
381 }
382
383 if self.vars.len() < r_index as usize {
384 false
385 } else {
386 self.vars[r_index as usize] = item;
387 true
388 }
389 }
390
391 pub fn del_item(&mut self, index: i32) -> bool {
393 let r_index = self.get_rindex(index);
394
395 if r_index < 0 {
396 return false;
397 }
398
399 if self.vars.len() < r_index as usize {
400 false
401 } else {
402 self.vars.remove(index as usize);
403 true
404 }
405 }
406
407 pub fn len(&self) -> usize {
409 self.vars.len()
410 }
411
412 pub fn insert_item(&mut self, index: usize, item: pxs_Var) {
414 self.vars.insert(index, item);
415 }
416}
417
418#[repr(C)]
420#[allow(non_camel_case_types)]
421pub union pxs_VarValue {
422 pub i64_val: i64,
423 pub u64_val: u64,
424 pub string_val: *mut c_char,
425 pub bool_val: bool,
426 pub f64_val: f64,
427 pub null_val: *const c_void,
428 pub object_val: *mut pxs_VarObject,
429 pub host_object_val: i32,
430 pub list_val: *mut pxs_VarList,
431 pub function_val: *mut c_void,
432 pub factory_val: *mut pxs_FactoryHolder,
433 pub map_val: *mut pxs_VarMap,
434}
435
436#[allow(non_camel_case_types)]
437pub type pxs_DeleterFn = unsafe extern "C" fn(*mut c_void);
439
440pub unsafe extern "C" fn default_deleter(_ptr: *mut c_void) {
443 }
445
446#[repr(C)]
473#[allow(non_camel_case_types)]
474pub struct pxs_Var {
475 pub tag: pxs_VarType,
477 pub value: pxs_VarValue,
479
480 pub deleter: Cell<pxs_DeleterFn>,
482
483 pub idx: i32,
485
486 pub arena: i32
489}
490
491impl pxs_Var {
493 pub fn new(tag: pxs_VarType, value: pxs_VarValue, deleter: pxs_DeleterFn) -> Self {
494 Self {
495 tag,
496 value,
497 deleter: Cell::new(deleter),
498 idx: -1,
499 arena: -1
500 }
501 }
502
503 pub unsafe fn slice_raw(argv: *mut *mut Self, argc: usize) -> &'static [*mut pxs_Var] {
504 unsafe { std::slice::from_raw_parts(argv, argc) }
505 }
506
507 pub fn get_host_ptr(&self) -> *mut c_void {
509 let object = get_object(self.get_host_idx());
510 if let Some(obj) = object {
511 obj.ptr
512 } else {
513 std::ptr::null_mut()
514 }
515 }
516
517 pub fn get_string(&self) -> Result<String, Error> {
521 if self.tag == pxs_VarType::pxs_String || self.tag == pxs_VarType::pxs_Exception {
522 unsafe {
523 if self.value.string_val.is_null() {
524 return Err(anyhow!("String pointer is null"));
525 }
526
527 let c_str = CStr::from_ptr(self.value.string_val);
528 let res = c_str.to_str();
529 if res.is_err() {
530 return Err(anyhow!(res.err().unwrap()));
531 }
532
533 Ok(res.unwrap().to_string())
534 }
535 } else {
536 Err(anyhow!("Var is not a string."))
537 }
538 }
539
540 pub fn new_string(val: String) -> Self {
545 let cstr = CString::new(val).expect("Could not create CString.");
546
547 Self::new(pxs_VarType::pxs_String, pxs_VarValue{string_val: cstr.into_raw()}, default_deleter)
548 }
549
550 pub fn new_null() -> Self {
554 Self::new(pxs_VarType::pxs_Null, pxs_VarValue{null_val: ptr::null()}, default_deleter)
555 }
556
557 pub fn new_host_object(ptr: i32) -> Self {
559 Self::new(pxs_VarType::pxs_HostObject, pxs_VarValue{host_object_val: ptr}, default_deleter)
560 }
561
562 pub fn new_object(ptr: pxs_VarObject, deleter: Option<pxs_DeleterFn>) -> Self {
564 let deleter = if let Some(d) = deleter {
565 d
566 } else {
567 default_deleter
568 };
569
570 Self::new(pxs_VarType::pxs_Object, pxs_VarValue { object_val: ptr.into_raw() }, deleter)
571 }
572
573 pub fn new_list() -> Self {
575 Self::new(pxs_VarType::pxs_List, pxs_VarValue{list_val: pxs_VarList::new().into_raw()}, default_deleter)
576 }
577
578 pub fn new_list_with(vars: Vec<pxs_Var>) -> Self {
580 let mut list = pxs_VarList::new();
581 list.vars = vars;
582 Self::new(pxs_VarType::pxs_List, pxs_VarValue{list_val: list.into_raw()}, default_deleter)
583 }
584
585 pub fn new_function(ptr: *mut c_void, deleter: Option<pxs_DeleterFn>) -> Self {
587 let deleter = if let Some(d) = deleter {
588 d
589 } else {
590 default_deleter
591 };
592
593 Self::new(pxs_VarType::pxs_Function, pxs_VarValue { function_val: ptr }, deleter)
594 }
595
596 pub fn new_factory(func: super::func::pxs_Func, args: pxs_VarT) -> Self {
598 let factory = pxs_FactoryHolder {
600 callback: func,
601 args,
602 };
603 Self::new(pxs_VarType::pxs_Factory, pxs_VarValue{factory_val: factory.into_raw()}, default_deleter)
604 }
605
606 pub fn new_exception<T: ToString>(msg: T) -> Self {
608 Self::new(pxs_VarType::pxs_Exception, pxs_VarValue{string_val: create_raw_string!(msg.to_string())}, default_deleter)
609 }
610
611 pub fn new_map() -> Self {
613 Self::new(pxs_VarType::pxs_Map, pxs_VarValue{map_val: pxs_VarMap::new().into_raw()}, default_deleter)
614 }
615
616 pub fn get_host_idx(&self) -> i32 {
618 match self.tag {
619 pxs_VarType::pxs_Int64 => self.get_i64().unwrap() as i32,
620 pxs_VarType::pxs_UInt64 => self.get_u64().unwrap() as i32,
621 pxs_VarType::pxs_HostObject => unsafe { self.value.host_object_val },
622 _ => -1,
623 }
624 }
625
626 pub fn get_object_ptr(&self) -> *mut c_void {
628 match self.tag {
629 pxs_VarType::pxs_Object => unsafe {
630 let object = pxs_VarObject::from_borrow(self.value.object_val);
631 object.get_raw()
632 },
633 _ => std::ptr::null_mut(),
634 }
635 }
636
637 pub fn get_list(&self) -> Option<&mut pxs_VarList> {
639 if !self.is_list() {
640 None
641 } else {
642 unsafe { Some(pxs_VarList::from_borrow(self.value.list_val)) }
643 }
644 }
645
646 pub fn get_factory(&self) -> Option<&mut pxs_FactoryHolder> {
648 if !self.is_factory() {
649 None
650 } else {
651 unsafe {
652 if self.value.factory_val.is_null() {
653 None
654 } else {
655 Some(pxs_FactoryHolder::from_borrow(self.value.factory_val))
656 }
657 }
658 }
659 }
660
661 pub fn get_map(&self) -> Option<&mut pxs_VarMap> {
663 if !self.is_map() {
664 None
665 } else {
666 unsafe { Some(pxs_VarMap::from_borrow(self.value.map_val)) }
667 }
668 }
669
670 unsafe fn dbg(&self) -> String {
686 unsafe {
687 let details = match self.tag {
688 pxs_VarType::pxs_Int64 => self.value.i64_val.to_string(),
689 pxs_VarType::pxs_UInt64 => self.value.u64_val.to_string(),
690 pxs_VarType::pxs_String => borrow_string!(self.value.string_val).to_string(),
691 pxs_VarType::pxs_Bool => self.value.bool_val.to_string(),
692 pxs_VarType::pxs_Float64 => self.value.f64_val.to_string(),
693 pxs_VarType::pxs_Null => "Null".to_string(),
694 pxs_VarType::pxs_Object => "Object".to_string(),
695 pxs_VarType::pxs_HostObject => {
696 let idx = self.get_host_idx();
697 let object = get_object(idx).unwrap();
698 object.type_name.to_string()
699 }
700 pxs_VarType::pxs_List => {
701 let list = self.get_list().unwrap();
702 let t: String = list.vars.iter().map(|v| format!("{},", v.dbg())).collect();
703 format!("[{t}]")
704 }
705 pxs_VarType::pxs_Function => "Function".to_string(),
706 pxs_VarType::pxs_Factory => "Factory".to_string(),
707 pxs_VarType::pxs_Exception => borrow_string!(self.value.string_val).to_string(),
708 pxs_VarType::pxs_Map => {
709 let map = self.get_map().unwrap();
710 let keys = map.keys();
711 let mut res = String::from("{");
712 for k in keys {
713 let value = map.get_item(k);
714 res.push_str(format!("{:#?}: {:#?},\n", k, value).as_str());
715 }
716 res.push_str("}");
717
718 res
719 }
720 };
721
722 format!("{details} :: {},{} :: {:p}", self.arena, self.idx, self)
723 }
724 }
725
726 write_func!(
733 (get_i64, i64_val, i64, pxs_VarType::pxs_Int64),
734 (get_u64, u64_val, u64, pxs_VarType::pxs_UInt64),
735 (get_bool, bool_val, bool, pxs_VarType::pxs_Bool),
736 (get_f64, f64_val, f64, pxs_VarType::pxs_Float64),
737 (
738 get_function,
739 function_val,
740 *mut c_void,
741 pxs_VarType::pxs_Function
742 )
743 );
744
745 write_new_methods! {
747 i64, new_i64, pxs_VarType::pxs_Int64, i64_val;
748 u64, new_u64, pxs_VarType::pxs_UInt64, u64_val;
749 f64, new_f64, pxs_VarType::pxs_Float64, f64_val;
750 bool, new_bool, pxs_VarType::pxs_Bool, bool_val
751 }
752
753 write_is_methods! {
754 is_i64, pxs_VarType::pxs_Int64;
755 is_u64, pxs_VarType::pxs_UInt64;
756 is_f64, pxs_VarType::pxs_Float64;
757 is_bool, pxs_VarType::pxs_Bool;
758 is_string, pxs_VarType::pxs_String;
759 is_null, pxs_VarType::pxs_Null;
760 is_object, pxs_VarType::pxs_Object;
761 is_host_object, pxs_VarType::pxs_HostObject;
762 is_list, pxs_VarType::pxs_List;
763 is_function, pxs_VarType::pxs_Function;
764 is_factory, pxs_VarType::pxs_Factory;
765 is_exception, pxs_VarType::pxs_Exception;
766 is_map, pxs_VarType::pxs_Map
767 }
768
769 pub fn shallow_copy(&self) -> pxs_Var {
775 unsafe{
776 match self.tag {
777 pxs_VarType::pxs_Int64 => self.clone(),
778 pxs_VarType::pxs_UInt64 => self.clone(),
779 pxs_VarType::pxs_String => self.clone(),
780 pxs_VarType::pxs_Bool => self.clone(),
781 pxs_VarType::pxs_Float64 => self.clone(),
782 pxs_VarType::pxs_Null => self.clone(),
783 pxs_VarType::pxs_Exception => self.clone(),
784 pxs_VarType::pxs_HostObject => self.clone(),
785 pxs_VarType::pxs_Object => {
786 let object = pxs_VarObject::from_borrow(self.value.object_val);
787 Self::new(pxs_VarType::pxs_Object, pxs_VarValue{object_val: object.clone().into_raw()}, default_deleter)
789 },
790 pxs_VarType::pxs_List => {
791 let mut list = pxs_VarList::new();
792 let og_list_val = pxs_VarList::from_borrow(self.value.list_val);
793
794 for item in og_list_val.vars.iter() {
796 list.add_item(item.shallow_copy());
797 }
798
799 Self::new(pxs_VarType::pxs_List, pxs_VarValue{list_val: list.into_raw()}, default_deleter)
800 },
801 pxs_VarType::pxs_Function => {
802 Self::new(pxs_VarType::pxs_Function, pxs_VarValue{function_val: self.value.function_val}, default_deleter)
803 },
804 pxs_VarType::pxs_Factory => {
805 let og = pxs_FactoryHolder::from_borrow(self.value.factory_val);
806 if og.args.is_null() {
807 return pxs_Var::new_null();
808 }
809
810 let new_args = pxs_Var::new_list();
812 let old_args = pxs_Var::from_borrow(og.args);
813 if !old_args.is_list() {
814 return pxs_Var::new_null();
815 }
816 let old_list = old_args.get_list().unwrap();
817 let new_list = new_args.get_list().unwrap();
818 for var in old_list.vars.iter() {
819 new_list.add_item(var.shallow_copy());
820 }
821 let f = pxs_FactoryHolder {
822 args: new_args.into_raw(),
823 callback: og.callback,
824 };
825 Self::new(pxs_VarType::pxs_Factory, pxs_VarValue{factory_val: f.into_raw()}, default_deleter)
826 },
827 pxs_VarType::pxs_Map => {
828 let mut map = pxs_VarMap::new();
830 let og_map = self.get_map().unwrap();
832 let keys = og_map.keys();
834 for k in keys {
835 let v = og_map.get_item(k);
836 if let Some(v) = v {
837 map.add_item(k.shallow_copy(), v.shallow_copy());
839 }
840 }
841
842 Self::new(pxs_VarType::pxs_Map, pxs_VarValue{map_val: map.into_raw()}, default_deleter)
844 },
845 }
846 }
847 }
848
849 pub fn remove_from_arena(&mut self) {
851 if self.idx < 0 && self.arena < 0 {
852 return;
853 }
854 remove_var_from_arena(self.arena, self.idx);
855 self.idx = -1;
856 self.arena = -1;
857 }
858}
859
860unsafe impl Send for pxs_Var {}
861unsafe impl Sync for pxs_Var {}
862
863impl Drop for pxs_Var {
864 fn drop(&mut self) {
865 if self.idx > -1 && self.arena > -1 {
866 self.remove_from_arena();
867 }
868
869 if self.tag == pxs_VarType::pxs_String || self.tag == pxs_VarType::pxs_Exception {
870 unsafe {
871 if !self.value.string_val.is_null() {
873 let _ = CString::from_raw(self.value.string_val);
874 self.value.string_val = ptr::null_mut();
875 }
876 }
877 } else if self.tag == pxs_VarType::pxs_List {
878 let _ = unsafe {
879 pxs_VarList::from_raw(self.value.list_val)
881 };
882 } else if self.tag == pxs_VarType::pxs_Object {
883 unsafe {
884 if self.value.object_val.is_null() {
885 return;
886 }
887 let object = pxs_VarObject::from_raw(self.value.object_val);
888 (self.deleter.get())(object.get_raw());
889 };
891 } else if self.tag == pxs_VarType::pxs_Function {
892 unsafe {
893 if self.value.object_val.is_null() {
894 return;
895 }
896 (self.deleter.get())(self.value.function_val)
897 };
898 } else if self.tag == pxs_VarType::pxs_Factory {
899 unsafe {
901 if self.value.factory_val.is_null() {
902 return;
903 }
904 let _ = pxs_FactoryHolder::from_raw(self.value.factory_val);
905 }
911 } else if self.tag == pxs_VarType::pxs_Map {
912 let _ = unsafe {
913 pxs_VarMap::from_raw(self.value.map_val)
914 };
915 }
916 }
917}
918
919impl PtrMagic for pxs_Var {
920 fn into_raw(self) -> *mut Self {
922 let arena = get_current_arena_id();
923 let ptr = Box::into_raw(Box::new(self));
924
925 save_var_in_arena(arena, ptr);
927
928 ptr
929 }
930}
931
932impl Clone for pxs_Var {
933 fn clone(&self) -> Self {
934 unsafe {
935 match self.tag {
936 pxs_VarType::pxs_Int64 => pxs_Var::new_i64(self.value.i64_val),
937 pxs_VarType::pxs_UInt64 => pxs_Var::new_u64(self.value.u64_val),
938 pxs_VarType::pxs_String => {
939 let string = borrow_string!(self.value.string_val);
940 let cloned_string = string.to_string().clone();
941 let new_string = create_raw_string!(cloned_string);
942
943 Self::new(pxs_VarType::pxs_String, pxs_VarValue{string_val: new_string}, default_deleter)
944 }
945 pxs_VarType::pxs_Bool => pxs_Var::new_bool(self.value.bool_val),
946 pxs_VarType::pxs_Float64 => pxs_Var::new_f64(self.value.f64_val),
947 pxs_VarType::pxs_Null => pxs_Var::new_null(),
948 pxs_VarType::pxs_Object => {
949 let object = pxs_VarObject::from_borrow(self.value.object_val);
950
951 let r = Self::new(pxs_VarType::pxs_Object, pxs_VarValue{object_val: object.clone().into_raw()}, self.deleter.get());
953
954 self.deleter.set(default_deleter);
955
956 r
957 }
958 pxs_VarType::pxs_HostObject => pxs_Var::new_host_object(self.value.host_object_val),
959 pxs_VarType::pxs_List => {
960 let mut list = pxs_VarList::new();
961 let og_list_val = pxs_VarList::from_borrow(self.value.list_val);
963
964 for item in og_list_val.vars.iter() {
966 list.add_item(item.clone());
968 }
969
970 Self::new(pxs_VarType::pxs_List, pxs_VarValue{ list_val: list.into_raw()}, default_deleter)
971 }
972 pxs_VarType::pxs_Function => {
973 let r = Self::new(pxs_VarType::pxs_Function, pxs_VarValue{function_val: self.value.function_val}, self.deleter.get());
974
975 self.deleter.set(default_deleter);
976 r
977 }
978 pxs_VarType::pxs_Factory => {
979 let og = pxs_FactoryHolder::from_borrow(self.value.factory_val);
980 if og.args.is_null() {
981 return pxs_Var::new_null();
982 }
983 let new_args = pxs_Var::new_list();
985 let old_args = pxs_Var::from_borrow(og.args);
986 if !old_args.is_list() {
987 return pxs_Var::new_null();
988 }
989 let old_list = old_args.get_list().unwrap();
990 let new_list = new_args.get_list().unwrap();
991 for var in old_list.vars.iter() {
992 new_list.add_item(var.clone());
993 }
994 let f = pxs_FactoryHolder {
995 args: new_args.into_raw(),
996 callback: og.callback,
997 };
998 Self::new(pxs_VarType::pxs_Factory, pxs_VarValue{factory_val: f.into_raw()}, default_deleter)
999 }
1000 pxs_VarType::pxs_Exception => {
1001 let string = borrow_string!(self.value.string_val);
1002 let cloned_string = string.to_string().clone();
1003 let new_string = create_raw_string!(cloned_string);
1004 Self::new(pxs_VarType::pxs_Exception, pxs_VarValue{string_val: new_string}, default_deleter)
1005 }
1006 pxs_VarType::pxs_Map => {
1007 let mut map = pxs_VarMap::new();
1009 let og_map = self.get_map().unwrap();
1011 let keys = og_map.keys();
1013 for k in keys {
1014 let v = og_map.get_item(k);
1015 if let Some(v) = v {
1016 map.add_item(k.clone(), v.clone());
1017 }
1018 }
1019
1020 Self::new(pxs_VarType::pxs_Map, pxs_VarValue{map_val: map.into_raw()}, default_deleter)
1022 }
1023 }
1024 }
1025 }
1026}
1027
1028impl std::fmt::Debug for pxs_Var {
1029 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1030 let debug_val: &dyn std::fmt::Debug = unsafe { &self.dbg() };
1031 f.debug_struct("pxs_Var")
1032 .field("tag", &self.tag)
1033 .field("value", debug_val)
1034 .finish()
1035 }
1036}
1037
1038impl PartialEq for pxs_Var {
1039 fn eq(&self, other: &Self) -> bool {
1040 unsafe {
1041 match (&self.tag, &other.tag) {
1042 (pxs_VarType::pxs_Int64, pxs_VarType::pxs_Int64) => {
1043 self.value.i64_val == other.value.i64_val
1044 }
1045 (pxs_VarType::pxs_Int64, _) => false,
1046 (pxs_VarType::pxs_UInt64, pxs_VarType::pxs_UInt64) => {
1047 self.value.u64_val == other.value.u64_val
1048 }
1049 (pxs_VarType::pxs_UInt64, _) => false,
1050 (pxs_VarType::pxs_String, pxs_VarType::pxs_String) => {
1051 self.get_string().unwrap_or(String::new())
1052 == other.get_string().unwrap_or(String::new())
1053 }
1054 (pxs_VarType::pxs_String, _) => false,
1055 (pxs_VarType::pxs_Bool, pxs_VarType::pxs_Bool) => {
1056 self.value.bool_val == other.value.bool_val
1057 }
1058 (pxs_VarType::pxs_Bool, _) => false,
1059 (pxs_VarType::pxs_Float64, pxs_VarType::pxs_Float64) => {
1060 self.value.f64_val == other.value.f64_val
1061 }
1062 (pxs_VarType::pxs_Float64, _) => false,
1063 (pxs_VarType::pxs_Null, _) => false,
1064 (pxs_VarType::pxs_Object, _) => false,
1065 (pxs_VarType::pxs_HostObject, _) => false,
1066 (pxs_VarType::pxs_List, _) => false,
1067 (pxs_VarType::pxs_Function, _) => false,
1068 (pxs_VarType::pxs_Factory, _) => false,
1069 (pxs_VarType::pxs_Exception, _) => false,
1070 (pxs_VarType::pxs_Map, _) => false,
1071 }
1072 }
1073 }
1074}
1075
1076impl Eq for pxs_Var {}
1077
1078impl Hash for pxs_Var {
1079 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1080 unsafe {
1081 match self.tag {
1082 pxs_VarType::pxs_Int64 => self.value.i64_val.hash(state),
1083 pxs_VarType::pxs_UInt64 => self.value.u64_val.hash(state),
1084 pxs_VarType::pxs_String => self.get_string().unwrap_or(String::new()).hash(state),
1085 pxs_VarType::pxs_Bool => self.value.bool_val.hash(state),
1086 pxs_VarType::pxs_Float64 => self.value.f64_val.to_bits().hash(state),
1087 _ => panic!("Can not Hash none basic pxs_VarType")
1088 }
1089 }
1090 }
1091}
1092
1093impl pxs_Var {
1094 pub fn incorrect_type_ep(expected: pxs_VarType, found: pxs_VarType) -> Self {
1096 Self::new_exception(format!("Expected {:#?}, found {:#?}", expected, found))
1097 }
1098
1099 pub fn incorrect_types_ep(allowed: Vec<pxs_VarType>, found: pxs_VarType) -> Self {
1101 Self::new_exception(format!("Allowed types: {:#?}, found: {:#?}", allowed, found))
1102 }
1103
1104 pub fn null_params_ep() -> Self {
1106 Self::new_exception("Paramaters are null")
1107 }
1108
1109 pub fn null_param_ep<T: ToString>(name:T) -> Self {
1111 Self::new_exception(format!("{} is null", name.to_string()))
1112 }
1113
1114 pub fn unkown_runtime_ep(runtime: i64) -> Self {
1116 Self::new_exception(format!("Unkown runtime: {runtime}"))
1117 }
1118
1119 pub fn unkown_runtime_var_ep(runtime: pxs_VarT) -> Self {
1121 let var = unsafe{Self::from_borrow(runtime)};
1122 Self::new_exception(format!("Unkown runtime: {:#?}", var))
1123 }
1124
1125 pub fn item_not_found_ep() -> Self {
1127 Self::new_exception("Item not found")
1128 }
1129
1130 pub fn feature_not_enabled_ep(feature: &str) -> Self {
1132 Self::new_exception(format!("{feature} is not enabled."))
1133 }
1134}
1135
1136pub trait ObjectMethods {
1138 fn object_call(var: &pxs_Var, method: &str, args: &mut pxs_VarList) -> Result<pxs_Var, Error>;
1140
1141 fn call_method(method: &str, args: &mut pxs_VarList) -> Result<pxs_Var, Error>;
1143
1144 fn var_call(method: &pxs_Var, args: &mut pxs_VarList) -> Result<pxs_Var, Error>;
1146
1147 fn get(var: &pxs_Var, key: &str) -> Result<pxs_Var, Error>;
1149
1150 fn set(var: &pxs_Var, key: &str, value: &pxs_Var) -> Result<pxs_Var, Error>;
1152
1153 fn get_from_name(name: &str) -> Result<pxs_Var, Error>;
1155}
1156
1157#[allow(non_camel_case_types)]
1160pub type pxs_VarT = *mut pxs_Var;