rpkl_jdx/internal/msgapi/
outgoing.rs1use std::collections::HashMap;
2use crate::value::value::MapImpl;
3
4use crate::internal::msgapi::codes::*;
5use serde::Serialize;
6
7use crate::{
8 api::{
9 evaluator::CREATE_EVALUATOR_REQUEST_ID,
10 reader::{PklModuleReader, PklResourceReader},
11 },
12 internal::msgapi::impl_pkl_message,
13 EvaluatorOptions,
14};
15
16impl From<&dyn PklModuleReader> for ClientModuleReader {
17 fn from(reader: &dyn PklModuleReader) -> Self {
18 ClientModuleReader {
19 scheme: reader.scheme().to_string(),
20 has_hierarchical_uris: reader.has_hierarchical_uris(),
21 is_globbable: reader.is_globbable(),
22 is_local: reader.is_local(),
23 }
24 }
25}
26
27impl From<&dyn PklResourceReader> for ClientResourceReader {
28 fn from(reader: &dyn PklResourceReader) -> Self {
29 ClientResourceReader {
30 scheme: reader.scheme().to_string(),
31 has_hierarchical_uris: reader.has_hierarchical_uris(),
32 is_globbable: reader.is_globbable(),
33 }
34 }
35}
36
37#[derive(Serialize)]
38#[serde(rename_all = "camelCase")]
39pub(crate) struct CreateEvaluator<'a> {
40 pub request_id: u64,
41 pub allowed_modules: Vec<String>,
42 pub allowed_resources: Vec<String>,
43
44 #[serde(skip_serializing_if = "Option::is_none")]
45 pub client_module_readers: Option<Vec<ClientModuleReader>>,
46
47 #[serde(skip_serializing_if = "Option::is_none")]
48 pub client_resource_readers: Option<Vec<ClientResourceReader>>,
49
50 #[serde(skip_serializing_if = "Option::is_none")]
51 pub env: Option<HashMap<String, String>>,
52
53 #[serde(skip_serializing_if = "Option::is_none")]
54 pub properties: Option<&'a MapImpl<String, String>>,
55
56 #[serde(skip_serializing_if = "Option::is_none")]
57 pub external_resource_readers: Option<&'a HashMap<String, ExternalReader>>,
58 #[serde(skip_serializing_if = "Option::is_none")]
59 pub external_module_readers: Option<&'a HashMap<String, ExternalReader>>,
60}
61
62impl Default for CreateEvaluator<'_> {
63 fn default() -> Self {
64 let env_vars: HashMap<String, String> = std::env::vars().collect();
65 Self {
66 request_id: CREATE_EVALUATOR_REQUEST_ID,
67 allowed_modules: vec![
68 "pkl:".into(),
69 "repl:".into(),
70 "file:".into(),
71 "https:".into(),
72 "package:".into(),
73 ],
74 allowed_resources: vec![
75 "env:".into(),
76 "prop:".into(),
77 "package:".into(),
78 "https:".into(),
79 "projectpackage:".into(),
80 ],
81 env: Some(env_vars),
82
83 client_module_readers: None,
84 client_resource_readers: None,
85 properties: None,
86 external_resource_readers: None,
87 external_module_readers: None,
88 }
89 }
90}
91
92impl<'a> From<&'a EvaluatorOptions> for CreateEvaluator<'a> {
93 fn from(opts: &'a EvaluatorOptions) -> Self {
94 let mut evaluator_message = CreateEvaluator::default();
95
96 {
98 if let Some(props) = &opts.properties {
99 evaluator_message.properties = Some(props);
100 }
101
102 if let Some(readers) = opts.client_module_readers.as_ref() {
103 for reader in readers.iter() {
104 evaluator_message
105 .allowed_modules
106 .push(reader.scheme().to_string());
107 }
108 let module_readers: Vec<ClientModuleReader> = readers
109 .iter()
110 .map(|r: &Box<dyn PklModuleReader>| r.as_ref().into())
111 .collect();
112 evaluator_message.client_module_readers = Some(module_readers);
113 }
114
115 if let Some(readers) = opts.client_resource_readers.as_ref() {
116 for reader in readers.iter() {
117 evaluator_message
118 .allowed_resources
119 .push(reader.scheme().to_string());
120 }
121 let resource_readers: Vec<ClientResourceReader> =
122 readers.iter().map(|r| r.as_ref().into()).collect();
123 evaluator_message.client_resource_readers = Some(resource_readers);
124 }
125
126 if let Some(readers) = &opts.external_resource_readers {
127 for uri in readers.keys() {
128 evaluator_message.allowed_resources.push(uri.clone());
129 }
130
131 evaluator_message.external_resource_readers = Some(readers);
132 }
133
134 if let Some(readers) = &opts.external_module_readers {
135 for uri in readers.keys() {
136 evaluator_message.allowed_modules.push(uri.clone());
137 }
138 evaluator_message.external_module_readers = Some(readers);
139 }
140 }
141 evaluator_message
144 }
145}
146
147#[derive(Serialize)]
148#[serde(rename_all = "camelCase")]
149pub struct ClientModuleReader {
150 pub scheme: String,
151 pub has_hierarchical_uris: bool,
152 pub is_globbable: bool,
153 pub is_local: bool,
154}
155
156#[derive(Serialize)]
157#[serde(rename_all = "camelCase")]
158pub struct ClientResourceReader {
159 pub scheme: String,
161
162 pub has_hierarchical_uris: bool,
171
172 pub is_globbable: bool,
174}
175
176#[derive(Serialize)]
177#[serde(rename_all = "camelCase")]
178pub struct CloseEvaluator {
179 pub evaluator_id: i64,
180}
181
182#[derive(Serialize)]
183#[serde(rename_all = "camelCase")]
184pub struct EvaluateRequest {
185 pub request_id: u64,
186 pub evaluator_id: i64,
187 pub module_uri: String,
188}
189
190#[derive(Serialize)]
194#[serde(rename_all = "camelCase")]
195pub(crate) struct ReadResourceResponse {
196 pub request_id: i64,
198
199 pub evaluator_id: i64,
201
202 #[serde(skip_serializing_if = "Option::is_none")]
204 pub contents: Option<Vec<u8>>,
205
206 #[serde(skip_serializing_if = "Option::is_none")]
208 pub error: Option<String>,
209}
210
211#[derive(Serialize)]
215#[serde(rename_all = "camelCase")]
216pub(crate) struct ReadModuleResponse {
217 pub request_id: i64,
219
220 pub evaluator_id: i64,
222
223 #[serde(skip_serializing_if = "Option::is_none")]
225 pub contents: Option<String>,
226
227 #[serde(skip_serializing_if = "Option::is_none")]
229 pub error: Option<String>,
230}
231
232#[derive(Serialize)]
235#[serde(rename_all = "camelCase")]
236pub(crate) struct InitializeResourceReaderResponse {
237 pub request_id: i64,
239
240 #[serde(skip_serializing_if = "Option::is_none")]
247 pub spec: Option<ClientResourceReader>,
248}
249
250#[derive(Serialize)]
253#[serde(rename_all = "camelCase")]
254pub(crate) struct InitializeModuleReaderResponse {
255 pub request_id: i64,
257
258 #[serde(skip_serializing_if = "Option::is_none")]
265 pub spec: Option<ClientModuleReader>,
266}
267
268#[derive(Serialize)]
271#[serde(rename_all = "camelCase")]
272pub(crate) struct ListResourcesResponse {
273 pub request_id: i64,
275
276 pub evaluator_id: i64,
278
279 #[serde(skip_serializing_if = "Option::is_none")]
281 pub path_elements: Option<Vec<PathElements>>,
282
283 #[serde(skip_serializing_if = "Option::is_none")]
285 pub error: Option<String>,
286}
287
288#[derive(Serialize)]
291#[serde(rename_all = "camelCase")]
292pub(crate) struct ListModulesResponse {
293 pub request_id: i64,
295
296 pub evaluator_id: i64,
298
299 #[serde(skip_serializing_if = "Option::is_none")]
301 pub path_elements: Option<Vec<PathElements>>,
302
303 #[serde(skip_serializing_if = "Option::is_none")]
305 pub error: Option<String>,
306}
307
308#[derive(Serialize)]
309#[serde(rename_all = "camelCase")]
310pub struct PathElements {
311 pub name: String,
313
314 pub is_directory: bool,
316}
317
318#[derive(Serialize)]
319pub struct ExternalReader {
320 pub executable: String,
323
324 pub arguments: Vec<String>,
326}
327
328impl_pkl_message!(CreateEvaluator<'a>, CREATE_EVALUATOR);
329impl_pkl_message!(EvaluateRequest, EVALUATE_REQUEST);
330impl_pkl_message!(CloseEvaluator, CLOSE);
331
332impl_pkl_message!(
334 InitializeResourceReaderResponse,
335 INITIALIZE_RESOURCE_READER_RESPONSE
336);
337impl_pkl_message!(
338 InitializeModuleReaderResponse,
339 INITIALIZE_MODULE_READER_RESPONSE
340);
341impl_pkl_message!(ReadResourceResponse, READ_RESOURCE_RESPONSE);
342impl_pkl_message!(ReadModuleResponse, READ_MODULE_RESPONSE);
343impl_pkl_message!(ListResourcesResponse, LIST_RESOURCES_RESPONSE);
344impl_pkl_message!(ListModulesResponse, LIST_MODULES_RESPONSE);
345