1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
use std::sync::Arc;

use crate::rcore::*;
use crate::rstd::{singular::*, *};

pub trait Inject<'a, Ctx: Context<'a>>: 'a + Send + Sync + Sized {
    fn inject<A: 'a + Send>(&self, fa: Wrapped<'a, Ctx, A>) -> Wrapped<'a, Ctx, A>;

    fn inject_mentionable<A: Mentionable<'a, Ctx>>(self: Arc<Self>, a: &A) -> ParseResultA<'a, A> {
        let factory = a.factory();
        let inject = self;
        let resolver = SingularResolver::from_mentionable(a).into_rc();
        let resolver = InjectedResolver { resolver, inject }.into_rc();
        let bytes = a.bytes();
        factory.parse_slice(&bytes, &resolver)
    }
}

struct InjectedResolver<'a, Ctx: Context<'a>, F: Inject<'a, Ctx>> {
    resolver: Arc<dyn Resolver<'a, Ctx>>,
    inject: Arc<F>,
}

impl<'a, Ctx: Context<'a>, F: Inject<'a, Ctx>> Resolver<'a, Ctx> for InjectedResolver<'a, Ctx, F> {
    fn resolve(self: Arc<Self>, address: Address) -> HashResolution<'a, Ctx> {
        let inject = self.inject.clone();
        self.inject.inject(
            self.resolver
                .clone()
                .resolve_map(address, |resolved| match resolved {
                    Ok((source, resolver)) => {
                        Ok((source, InjectedResolver { resolver, inject }.into_rc()))
                    }
                    Err(e) => Err(e),
                }),
        )
    }
}