intuicio_frontend_simpleton/library/
process.rs

1use crate::{Array, Integer, Map, Reference, Text};
2use intuicio_core::{registry::Registry, IntuicioStruct};
3use intuicio_derive::{intuicio_function, IntuicioStruct};
4use std::{
5    process::Command,
6    time::{SystemTime, UNIX_EPOCH},
7};
8
9#[derive(IntuicioStruct, Default)]
10#[intuicio(name = "CommandOutput", module_name = "process", override_send = true)]
11pub struct CommandOutput {
12    pub status: Reference,
13    pub stdout: Reference,
14    pub stderr: Reference,
15}
16
17#[intuicio_function(module_name = "process")]
18pub fn panic(message: Reference) -> Reference {
19    panic!("{}", message.read::<Text>().unwrap().as_str());
20}
21
22#[intuicio_function(module_name = "process", use_registry)]
23pub fn command(
24    registry: &Registry,
25    program: Reference,
26    args: Reference,
27    envs: Reference,
28) -> Reference {
29    let program = program.read::<Text>().unwrap();
30    let output = Command::new(program.as_str())
31        .args(
32            args.read::<Array>()
33                .unwrap()
34                .iter()
35                .map(|arg| arg.read::<Text>().unwrap().as_str().to_owned()),
36        )
37        .envs(envs.read::<Map>().unwrap().iter().map(|(key, value)| {
38            (
39                key.to_owned(),
40                value.read::<Text>().unwrap().as_str().to_owned(),
41            )
42        }))
43        .spawn()
44        .unwrap_or_else(|_| panic!("Could not run program: `{}`", program.as_str()))
45        .wait_with_output()
46        .unwrap_or_else(|_| panic!("Failed to wait for program: `{}`", program.as_str()));
47    let output = CommandOutput {
48        status: Reference::new_integer(output.status.code().unwrap_or(0) as Integer, registry),
49        stdout: Reference::new_text(
50            String::from_utf8_lossy(&output.stdout).to_string(),
51            registry,
52        ),
53        stderr: Reference::new_text(
54            String::from_utf8_lossy(&output.stderr).to_string(),
55            registry,
56        ),
57    };
58    Reference::new(output, registry)
59}
60
61#[intuicio_function(module_name = "process", use_registry)]
62pub fn current_time(registry: &Registry) -> Reference {
63    let start = SystemTime::now();
64    let since_the_epoch = start
65        .duration_since(UNIX_EPOCH)
66        .unwrap_or_else(|_| panic!("Time went backwards: {:?}", start));
67    Reference::new_real(since_the_epoch.as_secs_f64(), registry)
68}
69
70pub fn install(registry: &mut Registry) {
71    registry.add_type(CommandOutput::define_struct(registry));
72    registry.add_function(panic::define_function(registry));
73    registry.add_function(command::define_function(registry));
74    registry.add_function(current_time::define_function(registry));
75}