use std::rc::Rc; use futures::future::{LocalBoxFuture, join_all, ready}; use itertools::Itertools; use orchid_base::interner::local_interner::{Int, StrBranch, StrvBranch}; use orchid_base::interner::{IStr, IStrv, InternerSrv}; use crate::api; use crate::entrypoint::{MUTE_REPLY, request}; #[derive(Default)] struct ExtInterner { str: Int, strv: Int, } impl InternerSrv for ExtInterner { fn is<'a>(&'a self, v: &'a str) -> LocalBoxFuture<'a, IStr> { match self.str.i(v) { Ok(i) => Box::pin(ready(i)), Err(e) => Box::pin(async { e.set_if_empty(MUTE_REPLY.scope((), request(api::InternStr(v.to_owned()))).await) }), } } fn es(&self, t: api::TStr) -> LocalBoxFuture<'_, IStr> { match self.str.e(t) { Ok(i) => Box::pin(ready(i)), Err(e) => Box::pin(async move { e.set_if_empty(Rc::new(request(api::ExternStr(t)).await)) }), } } fn iv<'a>(&'a self, v: &'a [IStr]) -> LocalBoxFuture<'a, IStrv> { match self.strv.i(v) { Ok(i) => Box::pin(ready(i)), Err(e) => Box::pin(async { e.set_if_empty(request(api::InternStrv(v.iter().map(|is| is.to_api()).collect_vec())).await) }), } } fn ev(&self, t: orchid_api::TStrv) -> LocalBoxFuture<'_, IStrv> { match self.strv.e(t) { Ok(i) => Box::pin(ready(i)), Err(e) => Box::pin(async move { let tstr_v = request(api::ExternStrv(t)).await; e.set_if_empty(Rc::new(join_all(tstr_v.into_iter().map(|t| self.es(t))).await)) }), } } } pub fn new_interner() -> Rc { Rc::::default() }