Skip to main content

memlink_runtime/resolver/
chain.rs

1//! Chain resolver for composite module resolution.
2
3use crate::error::{Error, Result};
4use crate::resolver::{ArtifactHandle, ModuleRef, ModuleResolver};
5
6pub struct ChainResolver {
7    resolvers: Vec<Box<dyn ModuleResolver>>,
8}
9
10impl ChainResolver {
11    pub fn new() -> Self {
12        ChainResolver {
13            resolvers: Vec::new(),
14        }
15    }
16
17    pub fn add<R: ModuleResolver + 'static>(&mut self, resolver: R) {
18        self.resolvers.push(Box::new(resolver));
19    }
20
21    pub fn len(&self) -> usize {
22        self.resolvers.len()
23    }
24
25    pub fn is_empty(&self) -> bool {
26        self.resolvers.is_empty()
27    }
28}
29
30impl Default for ChainResolver {
31    fn default() -> Self {
32        Self::new()
33    }
34}
35
36impl ModuleResolver for ChainResolver {
37    fn resolve(&self, reference: ModuleRef) -> Result<ArtifactHandle> {
38        if self.resolvers.is_empty() {
39            return Err(Error::NoResolverFound);
40        }
41
42        let mut last_error: Option<Error> = None;
43
44        for resolver in &self.resolvers {
45            match resolver.resolve(reference.clone()) {
46                Ok(handle) => return Ok(handle),
47                Err(Error::NotOurs) => {
48                    continue;
49                }
50                Err(e) => {
51                    last_error = Some(e);
52                }
53            }
54        }
55
56        Err(last_error.unwrap_or(Error::NoResolverFound))
57    }
58}