polywrap_core/resolution/
helpers.rs

1use 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        // TODO: This vec<u8> isn't the file but the msgpack representation of it
58        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                // TODO: Validate if implementation is already added
83                // or if the implementation uri has redirect
84                // by invoking loader.try_resolve_uri
85                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}