use std::rc::Rc; use futures::future::join_all; use orchid_api_derive::{Coding, Hierarchy}; use orchid_base::{Receipt, ReqHandle, ReqHandleExt, Sym, es, sym}; use orchid_extension::gen_expr::new_atom; use orchid_extension::ParserObj; use orchid_extension::tree::{GenMember, merge_trivial}; use orchid_extension::{ AtomOps, AtomicFeatures, Expr, LexerObj, ReqForSystem, System, SystemCard, SystemCtor, ToExpr, }; use super::number::num_lib::gen_num_lib; use super::string::str_atom::{IntStrAtom, StrAtom}; use super::string::str_lib::gen_str_lib; use crate::std::binary::binary_atom::BlobAtom; use crate::std::binary::binary_lib::gen_binary_lib; use crate::std::boolean::gen_bool_lib; use crate::std::number::num_atom::{CreateFloat, CreateInt}; use crate::std::number::num_lexer::NumLexer; use crate::std::ops::gen_ops_lib; use crate::std::ops::subscript_lexer::SubscriptLexer; 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::{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::stream::stream_lib::gen_stream_lib; use crate::std::string::str_lexer::StringLexer; use crate::std::time::{CreateDT, gen_time_lib}; use crate::std::tuple::{CreateTuple, Tuple, TupleBuilder, gen_tuple_lib}; use crate::{Float, Int}; #[derive(Clone, Debug, Coding, Hierarchy)] #[extendable] #[allow(clippy::enum_variant_names, reason = "For the time being there are only ctor calls")] pub enum StdReq { CreateInt(CreateInt), CreateFloat(CreateFloat), CreateDT(CreateDT), CreateTag(CreateTag), CreateTuple(CreateTuple), CreateRecord(CreateRecord), CreateSymAtom(CreateSymAtom), } #[derive(Debug, Default)] pub struct StdSystem; impl SystemCtor for StdSystem { type Deps = (); type Card = Self; type Instance = Self; const NAME: &'static str = "orchid::std"; const VERSION: f64 = 0.00_01; fn inst(&self, _: ()) -> Self::Instance { Self } } impl SystemCard for StdSystem { type Ctor = Self; type Req = StdReq; fn atoms() -> impl IntoIterator>> { [ Some(BlobAtom::ops()), Some(Int::ops()), Some(Float::ops()), Some(StrAtom::ops()), Some(IntStrAtom::ops()), Some(OptAtom::ops()), Some(RecordAtom::ops()), Some(Tuple::ops()), Some(TupleBuilder::ops()), Some(Tag::ops()), Some(Tagged::ops()), ] } } impl System for StdSystem { type Ctor = Self; async fn request<'a>( &self, xreq: Box + 'a>, req: ReqForSystem, ) -> Receipt<'a> { match req { StdReq::CreateInt(ref req @ CreateInt(int)) => xreq.reply(req, &new_atom(int).to_expr().await.serialize().await).await.unwrap(), StdReq::CreateFloat(ref req @ CreateFloat(float)) => xreq.reply(req, &new_atom(float).to_expr().await.serialize().await).await.unwrap(), StdReq::CreateDT(ref req @ CreateDT(dt)) => xreq.reply(req, &new_atom(dt).to_expr().await.serialize().await).await.unwrap(), StdReq::CreateTuple(ref req @ CreateTuple(ref items)) => { let tpl = Tuple(Rc::new(join_all(items.iter().copied().map(Expr::deserialize)).await)); let tk = new_atom(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 = new_atom(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, &new_atom(sym_atom).to_expr().await.serialize().await).await.unwrap() }, StdReq::CreateTag(ref req @ CreateTag { name, ref impls }) => { let tag_atom = Tag { id: Sym::from_api(name).await, impls: Rc::new( join_all( (impls.iter()) .map(|(k, v)| async { (Sym::from_api(*k).await, Expr::deserialize(*v).await) }), ) .await .into_iter() .collect(), ), }; xreq.reply(req, &new_atom(tag_atom).to_expr().await.serialize().await).await.unwrap() }, } } fn lexers(&self) -> Vec { vec![&StringLexer, &NumLexer, &SubscriptLexer] } fn parsers(&self) -> Vec { vec![&AsTypeParser, &TypeParser, &AsProtoParser, &ProtoParser] } async fn env(&self) -> Vec { merge_trivial([ gen_bool_lib(), gen_num_lib(), gen_str_lib(), gen_option_lib(), gen_record_lib(), gen_tuple_lib(), gen_protocol_lib(), gen_sym_lib().await, gen_ops_lib(), gen_binary_lib(), gen_stream_lib(), gen_time_lib(), ]) } async fn prelude(&self) -> Vec { vec![sym!(std), sym!(std::tuple), sym!(std::option), sym!(std::record), sym!(std::string)] } }