1use extism_pdk::*;
2use fluentci_types::{cache::Cache, envhub as types, file::File, service::Service};
3use serde::{Deserialize, Serialize};
4
5#[host_fn]
6extern "ExtismHost" {
7 fn set_runner(runner: String);
8 fn with_exec(args: Json<Vec<String>>);
9 fn with_workdir(path: String);
10 fn with_cache(cache: Json<Cache>);
11 fn with_file(file: Json<File>);
12 fn stdout() -> String;
13 fn stderr() -> String;
14 fn as_service(name: String) -> Json<Service>;
15 fn with_service(service_id: String);
16 fn set_envs(envs: Json<Vec<(String, String)>>);
17 fn wait_on(args: Json<Vec<u32>>);
18 fn with_secret_variable(params: Json<Vec<String>>);
19}
20
21#[derive(Serialize, Deserialize)]
22pub struct Envhub {
23 pub id: String,
24}
25
26impl From<types::Envhub> for Envhub {
27 fn from(envhub: types::Envhub) -> Self {
28 Envhub { id: envhub.id }
29 }
30}
31
32impl Envhub {
33 pub fn with_exec(&self, args: Vec<&str>) -> Result<Envhub, Error> {
34 unsafe { set_runner("envhub".into()) }?;
35 unsafe {
36 with_exec(Json::from(
37 args.into_iter()
38 .map(|x| x.to_string())
39 .collect::<Vec<String>>(),
40 ))
41 }?;
42 Ok(Envhub {
43 id: self.id.clone(),
44 })
45 }
46
47 pub fn with_file(&self, path: &str, file_id: &str) -> Result<Envhub, Error> {
48 unsafe {
49 with_file(Json(File {
50 id: file_id.into(),
51 path: path.into(),
52 }))
53 }?;
54 Ok(Envhub {
55 id: self.id.clone(),
56 })
57 }
58
59 pub fn with_workdir(&self, path: &str) -> Result<Envhub, Error> {
60 unsafe { with_workdir(path.into()) }?;
61 Ok(Envhub {
62 id: self.id.clone(),
63 })
64 }
65
66 pub fn with_cache(&self, path: &str, cache_id: &str) -> Result<Envhub, Error> {
67 unsafe {
68 with_cache(Json(Cache {
69 id: cache_id.into(),
70 path: path.into(),
71 ..Default::default()
72 }))
73 }?;
74 Ok(Envhub {
75 id: self.id.clone(),
76 })
77 }
78
79 pub fn stdout(&self) -> Result<String, Error> {
80 unsafe { stdout() }
81 }
82
83 pub fn stderr(&self) -> Result<String, Error> {
84 unsafe { stderr() }
85 }
86
87 pub fn as_service(&self, name: &str) -> Result<String, Error> {
88 let service = unsafe { as_service(name.into())? };
89 Ok(service.into_inner().id)
90 }
91
92 pub fn with_service(&self, service_id: &str) -> Result<Envhub, Error> {
93 unsafe { with_service(service_id.into())? }
94 Ok(Envhub {
95 id: self.id.clone(),
96 })
97 }
98
99 pub fn with_env_variable(&self, name: &str, value: &str) -> Result<Envhub, Error> {
100 unsafe { set_envs(Json(vec![(name.into(), value.into())]))? };
101 Ok(Envhub {
102 id: self.id.clone(),
103 })
104 }
105
106 pub fn wait_on(&self, port: u32, timeout: Option<u32>) -> Result<Envhub, Error> {
107 unsafe {
108 wait_on(Json(vec![port, timeout.unwrap_or(60)]))?;
109 }
110 Ok(Envhub {
111 id: self.id.clone(),
112 })
113 }
114
115 pub fn with_secret_variable(&self, name: &str, secret_id: &str) -> Result<Envhub, Error> {
116 unsafe {
117 with_secret_variable(Json(vec![name.into(), secret_id.into()]))?;
118 }
119 Ok(Envhub {
120 id: self.id.clone(),
121 })
122 }
123}