partway towards commands
I got very confused and started mucking about with "spawn" when in fact all I needed was the "inline" extension type in orcx that allows the interpreter to expose custom constants.
This commit is contained in:
@@ -6,40 +6,38 @@ use async_once_cell::OnceCell;
|
||||
use futures::future::LocalBoxFuture;
|
||||
use futures::{AsyncWrite, FutureExt};
|
||||
use orchid_api_traits::{Coding, enc_vec};
|
||||
use orchid_base::error::OrcRes;
|
||||
use orchid_base::format::FmtUnit;
|
||||
use orchid_base::logging::log;
|
||||
use orchid_base::name::Sym;
|
||||
use orchid_base::{FmtUnit, Sym, log};
|
||||
|
||||
use crate::api;
|
||||
use crate::atom::{
|
||||
AtomCard, AtomCtx, AtomDynfo, AtomFactory, Atomic, AtomicFeaturesImpl, AtomicVariant, MethodSet,
|
||||
MethodSetBuilder, err_not_callable, err_not_command, get_info,
|
||||
AtomCtx, AtomFactory, AtomOps, Atomic, AtomicFeaturesImpl, AtomicVariant, MethodSet,
|
||||
MethodSetBuilder, err_not_callable, err_not_command,
|
||||
};
|
||||
use crate::expr::Expr;
|
||||
use crate::gen_expr::{GExpr, bot};
|
||||
use crate::system::{cted, sys_id};
|
||||
use crate::system::{DynSystemCardExt, cted};
|
||||
use crate::{CmdResult, api};
|
||||
|
||||
/// Value of [Atomic::Variant] for a type that implements [ThinAtom]
|
||||
pub struct ThinVariant;
|
||||
impl AtomicVariant for ThinVariant {}
|
||||
impl<A: ThinAtom + Atomic<Variant = ThinVariant>> AtomicFeaturesImpl<ThinVariant> for A {
|
||||
fn _factory(self) -> AtomFactory {
|
||||
AtomFactory::new(async move || {
|
||||
let (id, _) = get_info::<A>(cted().inst().card());
|
||||
let (id, _) = cted().inst().card().ops::<A>();
|
||||
let mut buf = enc_vec(&id);
|
||||
self.encode_vec(&mut buf);
|
||||
api::Atom { drop: None, data: api::AtomData(buf), owner: sys_id() }
|
||||
api::LocalAtom { drop: None, data: api::AtomData(buf) }
|
||||
})
|
||||
}
|
||||
fn _info() -> Self::_Info { ThinAtomDynfo { msbuild: Self::reg_reqs(), ms: OnceCell::new() } }
|
||||
type _Info = ThinAtomDynfo<Self>;
|
||||
fn _info() -> Self::_Info { ThinAtomOps { msbuild: Self::reg_methods(), ms: OnceCell::new() } }
|
||||
type _Info = ThinAtomOps<Self>;
|
||||
}
|
||||
|
||||
pub struct ThinAtomDynfo<T: ThinAtom> {
|
||||
pub(crate) struct ThinAtomOps<T: ThinAtom> {
|
||||
msbuild: MethodSetBuilder<T>,
|
||||
ms: OnceCell<MethodSet<T>>,
|
||||
}
|
||||
impl<T: ThinAtom> AtomDynfo for ThinAtomDynfo<T> {
|
||||
impl<T: ThinAtom> AtomOps for ThinAtomOps<T> {
|
||||
fn print<'a>(&self, AtomCtx(buf, _): AtomCtx<'a>) -> LocalBoxFuture<'a, FmtUnit> {
|
||||
Box::pin(async move { T::decode_slice(&mut &buf[..]).print().await })
|
||||
}
|
||||
@@ -58,17 +56,14 @@ impl<T: ThinAtom> AtomDynfo for ThinAtomDynfo<T> {
|
||||
&'a self,
|
||||
AtomCtx(buf, ..): AtomCtx<'a>,
|
||||
key: Sym,
|
||||
req: Box<dyn orchid_base::reqnot::ReqReader<'a> + 'a>,
|
||||
req: Box<dyn orchid_base::ReqReader<'a> + 'a>,
|
||||
) -> LocalBoxFuture<'a, bool> {
|
||||
Box::pin(async move {
|
||||
let ms = self.ms.get_or_init(self.msbuild.pack()).await;
|
||||
ms.dispatch(&T::decode_slice(&mut &buf[..]), key, req).await
|
||||
})
|
||||
}
|
||||
fn command<'a>(
|
||||
&'a self,
|
||||
AtomCtx(buf, _): AtomCtx<'a>,
|
||||
) -> LocalBoxFuture<'a, OrcRes<Option<GExpr>>> {
|
||||
fn command<'a>(&'a self, AtomCtx(buf, _): AtomCtx<'a>) -> LocalBoxFuture<'a, CmdResult> {
|
||||
async move { T::decode_slice(&mut &buf[..]).command().await }.boxed_local()
|
||||
}
|
||||
fn serialize<'a, 'b: 'a>(
|
||||
@@ -81,7 +76,11 @@ impl<T: ThinAtom> AtomDynfo for ThinAtomDynfo<T> {
|
||||
Some(Vec::new())
|
||||
})
|
||||
}
|
||||
fn deserialize<'a>(&'a self, data: &'a [u8], refs: &'a [Expr]) -> LocalBoxFuture<'a, api::Atom> {
|
||||
fn deserialize<'a>(
|
||||
&'a self,
|
||||
data: &'a [u8],
|
||||
refs: &'a [Expr],
|
||||
) -> LocalBoxFuture<'a, api::LocalAtom> {
|
||||
assert!(refs.is_empty(), "Refs found when deserializing thin atom");
|
||||
Box::pin(async { T::decode_slice(&mut &data[..])._factory().build().await })
|
||||
}
|
||||
@@ -93,16 +92,15 @@ impl<T: ThinAtom> AtomDynfo for ThinAtomDynfo<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ThinAtom:
|
||||
AtomCard<Data = Self> + Atomic<Variant = ThinVariant> + Coding + Send + Sync + 'static
|
||||
{
|
||||
/// A simple value that is serializable and does not reference any other values
|
||||
pub trait ThinAtom: Atomic<Data = Self> + Atomic<Variant = ThinVariant> + Coding + 'static {
|
||||
#[allow(unused_variables)]
|
||||
fn call(&self, arg: Expr) -> impl Future<Output = GExpr> {
|
||||
async move { bot(err_not_callable(&self.print().await).await) }
|
||||
}
|
||||
#[allow(unused_variables)]
|
||||
fn command(&self) -> impl Future<Output = OrcRes<Option<GExpr>>> {
|
||||
async move { Err(err_not_command(&self.print().await).await) }
|
||||
fn command(&self) -> impl Future<Output = CmdResult> {
|
||||
async move { Err(err_not_command(&self.print().await).await.into()) }
|
||||
}
|
||||
#[allow(unused_variables)]
|
||||
fn print(&self) -> impl Future<Output = FmtUnit> {
|
||||
|
||||
Reference in New Issue
Block a user