polywrap_core/resolution/
helpers.rs1use std::sync::Arc;
2
3use crate::{
4 client::CoreClient, error::Error, file_reader::FileReader,
5 interface_implementation::InterfaceImplementations, invoker::Invoker, uri::Uri,
6};
7use polywrap_msgpack_serde::to_vec;
8use serde::Serialize;
9use serde_bytes::ByteBuf;
10
11fn combine_paths(a: &str, b: &str) -> String {
12 let mut a = a.to_string();
13 let mut b = b.to_string();
14
15 a = a.replace('\\', "/");
16 b = b.replace('\\', "/");
17
18 if !a.ends_with('/') {
19 a.push('/');
20 };
21
22 while b.chars().rev().last().unwrap() == '/' || b.chars().rev().last().unwrap() == '.' {
23 b = b.split_off(1);
24 }
25
26 a.push_str(&b);
27
28 a
29}
30
31pub struct UriResolverExtensionFileReader {
32 pub resolver_extension_uri: Uri,
33 pub wrapper_uri: Uri,
34 invoker: Arc<dyn Invoker>,
35}
36
37impl UriResolverExtensionFileReader {
38 pub fn new(resolver_extension_uri: Uri, wrapper_uri: Uri, invoker: Arc<dyn Invoker>) -> Self {
39 UriResolverExtensionFileReader {
40 resolver_extension_uri,
41 wrapper_uri,
42 invoker,
43 }
44 }
45}
46
47#[derive(Serialize)]
48struct GetFileArgs {
49 path: String,
50}
51
52impl FileReader for UriResolverExtensionFileReader {
53 fn read_file(&self, file_path: &str) -> Result<Vec<u8>, Error> {
54 let path = combine_paths(&self.wrapper_uri.path(), file_path);
55 let args = GetFileArgs { path };
56 let invoker_args = to_vec(&args).unwrap();
57 let result = self.invoker.invoke_raw(
59 &self.resolver_extension_uri,
60 "getFile",
61 Some(&invoker_args),
62 None,
63 None,
64 )?;
65
66 let result: ByteBuf = polywrap_msgpack_serde::from_slice(&result)?;
67 Ok(result.into_vec())
68 }
69}
70
71pub fn get_implementations(
72 wrapper_uri: &Uri,
73 interfaces: Option<InterfaceImplementations>,
74 _: &dyn CoreClient,
75) -> Result<Vec<Uri>, Error> {
76 let mut implementation_uris: Vec<Uri> = vec![];
77
78 if let Some(interfaces) = interfaces {
79 let implementations_value = interfaces.get(&wrapper_uri);
80 if let Some(implementations) = implementations_value {
81 for implementation in implementations.iter() {
82 implementation_uris.push(implementation.clone());
86 }
87 }
88 }
89
90 Ok(implementation_uris)
91}
92
93pub fn get_env_from_resolution_path(
94 resolution_path: &[Uri],
95 client: &dyn CoreClient,
96) -> Option<Vec<u8>> {
97 for uri in resolution_path.iter() {
98 let env = client.get_env_by_uri(uri);
99
100 if env.is_some() {
101 return env;
102 }
103 }
104
105 None
106}