This commit is contained in:
@@ -5,11 +5,12 @@ use std::rc::Rc;
|
||||
use futures::AsyncWrite;
|
||||
use futures::future::join_all;
|
||||
use hashbrown::HashMap;
|
||||
use orchid_api_derive::Coding;
|
||||
use orchid_api_traits::{Encode, Request};
|
||||
use orchid_base::interner::{IStr, es};
|
||||
use orchid_base::name::Sym;
|
||||
use orchid_base::sym;
|
||||
use orchid_extension::atom::{Atomic, Supports};
|
||||
use orchid_extension::atom::{Atomic, MethodSetBuilder, Supports};
|
||||
use orchid_extension::atom_owned::{DeserializeCtx, OwnedAtom, OwnedVariant};
|
||||
use orchid_extension::expr::Expr;
|
||||
use orchid_extension::gen_expr::sym_ref;
|
||||
@@ -18,12 +19,15 @@ use crate::api;
|
||||
use crate::std::protocol::types::{GetImplMethod, GetTagIdMethod};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Record(pub Rc<HashMap<IStr, Expr>>);
|
||||
impl Atomic for Record {
|
||||
pub struct RecordAtom(pub Rc<HashMap<IStr, Expr>>);
|
||||
impl Atomic for RecordAtom {
|
||||
type Data = ();
|
||||
type Variant = OwnedVariant;
|
||||
fn reg_reqs() -> MethodSetBuilder<Self> {
|
||||
MethodSetBuilder::new().handle::<GetTagIdMethod>().handle::<GetImplMethod>()
|
||||
}
|
||||
}
|
||||
impl OwnedAtom for Record {
|
||||
impl OwnedAtom for RecordAtom {
|
||||
type Refs = Vec<Expr>;
|
||||
async fn serialize(&self, write: Pin<&mut (impl AsyncWrite + ?Sized)>) -> Self::Refs {
|
||||
let (keys, values) =
|
||||
@@ -34,17 +38,17 @@ impl OwnedAtom for Record {
|
||||
async fn deserialize(mut dctx: impl DeserializeCtx, refs: Self::Refs) -> Self {
|
||||
let keys =
|
||||
join_all(dctx.decode::<Vec<api::TStr>>().await.iter().map(|t| async { es(*t).await })).await;
|
||||
Record(Rc::new(keys.into_iter().zip(refs).collect()))
|
||||
RecordAtom(Rc::new(keys.into_iter().zip(refs).collect()))
|
||||
}
|
||||
|
||||
async fn val(&self) -> Cow<'_, Self::Data> { Cow::Owned(()) }
|
||||
}
|
||||
impl Supports<GetTagIdMethod> for Record {
|
||||
impl Supports<GetTagIdMethod> for RecordAtom {
|
||||
async fn handle(&self, _: GetTagIdMethod) -> <GetTagIdMethod as Request>::Response {
|
||||
Sym::literal("std::record::Record").await.to_api()
|
||||
}
|
||||
}
|
||||
impl Supports<GetImplMethod> for Record {
|
||||
impl Supports<GetImplMethod> for RecordAtom {
|
||||
async fn handle(&self, req: GetImplMethod) -> <GetImplMethod as Request>::Response {
|
||||
let name = Sym::from_api(req.0).await;
|
||||
let val = if name == sym!(std::ops::get) {
|
||||
@@ -57,3 +61,9 @@ impl Supports<GetImplMethod> for Record {
|
||||
Some(val.create().await.serialize().await)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Coding)]
|
||||
pub struct CreateRecord(pub std::collections::HashMap<api::TStr, api::ExprTicket>);
|
||||
impl Request for CreateRecord {
|
||||
type Response = api::ExprTicket;
|
||||
}
|
||||
|
||||
@@ -7,24 +7,24 @@ use orchid_extension::expr::Expr;
|
||||
use orchid_extension::tree::{GenMember, cnst, fun, prefix};
|
||||
|
||||
use crate::std::option::OrcOpt;
|
||||
use crate::std::record::record_atom::Record;
|
||||
use crate::std::record::record_atom::RecordAtom;
|
||||
use crate::std::string::str_atom::IntStrAtom;
|
||||
|
||||
pub fn gen_record_lib() -> Vec<GenMember> {
|
||||
prefix("std::record", [
|
||||
cnst(true, "empty", Record(Rc::new(HashMap::new()))),
|
||||
fun(true, "set", async |map: TAtom<Record>, key: IntStrAtom, val: Expr| {
|
||||
cnst(true, "empty", RecordAtom(Rc::new(HashMap::new()))),
|
||||
fun(true, "set", async |map: TAtom<RecordAtom>, key: IntStrAtom, val: Expr| {
|
||||
let mut map = own(&map).await.0.as_ref().clone();
|
||||
map.insert(key.0.clone(), val);
|
||||
Record(Rc::new(map))
|
||||
RecordAtom(Rc::new(map))
|
||||
}),
|
||||
fun(true, "get", async |map: TAtom<Record>, key: IntStrAtom| {
|
||||
fun(true, "get", async |map: TAtom<RecordAtom>, key: IntStrAtom| {
|
||||
OrcOpt(own(&map).await.0.get(&key.0).cloned())
|
||||
}),
|
||||
fun(true, "delete", async |map: TAtom<Record>, key: IntStrAtom| {
|
||||
fun(true, "delete", async |map: TAtom<RecordAtom>, key: IntStrAtom| {
|
||||
let mut map = own(&map).await.0.as_ref().clone();
|
||||
map.remove(&key.0);
|
||||
Record(Rc::new(map))
|
||||
RecordAtom(Rc::new(map))
|
||||
}),
|
||||
])
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ use std::rc::Rc;
|
||||
|
||||
use futures::future::join_all;
|
||||
use orchid_api_derive::{Coding, Hierarchy};
|
||||
use orchid_base::interner::es;
|
||||
use orchid_base::name::Sym;
|
||||
use orchid_base::reqnot::{Receipt, ReqHandle, ReqHandleExt};
|
||||
use orchid_base::sym;
|
||||
@@ -23,7 +24,7 @@ use crate::std::option::{OptAtom, gen_option_lib};
|
||||
use crate::std::protocol::proto_parser::{AsProtoParser, ProtoParser};
|
||||
use crate::std::protocol::type_parser::{AsTypeParser, TypeParser};
|
||||
use crate::std::protocol::types::{CreateTag, Tag, Tagged, gen_protocol_lib};
|
||||
use crate::std::record::record_atom::Record;
|
||||
use crate::std::record::record_atom::{CreateRecord, RecordAtom};
|
||||
use crate::std::record::record_lib::gen_record_lib;
|
||||
use crate::std::reflection::sym_atom::{CreateSymAtom, SymAtom, gen_sym_lib};
|
||||
use crate::std::string::str_lexer::StringLexer;
|
||||
@@ -36,6 +37,7 @@ use crate::{Float, Int};
|
||||
pub enum StdReq {
|
||||
CreateTag(CreateTag),
|
||||
CreateTuple(CreateTuple),
|
||||
CreateRecord(CreateRecord),
|
||||
CreateSymAtom(CreateSymAtom),
|
||||
}
|
||||
|
||||
@@ -58,7 +60,7 @@ impl SystemCard for StdSystem {
|
||||
Some(StrAtom::dynfo()),
|
||||
Some(IntStrAtom::dynfo()),
|
||||
Some(OptAtom::dynfo()),
|
||||
Some(Record::dynfo()),
|
||||
Some(RecordAtom::dynfo()),
|
||||
Some(Tuple::dynfo()),
|
||||
Some(TupleBuilder::dynfo()),
|
||||
Some(Tag::dynfo()),
|
||||
@@ -74,6 +76,14 @@ impl System for StdSystem {
|
||||
let tk = tpl.to_expr().await.serialize().await;
|
||||
xreq.reply(req, &tk).await.unwrap()
|
||||
},
|
||||
StdReq::CreateRecord(ref req @ CreateRecord(ref items)) => {
|
||||
let values =
|
||||
join_all(items.iter().map(async |(k, v)| (es(*k).await, Expr::deserialize(*v).await)))
|
||||
.await;
|
||||
let rec = RecordAtom(Rc::new(values.into_iter().collect()));
|
||||
let tk = rec.to_expr().await.serialize().await;
|
||||
xreq.reply(req, &tk).await.unwrap()
|
||||
},
|
||||
StdReq::CreateSymAtom(ref req @ CreateSymAtom(sym_tok)) => {
|
||||
let sym_atom = SymAtom(Sym::from_api(sym_tok).await);
|
||||
xreq.reply(req, &sym_atom.to_expr().await.serialize().await).await.unwrap()
|
||||
@@ -109,5 +119,7 @@ impl System for StdSystem {
|
||||
gen_ops_lib(),
|
||||
])
|
||||
}
|
||||
async fn prelude() -> Vec<Sym> { vec![sym!(std), sym!(std::tuple), sym!(std::option)] }
|
||||
async fn prelude() -> Vec<Sym> {
|
||||
vec![sym!(std), sym!(std::tuple), sym!(std::option), sym!(std::record)]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user