polywrap_resolvers 0.1.6-beta.2

Uri resolvers to achieve uri resolution in Polywrap Client
Documentation
use core::fmt;
use std::sync::{Arc};

use polywrap_core::{
  resolvers::uri_resolution_context::{UriPackageOrWrapper, UriResolutionContext},
  uri::Uri,
  error::Error, package::WrapPackage, invoker::Invoker, 
};
use polywrap_msgpack::{msgpack, decode};
use polywrap_wasm::wasm_package::{WasmPackage};
use serde::{Serialize,Deserialize};

use polywrap_core::{resolvers::resolver_with_history::ResolverWithHistory, resolvers::helpers::UriResolverExtensionFileReader};

pub struct UriResolverWrapper {
  pub implementation_uri: Uri
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct MaybeUriOrManifest {
  pub uri: Option<String>,
  pub manifest: Option<Vec<u8>>,
}

impl UriResolverWrapper {
  pub fn new(implementation_uri: Uri) -> Self {
    UriResolverWrapper { implementation_uri }
  }

  fn try_resolve_uri_with_implementation(
    &self,
    uri: &Uri,
    implementation_uri: &Uri,
    invoker: &dyn Invoker,
    resolution_context: &mut UriResolutionContext
  ) -> Result<MaybeUriOrManifest, Error> {
      let result = invoker.invoke_raw(
          implementation_uri,
          "tryResolveUri", 
          Some(&msgpack!({
            "authority": uri.authority.as_str(),
            "path": uri.path.as_str(),
          })), 
          None, 
          Some(resolution_context)
      )?;

      if result.is_empty() {
        Ok(MaybeUriOrManifest {
          uri: None,
          manifest: None
        })
      } else {
        Ok(decode::<MaybeUriOrManifest>(result.as_slice())?)
      }
  }
}

impl ResolverWithHistory for UriResolverWrapper {
    fn _try_resolve_uri(
      &self, 
      uri: &Uri, 
      invoker: Arc<dyn Invoker>, 
      resolution_context: &mut UriResolutionContext
    ) ->  Result<UriPackageOrWrapper, Error> {
      let result = self.try_resolve_uri_with_implementation(
        uri, 
        &self.implementation_uri, 
        invoker.as_ref(), 
        resolution_context
      )?;
      let file_reader = UriResolverExtensionFileReader::new(
        self.implementation_uri.clone(),
        uri.clone(),
        invoker
      );

      if let Some(manifest) = result.manifest {
          let package = WasmPackage::new(
            Arc::new(file_reader),
            Some(manifest),
            None
          );
          let wrapper = package.create_wrapper()?;
          return Ok(UriPackageOrWrapper::Wrapper(uri.clone(), wrapper));
      }

      let package = WasmPackage::new(
        Arc::new(file_reader), None, None
      );

      if package.get_manifest(None).is_ok() {
        return Ok(
          UriPackageOrWrapper::Package(uri.clone(), 
          Arc::new(package))
        );
      }

      if let Some(uri) = result.uri {
          return Ok(UriPackageOrWrapper::Uri(uri.try_into()?));
      }

      Ok(UriPackageOrWrapper::Uri(uri.clone()))
    }

    fn get_step_description(&self, uri: &Uri) -> String {
      format!("UriResolverWrapper - Implementation called: {}", uri.clone().uri)
    }
}

impl fmt::Debug for UriResolverWrapper {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
      write!(f, "UriResolverWrapper: {:?}", self.implementation_uri)
  }
}