pipeline_script/core/
builtin.rs

1use std::ffi::{c_char, CStr};
2use std::process::{Command, Stdio};
3use std::thread::{self};
4use std::time::{Duration, SystemTime, UNIX_EPOCH};
5
6#[repr(C)]
7pub struct Array {
8    len: i64,
9    ptr: *mut Any,
10}
11#[repr(C)]
12pub struct Any {
13    id: i32,
14    ptr: *mut i8,
15}
16#[allow(unused)]
17pub extern "C" fn len(target: Array) -> i64 {
18    target.len
19}
20pub extern "C" fn println(obj: Any) {
21    unsafe {
22        match obj.id {
23            0 => {
24                print!("Unit")
25            }
26            1 => {
27                let b = obj.ptr as *mut bool;
28                print!("{}", *b);
29            }
30            3 => {
31                let value = obj.ptr as i8;
32                print!("{}", value);
33            }
34            5 => {
35                let value = obj.ptr as i16;
36                print!("{}", value);
37            }
38            7 => {
39                let v = obj.ptr as i32;
40                print!("{}", v);
41            }
42            9 => {
43                let v = obj.ptr as i64;
44                print!("{}", v);
45            }
46            11 => {
47                let v = obj.ptr as *mut f32;
48                print!("{}", *v);
49            }
50            13 => {
51                let v = obj.ptr as *mut f64;
52                print!("{}", *v);
53            }
54            15 => {
55                let s = CStr::from_ptr(obj.ptr as *const c_char);
56                print!("{}", s.to_str().unwrap());
57            }
58
59            t => todo!("{t}"),
60        }
61    }
62    // }
63    println!()
64}
65#[allow(unused)]
66pub extern "C" fn print(obj: Array) {
67    for i in 0..obj.len {
68        let obj = unsafe { (obj.ptr).offset(i as isize) };
69        unsafe {
70            match (*obj).id {
71                0 => {
72                    print!("Unit")
73                }
74                3 => {
75                    let value = (*obj).ptr as i32;
76                    print!("{}", value);
77                }
78                4 => {
79                    let v = (*obj).ptr as i64;
80                    print!("{}", v);
81                }
82                7 => {
83                    let s = CStr::from_ptr((*obj).ptr as *const c_char);
84                    print!("{}", s.to_str().unwrap());
85                }
86                t => todo!("{t}"),
87            }
88        }
89    }
90}
91pub extern "C" fn append(obj: Array) -> *mut c_char {
92    let mut s = String::new();
93    for i in 0..obj.len {
94        let obj = unsafe { (obj.ptr).offset(i as isize) };
95        unsafe {
96            match (*obj).id {
97                0 => {
98                    s.push_str("Unit");
99                }
100                3 => {
101                    let value = (*obj).ptr as i32;
102                    s.push_str(&format!("{}", value));
103                }
104                4 => {
105                    let v = (*obj).ptr as i64;
106                    s.push_str(&format!("{}", v));
107                }
108                7 => {
109                    let s0 = CStr::from_ptr((*obj).ptr as *const c_char);
110                    s.push_str(s0.to_str().unwrap());
111                }
112                t => todo!("{t}"),
113            }
114        }
115    }
116    s.push('\0');
117    let s = s.leak();
118    s.as_ptr() as *mut c_char
119}
120
121pub extern "C" fn cmd(command: *mut c_char) {
122    let cmd = unsafe { CStr::from_ptr(command).to_str().unwrap() };
123    Command::new("powershell")
124        .arg("/C")
125        .arg(cmd)
126        .stdout(Stdio::inherit())
127        .stderr(Stdio::inherit())
128        .output()
129        .expect("Failed to execute command");
130}
131#[allow(unused)]
132pub extern "C" fn exit() {
133    std::process::exit(0);
134}
135#[allow(unused)]
136pub extern "C" fn get_env(key: *mut c_char) -> *mut c_char {
137    let key = unsafe { CStr::from_ptr(key).to_str().unwrap() };
138    let mut value = std::env::var(key).unwrap();
139    value.push('\0');
140    let value = value.leak();
141    value.as_ptr() as *mut c_char
142}
143#[allow(unused)]
144pub extern "C" fn set_env(key: *mut c_char, value: *mut c_char) {
145    let key = unsafe { CStr::from_ptr(key).to_str().unwrap() };
146    let value = unsafe { CStr::from_ptr(value).to_str().unwrap() };
147    std::env::set_var(key, value);
148}
149
150#[allow(unused)]
151pub extern "C" fn panic(ptr: *mut c_char) {
152    let s = unsafe { CStr::from_ptr(ptr).to_str().unwrap() };
153    eprintln!("\x1b[31mpanic: {}\x1b[0m", s);
154    std::process::exit(1);
155}
156
157#[no_mangle]
158pub extern "C" fn now() -> u64 {
159    SystemTime::now()
160        .duration_since(UNIX_EPOCH)
161        .unwrap_or_default() // 错误时返回0(例如系统时间早于Unix纪元)
162        .as_millis() as u64 // 转换为u64(C兼容)
163}
164
165// 定义一个类型安全的函数指针类型,用于C FFI
166pub type ExternFn = extern "C" fn();
167
168pub extern "C" fn spawn(func: ExternFn) {
169    // 在新线程中异步执行函数
170    thread::spawn(move || {
171        func();
172    });
173}
174
175pub extern "C" fn sleep(ms: u64) {
176    thread::sleep(Duration::from_millis(ms));
177}