polywrap_resolvers/
resolver_with_loop_guard.rs1use core::fmt;
2use std::sync::{Arc, Mutex};
3
4use polywrap_core::{
5    error::Error,
6    invoker::Invoker,
7    resolution::{
8        uri_resolution_context::{UriPackageOrWrapper, UriResolutionContext},
9        uri_resolver::UriResolver,
10    },
11    uri::Uri,
12};
13
14pub struct ResolverWithLoopGuard {
15    pub resolver: Arc<dyn UriResolver>,
16}
17
18impl UriResolver for ResolverWithLoopGuard {
19    fn try_resolve_uri(
20        &self,
21        uri: &Uri,
22        invoker: Arc<dyn Invoker>,
23        resolution_context: Arc<Mutex<UriResolutionContext>>,
24    ) -> Result<UriPackageOrWrapper, Error> {
25        if resolution_context.lock().unwrap().is_resolving(uri) {
26            Err(Error::ResolverError("Infinite Loop".to_string()))
28        } else {
29            resolution_context.lock().unwrap().start_resolving(uri);
30
31            let result = self
32                .resolver
33                .try_resolve_uri(uri, invoker, resolution_context.clone());
34
35            resolution_context.lock().unwrap().stop_resolving(uri);
36
37            result
38        }
39    }
40}
41
42impl fmt::Debug for ResolverWithLoopGuard {
43    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
44        write!(f, "ResolverWithLoopGuard")
45    }
46}