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