forked from Orchid/orchid
updated all deps
migrated away from paste and async-std
This commit is contained in:
538
Cargo.lock
generated
538
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -10,5 +10,6 @@ members = [
|
||||
"orchid-api",
|
||||
"orchid-api-derive",
|
||||
"orchid-api-traits",
|
||||
"stdio-perftest", "xtask", "orchid-macros",
|
||||
"stdio-perftest",
|
||||
"xtask",
|
||||
]
|
||||
|
||||
@@ -9,9 +9,9 @@ proc-macro = true
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
quote = "1.0.38"
|
||||
syn = { version = "2.0.95" }
|
||||
quote = "1.0.40"
|
||||
syn = { version = "2.0.106" }
|
||||
orchid-api-traits = { version = "0.1.0", path = "../orchid-api-traits" }
|
||||
proc-macro2 = "1.0.92"
|
||||
darling = "0.20.10"
|
||||
proc-macro2 = "1.0.101"
|
||||
darling = "0.21.3"
|
||||
itertools = "0.14.0"
|
||||
|
||||
@@ -12,7 +12,7 @@ pub fn derive(input: TokenStream) -> TokenStream {
|
||||
let decode = decode_body(&input.data);
|
||||
let expanded = quote! {
|
||||
impl #impl_generics orchid_api_traits::Decode for #name #ty_generics #where_clause {
|
||||
async fn decode<R: orchid_api_traits::async_std::io::Read + ?Sized>(
|
||||
async fn decode<R: orchid_api_traits::AsyncRead + ?Sized>(
|
||||
mut read: std::pin::Pin<&mut R>
|
||||
) -> Self {
|
||||
#decode
|
||||
|
||||
@@ -14,7 +14,7 @@ pub fn derive(input: TokenStream) -> TokenStream {
|
||||
let encode = encode_body(&input.data);
|
||||
let expanded = quote! {
|
||||
impl #e_impl_generics orchid_api_traits::Encode for #name #e_ty_generics #e_where_clause {
|
||||
async fn encode<W: orchid_api_traits::async_std::io::Write + ?Sized>(
|
||||
async fn encode<W: orchid_api_traits::AsyncWrite + ?Sized>(
|
||||
&self,
|
||||
mut write: std::pin::Pin<&mut W>
|
||||
) {
|
||||
|
||||
@@ -6,9 +6,8 @@ edition = "2024"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
async-std = "1.13.0"
|
||||
async-stream = "0.3.6"
|
||||
futures = "0.3.31"
|
||||
futures = { version = "0.3.31", features = ["std"] }
|
||||
itertools = "0.14.0"
|
||||
never = "0.1.0"
|
||||
ordered-float = "5.0.0"
|
||||
|
||||
@@ -7,9 +7,8 @@ use std::pin::Pin;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_std::io::{Read, ReadExt, Write, WriteExt};
|
||||
use async_stream::stream;
|
||||
use futures::StreamExt;
|
||||
use futures::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, StreamExt};
|
||||
use never::Never;
|
||||
use ordered_float::NotNan;
|
||||
|
||||
@@ -18,16 +17,16 @@ use crate::encode_enum;
|
||||
pub trait Decode: 'static {
|
||||
/// Decode an instance from the beginning of the buffer. Return the decoded
|
||||
/// data and the remaining buffer.
|
||||
fn decode<R: Read + ?Sized>(read: Pin<&mut R>) -> impl Future<Output = Self> + '_;
|
||||
fn decode<R: AsyncRead + ?Sized>(read: Pin<&mut R>) -> impl Future<Output = Self> + '_;
|
||||
}
|
||||
pub trait Encode {
|
||||
/// Append an instance of the struct to the buffer
|
||||
fn encode<W: Write + ?Sized>(&self, write: Pin<&mut W>) -> impl Future<Output = ()>;
|
||||
fn encode<W: AsyncWrite + ?Sized>(&self, write: Pin<&mut W>) -> impl Future<Output = ()>;
|
||||
}
|
||||
pub trait Coding: Encode + Decode + Clone {
|
||||
fn get_decoder<T: 'static, F: Future<Output = T> + 'static>(
|
||||
map: impl Fn(Self) -> F + Clone + 'static,
|
||||
) -> impl AsyncFn(Pin<&mut dyn Read>) -> T {
|
||||
) -> impl AsyncFn(Pin<&mut dyn AsyncRead>) -> T {
|
||||
async move |r| map(Self::decode(r).await).await
|
||||
}
|
||||
}
|
||||
@@ -36,14 +35,14 @@ impl<T: Encode + Decode + Clone> Coding for T {}
|
||||
macro_rules! num_impl {
|
||||
($number:ty) => {
|
||||
impl Decode for $number {
|
||||
async fn decode<R: Read + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
async fn decode<R: AsyncRead + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
let mut bytes = [0u8; (<$number>::BITS / 8) as usize];
|
||||
read.read_exact(&mut bytes).await.unwrap();
|
||||
<$number>::from_be_bytes(bytes)
|
||||
}
|
||||
}
|
||||
impl Encode for $number {
|
||||
async fn encode<W: Write + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
async fn encode<W: AsyncWrite + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
write.write_all(&self.to_be_bytes()).await.expect("Could not write number")
|
||||
}
|
||||
}
|
||||
@@ -63,12 +62,12 @@ num_impl!(i8);
|
||||
macro_rules! nonzero_impl {
|
||||
($name:ty) => {
|
||||
impl Decode for NonZero<$name> {
|
||||
async fn decode<R: Read + ?Sized>(read: Pin<&mut R>) -> Self {
|
||||
async fn decode<R: AsyncRead + ?Sized>(read: Pin<&mut R>) -> Self {
|
||||
Self::new(<$name as Decode>::decode(read).await).unwrap()
|
||||
}
|
||||
}
|
||||
impl Encode for NonZero<$name> {
|
||||
async fn encode<W: Write + ?Sized>(&self, write: Pin<&mut W>) {
|
||||
async fn encode<W: AsyncWrite + ?Sized>(&self, write: Pin<&mut W>) {
|
||||
self.get().encode(write).await
|
||||
}
|
||||
}
|
||||
@@ -87,19 +86,21 @@ nonzero_impl!(i64);
|
||||
nonzero_impl!(i128);
|
||||
|
||||
impl<T: Encode + ?Sized> Encode for &T {
|
||||
async fn encode<W: Write + ?Sized>(&self, write: Pin<&mut W>) { (**self).encode(write).await }
|
||||
async fn encode<W: AsyncWrite + ?Sized>(&self, write: Pin<&mut W>) {
|
||||
(**self).encode(write).await
|
||||
}
|
||||
}
|
||||
macro_rules! float_impl {
|
||||
($t:ty, $size:expr) => {
|
||||
impl Decode for NotNan<$t> {
|
||||
async fn decode<R: Read + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
async fn decode<R: AsyncRead + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
let mut bytes = [0u8; $size];
|
||||
read.read_exact(&mut bytes).await.unwrap();
|
||||
NotNan::new(<$t>::from_be_bytes(bytes)).expect("Float was NaN")
|
||||
}
|
||||
}
|
||||
impl Encode for NotNan<$t> {
|
||||
async fn encode<W: Write + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
async fn encode<W: AsyncWrite + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
write.write_all(&self.as_ref().to_be_bytes()).await.expect("Could not write number")
|
||||
}
|
||||
}
|
||||
@@ -110,7 +111,7 @@ float_impl!(f64, 8);
|
||||
float_impl!(f32, 4);
|
||||
|
||||
impl Decode for String {
|
||||
async fn decode<R: Read + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
async fn decode<R: AsyncRead + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
let len = u64::decode(read.as_mut()).await.try_into().unwrap();
|
||||
let mut data = vec![0u8; len];
|
||||
read.read_exact(&mut data).await.unwrap();
|
||||
@@ -118,30 +119,30 @@ impl Decode for String {
|
||||
}
|
||||
}
|
||||
impl Encode for String {
|
||||
async fn encode<W: Write + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
async fn encode<W: AsyncWrite + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
u64::try_from(self.len()).unwrap().encode(write.as_mut()).await;
|
||||
write.write_all(self.as_bytes()).await.unwrap()
|
||||
}
|
||||
}
|
||||
impl Encode for str {
|
||||
async fn encode<W: Write + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
async fn encode<W: AsyncWrite + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
u64::try_from(self.len()).unwrap().encode(write.as_mut()).await;
|
||||
write.write_all(self.as_bytes()).await.unwrap()
|
||||
}
|
||||
}
|
||||
impl<T: Decode> Decode for Vec<T> {
|
||||
async fn decode<R: Read + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
async fn decode<R: AsyncRead + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
let len = u64::decode(read.as_mut()).await.try_into().unwrap();
|
||||
stream! { loop { yield T::decode(read.as_mut()).await } }.take(len).collect().await
|
||||
}
|
||||
}
|
||||
impl<T: Encode> Encode for Vec<T> {
|
||||
async fn encode<W: Write + ?Sized>(&self, write: Pin<&mut W>) {
|
||||
async fn encode<W: AsyncWrite + ?Sized>(&self, write: Pin<&mut W>) {
|
||||
self.as_slice().encode(write).await
|
||||
}
|
||||
}
|
||||
impl<T: Encode> Encode for [T] {
|
||||
async fn encode<W: Write + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
async fn encode<W: AsyncWrite + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
u64::try_from(self.len()).unwrap().encode(write.as_mut()).await;
|
||||
for t in self.iter() {
|
||||
t.encode(write.as_mut()).await
|
||||
@@ -149,7 +150,7 @@ impl<T: Encode> Encode for [T] {
|
||||
}
|
||||
}
|
||||
impl<T: Decode> Decode for Option<T> {
|
||||
async fn decode<R: Read + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
async fn decode<R: AsyncRead + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
match u8::decode(read.as_mut()).await {
|
||||
0 => None,
|
||||
1 => Some(T::decode(read).await),
|
||||
@@ -158,14 +159,14 @@ impl<T: Decode> Decode for Option<T> {
|
||||
}
|
||||
}
|
||||
impl<T: Encode> Encode for Option<T> {
|
||||
async fn encode<W: Write + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
async fn encode<W: AsyncWrite + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
let t = if let Some(t) = self { t } else { return 0u8.encode(write.as_mut()).await };
|
||||
1u8.encode(write.as_mut()).await;
|
||||
t.encode(write).await;
|
||||
}
|
||||
}
|
||||
impl<T: Decode, E: Decode> Decode for Result<T, E> {
|
||||
async fn decode<R: Read + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
async fn decode<R: AsyncRead + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
match u8::decode(read.as_mut()).await {
|
||||
0 => Self::Ok(T::decode(read).await),
|
||||
1 => Self::Err(E::decode(read).await),
|
||||
@@ -175,7 +176,7 @@ impl<T: Decode, E: Decode> Decode for Result<T, E> {
|
||||
}
|
||||
|
||||
impl<T: Encode, E: Encode> Encode for Result<T, E> {
|
||||
async fn encode<W: Write + ?Sized>(&self, write: Pin<&mut W>) {
|
||||
async fn encode<W: AsyncWrite + ?Sized>(&self, write: Pin<&mut W>) {
|
||||
match self {
|
||||
Ok(t) => encode_enum(write, 0, |w| t.encode(w)).await,
|
||||
Err(e) => encode_enum(write, 1, |w| e.encode(w)).await,
|
||||
@@ -183,13 +184,13 @@ impl<T: Encode, E: Encode> Encode for Result<T, E> {
|
||||
}
|
||||
}
|
||||
impl<K: Decode + Eq + Hash, V: Decode> Decode for HashMap<K, V> {
|
||||
async fn decode<R: Read + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
async fn decode<R: AsyncRead + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
let len = u64::decode(read.as_mut()).await.try_into().unwrap();
|
||||
stream! { loop { yield <(K, V)>::decode(read.as_mut()).await } }.take(len).collect().await
|
||||
}
|
||||
}
|
||||
impl<K: Encode + Eq + Hash, V: Encode> Encode for HashMap<K, V> {
|
||||
async fn encode<W: Write + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
async fn encode<W: AsyncWrite + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
u64::try_from(self.len()).unwrap().encode(write.as_mut()).await;
|
||||
for pair in self.iter() {
|
||||
pair.encode(write.as_mut()).await
|
||||
@@ -199,12 +200,12 @@ impl<K: Encode + Eq + Hash, V: Encode> Encode for HashMap<K, V> {
|
||||
macro_rules! tuple {
|
||||
(($($t:ident)*) ($($T:ident)*)) => {
|
||||
impl<$($T: Decode),*> Decode for ($($T,)*) {
|
||||
async fn decode<R: Read + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
async fn decode<R: AsyncRead + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
($($T::decode(read.as_mut()).await,)*)
|
||||
}
|
||||
}
|
||||
impl<$($T: Encode),*> Encode for ($($T,)*) {
|
||||
async fn encode<W: Write + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
async fn encode<W: AsyncWrite + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
let ($($t,)*) = self;
|
||||
$( $t.encode(write.as_mut()).await; )*
|
||||
}
|
||||
@@ -230,33 +231,33 @@ tuple!((t u v x y z a b c d e f g h i) (T U V X Y Z A B C D E F G H I));
|
||||
tuple!((t u v x y z a b c d e f g h i j) (T U V X Y Z A B C D E F G H I J)); // 16
|
||||
|
||||
impl Decode for () {
|
||||
async fn decode<R: Read + ?Sized>(_: Pin<&mut R>) -> Self {}
|
||||
async fn decode<R: AsyncRead + ?Sized>(_: Pin<&mut R>) -> Self {}
|
||||
}
|
||||
impl Encode for () {
|
||||
async fn encode<W: Write + ?Sized>(&self, _: Pin<&mut W>) {}
|
||||
async fn encode<W: AsyncWrite + ?Sized>(&self, _: Pin<&mut W>) {}
|
||||
}
|
||||
impl Decode for Never {
|
||||
async fn decode<R: Read + ?Sized>(_: Pin<&mut R>) -> Self {
|
||||
async fn decode<R: AsyncRead + ?Sized>(_: Pin<&mut R>) -> Self {
|
||||
unreachable!("A value of Never cannot exist so it can't have been serialized");
|
||||
}
|
||||
}
|
||||
impl Encode for Never {
|
||||
async fn encode<W: Write + ?Sized>(&self, _: Pin<&mut W>) { match *self {} }
|
||||
async fn encode<W: AsyncWrite + ?Sized>(&self, _: Pin<&mut W>) { match *self {} }
|
||||
}
|
||||
impl Decode for bool {
|
||||
async fn decode<R: Read + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
async fn decode<R: AsyncRead + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
let mut buf = [0];
|
||||
read.read_exact(&mut buf).await.unwrap();
|
||||
buf[0] != 0
|
||||
}
|
||||
}
|
||||
impl Encode for bool {
|
||||
async fn encode<W: Write + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
async fn encode<W: AsyncWrite + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
write.write_all(&[if *self { 0xffu8 } else { 0u8 }]).await.unwrap()
|
||||
}
|
||||
}
|
||||
impl<T: Decode, const N: usize> Decode for [T; N] {
|
||||
async fn decode<R: Read + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
async fn decode<R: AsyncRead + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
// TODO: figure out how to do this in safe rust on the stack
|
||||
let v =
|
||||
stream! { loop { yield T::decode(read.as_mut()).await } }.take(N).collect::<Vec<_>>().await;
|
||||
@@ -264,7 +265,7 @@ impl<T: Decode, const N: usize> Decode for [T; N] {
|
||||
}
|
||||
}
|
||||
impl<T: Encode, const N: usize> Encode for [T; N] {
|
||||
async fn encode<W: Write + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
async fn encode<W: AsyncWrite + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
for t in self.iter() {
|
||||
t.encode(write.as_mut()).await
|
||||
}
|
||||
@@ -274,12 +275,12 @@ impl<T: Encode, const N: usize> Encode for [T; N] {
|
||||
macro_rules! two_end_range {
|
||||
($this:ident, $name:tt, $op:tt, $start:expr, $end:expr) => {
|
||||
impl<T: Decode> Decode for $name<T> {
|
||||
async fn decode<R: Read + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
async fn decode<R: AsyncRead + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
T::decode(read.as_mut()).await $op T::decode(read).await
|
||||
}
|
||||
}
|
||||
impl<T: Encode> Encode for $name<T> {
|
||||
async fn encode<W: Write + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
async fn encode<W: AsyncWrite + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
let $this = self;
|
||||
($start).encode(write.as_mut()).await;
|
||||
($end).encode(write).await;
|
||||
@@ -294,12 +295,14 @@ two_end_range!(x, RangeInclusive, ..=, x.start(), x.end());
|
||||
macro_rules! smart_ptr {
|
||||
($name:tt) => {
|
||||
impl<T: Decode> Decode for $name<T> {
|
||||
async fn decode<R: Read + ?Sized>(read: Pin<&mut R>) -> Self {
|
||||
async fn decode<R: AsyncRead + ?Sized>(read: Pin<&mut R>) -> Self {
|
||||
$name::new(T::decode(read).await)
|
||||
}
|
||||
}
|
||||
impl<T: Encode> Encode for $name<T> {
|
||||
async fn encode<W: Write + ?Sized>(&self, write: Pin<&mut W>) { (**self).encode(write).await }
|
||||
async fn encode<W: AsyncWrite + ?Sized>(&self, write: Pin<&mut W>) {
|
||||
(**self).encode(write).await
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -309,12 +312,12 @@ smart_ptr!(Rc);
|
||||
smart_ptr!(Box);
|
||||
|
||||
impl Decode for char {
|
||||
async fn decode<R: Read + ?Sized>(read: Pin<&mut R>) -> Self {
|
||||
async fn decode<R: AsyncRead + ?Sized>(read: Pin<&mut R>) -> Self {
|
||||
char::from_u32(u32::decode(read).await).unwrap()
|
||||
}
|
||||
}
|
||||
impl Encode for char {
|
||||
async fn encode<W: Write + ?Sized>(&self, write: Pin<&mut W>) {
|
||||
async fn encode<W: AsyncWrite + ?Sized>(&self, write: Pin<&mut W>) {
|
||||
(*self as u32).encode(write).await
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
|
||||
use async_std::io::{Read, ReadExt, Write, WriteExt};
|
||||
use futures::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
|
||||
use itertools::{Chunk, Itertools};
|
||||
|
||||
use crate::Encode;
|
||||
|
||||
pub async fn encode_enum<'a, W: Write + ?Sized, F: Future<Output = ()>>(
|
||||
pub async fn encode_enum<'a, W: AsyncWrite + ?Sized, F: Future<Output = ()>>(
|
||||
mut write: Pin<&'a mut W>,
|
||||
id: u8,
|
||||
f: impl FnOnce(Pin<&'a mut W>) -> F,
|
||||
@@ -15,7 +15,7 @@ pub async fn encode_enum<'a, W: Write + ?Sized, F: Future<Output = ()>>(
|
||||
f(write).await
|
||||
}
|
||||
|
||||
pub async fn write_exact<W: Write + ?Sized>(mut write: Pin<&mut W>, bytes: &'static [u8]) {
|
||||
pub async fn write_exact<W: AsyncWrite + ?Sized>(mut write: Pin<&mut W>, bytes: &'static [u8]) {
|
||||
write.write_all(bytes).await.expect("Failed to write exact bytes")
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ pub fn print_bytes(b: &[u8]) -> String {
|
||||
.join(" ")
|
||||
}
|
||||
|
||||
pub async fn read_exact<R: Read + ?Sized>(mut read: Pin<&mut R>, bytes: &'static [u8]) {
|
||||
pub async fn read_exact<R: AsyncRead + ?Sized>(mut read: Pin<&mut R>, bytes: &'static [u8]) {
|
||||
let mut data = vec![0u8; bytes.len()];
|
||||
read.read_exact(&mut data).await.expect("Failed to read bytes");
|
||||
if data != bytes {
|
||||
|
||||
@@ -3,8 +3,8 @@ mod helpers;
|
||||
mod hierarchy;
|
||||
mod relations;
|
||||
|
||||
pub use async_std;
|
||||
pub use coding::*;
|
||||
pub use futures::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
|
||||
pub use helpers::*;
|
||||
pub use hierarchy::*;
|
||||
pub use relations::*;
|
||||
|
||||
@@ -9,7 +9,7 @@ edition = "2024"
|
||||
ordered-float = "5.0.0"
|
||||
orchid-api-traits = { version = "0.1.0", path = "../orchid-api-traits" }
|
||||
orchid-api-derive = { version = "0.1.0", path = "../orchid-api-derive" }
|
||||
async-std = "1.13.0"
|
||||
futures = { version = "0.3.31", features = ["std"] }
|
||||
|
||||
[dev-dependencies]
|
||||
test_executors = "0.3.2"
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
use std::pin::Pin;
|
||||
|
||||
use async_std::io::{Read, Write};
|
||||
use futures::{AsyncRead, AsyncWrite};
|
||||
use orchid_api_derive::{Coding, Hierarchy};
|
||||
use orchid_api_traits::{Channel, Decode, Encode, MsgSet, Request, read_exact, write_exact};
|
||||
|
||||
@@ -36,7 +36,7 @@ pub struct HostHeader {
|
||||
pub msg_logs: logging::LogStrategy,
|
||||
}
|
||||
impl Decode for HostHeader {
|
||||
async fn decode<R: Read + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
async fn decode<R: AsyncRead + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
read_exact(read.as_mut(), HOST_INTRO).await;
|
||||
Self {
|
||||
log_strategy: logging::LogStrategy::decode(read.as_mut()).await,
|
||||
@@ -45,7 +45,7 @@ impl Decode for HostHeader {
|
||||
}
|
||||
}
|
||||
impl Encode for HostHeader {
|
||||
async fn encode<W: Write + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
async fn encode<W: AsyncWrite + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
write_exact(write.as_mut(), HOST_INTRO).await;
|
||||
self.log_strategy.encode(write.as_mut()).await;
|
||||
self.msg_logs.encode(write.as_mut()).await
|
||||
@@ -58,13 +58,13 @@ pub struct ExtensionHeader {
|
||||
pub systems: Vec<system::SystemDecl>,
|
||||
}
|
||||
impl Decode for ExtensionHeader {
|
||||
async fn decode<R: Read + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
async fn decode<R: AsyncRead + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
read_exact(read.as_mut(), EXT_INTRO).await;
|
||||
Self { name: String::decode(read.as_mut()).await, systems: Vec::decode(read).await }
|
||||
}
|
||||
}
|
||||
impl Encode for ExtensionHeader {
|
||||
async fn encode<W: Write + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
async fn encode<W: AsyncWrite + ?Sized>(&self, mut write: Pin<&mut W>) {
|
||||
write_exact(write.as_mut(), EXT_INTRO).await;
|
||||
self.name.encode(write.as_mut()).await;
|
||||
self.systems.encode(write).await
|
||||
|
||||
@@ -7,12 +7,11 @@ edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
async-once-cell = "0.5.4"
|
||||
async-std = "1.13.0"
|
||||
async-stream = "0.3.6"
|
||||
derive_destructure = "1.0.0"
|
||||
dyn-clone = "1.0.17"
|
||||
futures = "0.3.31"
|
||||
hashbrown = "0.15.2"
|
||||
dyn-clone = "1.0.20"
|
||||
futures = { version = "0.3.31", features = ["std"] }
|
||||
hashbrown = "0.16.0"
|
||||
itertools = "0.14.0"
|
||||
lazy_static = "1.5.0"
|
||||
never = "0.1.0"
|
||||
@@ -21,9 +20,9 @@ orchid-api = { version = "0.1.0", path = "../orchid-api" }
|
||||
orchid-api-derive = { version = "0.1.0", path = "../orchid-api-derive" }
|
||||
orchid-api-traits = { version = "0.1.0", path = "../orchid-api-traits" }
|
||||
ordered-float = "5.0.0"
|
||||
regex = "1.11.1"
|
||||
rust-embed = "8.5.0"
|
||||
some_executor = "0.4.0"
|
||||
regex = "1.11.2"
|
||||
rust-embed = "8.7.2"
|
||||
some_executor = "0.6.1"
|
||||
substack = "1.1.1"
|
||||
test_executors = "0.3.2"
|
||||
test_executors = "0.3.5"
|
||||
trait-set = "0.3.0"
|
||||
|
||||
@@ -209,7 +209,7 @@ pub fn mk_errv<I: Into<ErrPos>>(
|
||||
}
|
||||
|
||||
pub async fn async_io_err<I: Into<ErrPos>>(
|
||||
err: async_std::io::Error,
|
||||
err: std::io::Error,
|
||||
i: &Interner,
|
||||
posv: impl IntoIterator<Item = I>,
|
||||
) -> OrcErrv {
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::rc::Rc;
|
||||
use std::sync::atomic;
|
||||
use std::{fmt, hash};
|
||||
|
||||
use async_std::sync::Mutex;
|
||||
use futures::lock::Mutex;
|
||||
use hashbrown::{HashMap, HashSet};
|
||||
use itertools::Itertools as _;
|
||||
use orchid_api_traits::Request;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use std::io;
|
||||
use std::pin::Pin;
|
||||
|
||||
use async_std::io::{Read, ReadExt, Write, WriteExt};
|
||||
use futures::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
|
||||
use orchid_api_traits::{Decode, Encode};
|
||||
|
||||
pub async fn send_msg(mut write: Pin<&mut impl Write>, msg: &[u8]) -> io::Result<()> {
|
||||
pub async fn send_msg(mut write: Pin<&mut impl AsyncWrite>, msg: &[u8]) -> io::Result<()> {
|
||||
let mut len_buf = vec![];
|
||||
u32::try_from(msg.len()).unwrap().encode(Pin::new(&mut len_buf)).await;
|
||||
write.write_all(&len_buf).await?;
|
||||
@@ -12,7 +12,7 @@ pub async fn send_msg(mut write: Pin<&mut impl Write>, msg: &[u8]) -> io::Result
|
||||
write.flush().await
|
||||
}
|
||||
|
||||
pub async fn recv_msg(mut read: Pin<&mut impl Read>) -> io::Result<Vec<u8>> {
|
||||
pub async fn recv_msg(mut read: Pin<&mut impl AsyncRead>) -> io::Result<Vec<u8>> {
|
||||
let mut len_buf = [0u8; (u32::BITS / 8) as usize];
|
||||
read.read_exact(&mut len_buf).await?;
|
||||
let len = u32::decode(Pin::new(&mut &len_buf[..])).await;
|
||||
|
||||
@@ -8,11 +8,12 @@ use std::pin::Pin;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
use async_std::channel;
|
||||
use async_std::sync::Mutex;
|
||||
use derive_destructure::destructure;
|
||||
use dyn_clone::{DynClone, clone_box};
|
||||
use futures::channel::mpsc;
|
||||
use futures::future::LocalBoxFuture;
|
||||
use futures::lock::Mutex;
|
||||
use futures::{SinkExt, StreamExt};
|
||||
use hashbrown::HashMap;
|
||||
use orchid_api_traits::{Channel, Coding, Decode, Encode, MsgSet, Request};
|
||||
use trait_set::trait_set;
|
||||
@@ -102,7 +103,7 @@ pub struct ReqNotData<T: MsgSet> {
|
||||
send: Box<dyn SendFn<T>>,
|
||||
notif: Box<dyn NotifFn<T>>,
|
||||
req: Box<dyn ReqFn<T>>,
|
||||
responses: HashMap<u64, channel::Sender<Vec<u8>>>,
|
||||
responses: HashMap<u64, mpsc::Sender<Vec<u8>>>,
|
||||
}
|
||||
|
||||
/// Wraps a raw message buffer to save on copying.
|
||||
@@ -144,7 +145,7 @@ impl<T: MsgSet> ReqNot<T> {
|
||||
let notif_val = <T::In as Channel>::Notif::decode(Pin::new(&mut &payload[..])).await;
|
||||
notif_cb(notif_val, self.clone()).await
|
||||
} else if 0 < id.bitand(1 << 63) {
|
||||
let sender = g.responses.remove(&!id).expect("Received response for invalid message");
|
||||
let mut sender = g.responses.remove(&!id).expect("Received response for invalid message");
|
||||
sender.send(message.to_vec()).await.unwrap()
|
||||
} else {
|
||||
let message = <T::In as Channel>::Req::decode(Pin::new(&mut &payload[..])).await;
|
||||
@@ -205,13 +206,13 @@ impl<T: MsgSet> DynRequester for ReqNot<T> {
|
||||
g.id += 1;
|
||||
let mut buf = id.to_be_bytes().to_vec();
|
||||
req.encode(Pin::new(&mut buf)).await;
|
||||
let (send, recv) = channel::bounded(1);
|
||||
let (send, mut recv) = mpsc::channel(1);
|
||||
g.responses.insert(id, send);
|
||||
let mut send = clone_box(&*g.send);
|
||||
mem::drop(g);
|
||||
let rn = self.clone();
|
||||
send(&buf, rn).await;
|
||||
let items = recv.recv().await;
|
||||
let items = recv.next().await;
|
||||
RawReply(items.unwrap())
|
||||
})
|
||||
}
|
||||
@@ -249,8 +250,8 @@ mod test {
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_std::sync::Mutex;
|
||||
use futures::FutureExt;
|
||||
use futures::lock::Mutex;
|
||||
use orchid_api::LogStrategy;
|
||||
use orchid_api_derive::Coding;
|
||||
use orchid_api_traits::{Channel, Request};
|
||||
|
||||
@@ -6,28 +6,33 @@ edition = "2024"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
ahash = "0.8.11"
|
||||
ahash = "0.8.12"
|
||||
async-lock = "3.4.1"
|
||||
async-once-cell = "0.5.4"
|
||||
async-std = "1.13.0"
|
||||
async-stream = "0.3.6"
|
||||
derive_destructure = "1.0.0"
|
||||
dyn-clone = "1.0.17"
|
||||
futures = "0.3.31"
|
||||
hashbrown = "0.15.2"
|
||||
dyn-clone = "1.0.20"
|
||||
futures = { version = "0.3.31", features = ["std"] }
|
||||
hashbrown = "0.16.0"
|
||||
include_dir = { version = "0.7.4", optional = true }
|
||||
itertools = "0.14.0"
|
||||
konst = "0.3.16"
|
||||
konst = "0.4.1"
|
||||
lazy_static = "1.5.0"
|
||||
memo-map = "0.3.3"
|
||||
never = "0.1.0"
|
||||
once_cell = "1.20.2"
|
||||
once_cell = "1.21.3"
|
||||
orchid-api = { version = "0.1.0", path = "../orchid-api" }
|
||||
orchid-api-derive = { version = "0.1.0", path = "../orchid-api-derive" }
|
||||
orchid-api-traits = { version = "0.1.0", path = "../orchid-api-traits" }
|
||||
orchid-base = { version = "0.1.0", path = "../orchid-base" }
|
||||
ordered-float = "5.0.0"
|
||||
pastey = "0.1.0"
|
||||
some_executor = "0.5.1"
|
||||
pastey = "0.1.1"
|
||||
some_executor = "0.6.1"
|
||||
substack = "1.1.1"
|
||||
tokio = { version = "1.46.1", optional = true }
|
||||
tokio = { version = "1.47.1", optional = true }
|
||||
tokio-util = { version = "0.7.16", optional = true, features = ["compat"] }
|
||||
|
||||
trait-set = "0.3.0"
|
||||
|
||||
[features]
|
||||
tokio = ["dep:tokio", "dep:tokio-util"]
|
||||
|
||||
@@ -7,11 +7,9 @@ use std::pin::Pin;
|
||||
use std::rc::Rc;
|
||||
|
||||
use ahash::HashMap;
|
||||
use async_std::io::{Read, Write};
|
||||
use async_std::stream;
|
||||
use dyn_clone::{DynClone, clone_box};
|
||||
use futures::future::LocalBoxFuture;
|
||||
use futures::{FutureExt, StreamExt};
|
||||
use futures::{AsyncRead, AsyncWrite, FutureExt, StreamExt, stream};
|
||||
use orchid_api_derive::Coding;
|
||||
use orchid_api_traits::{Coding, Decode, Encode, Request, enc_vec};
|
||||
use orchid_base::clone;
|
||||
@@ -157,8 +155,8 @@ trait_set! {
|
||||
trait AtomReqCb<A> = for<'a> Fn(
|
||||
&'a A,
|
||||
SysCtx,
|
||||
Pin<&'a mut dyn Read>,
|
||||
Pin<&'a mut dyn Write>,
|
||||
Pin<&'a mut dyn AsyncRead>,
|
||||
Pin<&'a mut dyn AsyncWrite>,
|
||||
) -> LocalBoxFuture<'a, ()>
|
||||
}
|
||||
|
||||
@@ -173,17 +171,19 @@ impl<A: AtomCard> MethodSetBuilder<A> {
|
||||
assert!(!M::NAME.is_empty(), "AtomMethod::NAME cannoot be empty");
|
||||
self.handlers.push((
|
||||
M::NAME,
|
||||
Rc::new(move |a: &A, ctx: SysCtx, req: Pin<&mut dyn Read>, rep: Pin<&mut dyn Write>| {
|
||||
Rc::new(
|
||||
move |a: &A, ctx: SysCtx, req: Pin<&mut dyn AsyncRead>, rep: Pin<&mut dyn AsyncWrite>| {
|
||||
async { Supports::<M>::handle(a, ctx, M::decode(req).await).await.encode(rep).await }
|
||||
.boxed_local()
|
||||
}),
|
||||
},
|
||||
),
|
||||
));
|
||||
self
|
||||
}
|
||||
|
||||
pub async fn pack(&self, ctx: SysCtx) -> MethodSet<A> {
|
||||
MethodSet {
|
||||
handlers: stream::from_iter(self.handlers.iter())
|
||||
handlers: stream::iter(self.handlers.iter())
|
||||
.then(|(k, v)| {
|
||||
clone!(ctx; async move {
|
||||
(Sym::parse(k, ctx.i()).await.unwrap(), v.clone())
|
||||
@@ -204,8 +204,8 @@ impl<A: AtomCard> MethodSet<A> {
|
||||
atom: &'a A,
|
||||
ctx: SysCtx,
|
||||
key: Sym,
|
||||
req: Pin<&'a mut dyn Read>,
|
||||
rep: Pin<&'a mut dyn Write>,
|
||||
req: Pin<&'a mut dyn AsyncRead>,
|
||||
rep: Pin<&'a mut dyn AsyncWrite>,
|
||||
) -> bool {
|
||||
match self.handlers.get(&key) {
|
||||
None => false,
|
||||
@@ -286,14 +286,14 @@ pub trait AtomDynfo: 'static {
|
||||
&'a self,
|
||||
ctx: AtomCtx<'a>,
|
||||
key: Sym,
|
||||
req: Pin<&'b mut dyn Read>,
|
||||
rep: Pin<&'c mut dyn Write>,
|
||||
req: Pin<&'b mut dyn AsyncRead>,
|
||||
rep: Pin<&'c mut dyn AsyncWrite>,
|
||||
) -> LocalBoxFuture<'a, bool>;
|
||||
fn command<'a>(&'a self, ctx: AtomCtx<'a>) -> LocalBoxFuture<'a, OrcRes<Option<GExpr>>>;
|
||||
fn serialize<'a, 'b: 'a>(
|
||||
&'a self,
|
||||
ctx: AtomCtx<'a>,
|
||||
write: Pin<&'b mut dyn Write>,
|
||||
write: Pin<&'b mut dyn AsyncWrite>,
|
||||
) -> LocalBoxFuture<'a, Option<Vec<Expr>>>;
|
||||
fn deserialize<'a>(
|
||||
&'a self,
|
||||
|
||||
@@ -6,11 +6,10 @@ use std::ops::Deref;
|
||||
use std::pin::Pin;
|
||||
use std::sync::atomic::AtomicU64;
|
||||
|
||||
use async_lock::{RwLock, RwLockReadGuard};
|
||||
use async_once_cell::OnceCell;
|
||||
use async_std::io::{Read, Write};
|
||||
use async_std::sync::{RwLock, RwLockReadGuard};
|
||||
use futures::FutureExt;
|
||||
use futures::future::{LocalBoxFuture, ready};
|
||||
use futures::{AsyncRead, AsyncWrite, FutureExt};
|
||||
use itertools::Itertools;
|
||||
use memo_map::MemoMap;
|
||||
use never::Never;
|
||||
@@ -105,8 +104,8 @@ impl<T: OwnedAtom> AtomDynfo for OwnedAtomDynfo<T> {
|
||||
&'a self,
|
||||
AtomCtx(_, id, ctx): AtomCtx,
|
||||
key: Sym,
|
||||
req: Pin<&'b mut dyn Read>,
|
||||
rep: Pin<&'c mut dyn Write>,
|
||||
req: Pin<&'b mut dyn AsyncRead>,
|
||||
rep: Pin<&'c mut dyn AsyncWrite>,
|
||||
) -> LocalBoxFuture<'a, bool> {
|
||||
Box::pin(async move {
|
||||
let a = AtomReadGuard::new(id.unwrap(), &ctx).await;
|
||||
@@ -126,7 +125,7 @@ impl<T: OwnedAtom> AtomDynfo for OwnedAtomDynfo<T> {
|
||||
fn serialize<'a, 'b: 'a>(
|
||||
&'a self,
|
||||
AtomCtx(_, id, ctx): AtomCtx<'a>,
|
||||
mut write: Pin<&'b mut dyn Write>,
|
||||
mut write: Pin<&'b mut dyn AsyncWrite>,
|
||||
) -> LocalBoxFuture<'a, Option<Vec<Expr>>> {
|
||||
Box::pin(async move {
|
||||
let id = id.unwrap();
|
||||
@@ -241,7 +240,7 @@ pub trait OwnedAtom: Atomic<Variant = OwnedVariant> + Any + Clone + 'static {
|
||||
fn serialize(
|
||||
&self,
|
||||
ctx: SysCtx,
|
||||
write: Pin<&mut (impl Write + ?Sized)>,
|
||||
write: Pin<&mut (impl AsyncWrite + ?Sized)>,
|
||||
) -> impl Future<Output = Self::Refs> {
|
||||
assert_serializable::<Self>();
|
||||
async { panic!("Either implement serialize or set Refs to Never for {}", type_name::<Self>()) }
|
||||
@@ -263,7 +262,7 @@ fn assert_serializable<T: OwnedAtom>() {
|
||||
pub trait DynOwnedAtom: 'static {
|
||||
fn atom_tid(&self) -> TypeId;
|
||||
fn as_any_ref(&self) -> &dyn Any;
|
||||
fn encode<'a>(&'a self, buffer: Pin<&'a mut dyn Write>) -> LocalBoxFuture<'a, ()>;
|
||||
fn encode<'a>(&'a self, buffer: Pin<&'a mut dyn AsyncWrite>) -> LocalBoxFuture<'a, ()>;
|
||||
fn dyn_call_ref(&self, arg: Expr) -> LocalBoxFuture<'_, GExpr>;
|
||||
fn dyn_call(self: Box<Self>, arg: Expr) -> LocalBoxFuture<'static, GExpr>;
|
||||
fn dyn_command(self: Box<Self>, ctx: SysCtx) -> LocalBoxFuture<'static, OrcRes<Option<GExpr>>>;
|
||||
@@ -272,13 +271,13 @@ pub trait DynOwnedAtom: 'static {
|
||||
fn dyn_serialize<'a>(
|
||||
&'a self,
|
||||
ctx: SysCtx,
|
||||
sink: Pin<&'a mut dyn Write>,
|
||||
sink: Pin<&'a mut dyn AsyncWrite>,
|
||||
) -> LocalBoxFuture<'a, Option<Vec<Expr>>>;
|
||||
}
|
||||
impl<T: OwnedAtom> DynOwnedAtom for T {
|
||||
fn atom_tid(&self) -> TypeId { TypeId::of::<T>() }
|
||||
fn as_any_ref(&self) -> &dyn Any { self }
|
||||
fn encode<'a>(&'a self, buffer: Pin<&'a mut dyn Write>) -> LocalBoxFuture<'a, ()> {
|
||||
fn encode<'a>(&'a self, buffer: Pin<&'a mut dyn AsyncWrite>) -> LocalBoxFuture<'a, ()> {
|
||||
async { self.val().await.as_ref().encode(buffer).await }.boxed_local()
|
||||
}
|
||||
fn dyn_call_ref(&self, arg: Expr) -> LocalBoxFuture<'_, GExpr> {
|
||||
@@ -299,7 +298,7 @@ impl<T: OwnedAtom> DynOwnedAtom for T {
|
||||
fn dyn_serialize<'a>(
|
||||
&'a self,
|
||||
ctx: SysCtx,
|
||||
sink: Pin<&'a mut dyn Write>,
|
||||
sink: Pin<&'a mut dyn AsyncWrite>,
|
||||
) -> LocalBoxFuture<'a, Option<Vec<Expr>>> {
|
||||
match TypeId::of::<Never>() == TypeId::of::<<Self as OwnedAtom>::Refs>() {
|
||||
true => ready(None).boxed_local(),
|
||||
|
||||
@@ -3,9 +3,8 @@ use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
|
||||
use async_once_cell::OnceCell;
|
||||
use async_std::io::{Read, Write};
|
||||
use futures::FutureExt;
|
||||
use futures::future::LocalBoxFuture;
|
||||
use futures::{AsyncRead, AsyncWrite, FutureExt};
|
||||
use orchid_api_traits::{Coding, enc_vec};
|
||||
use orchid_base::error::OrcRes;
|
||||
use orchid_base::format::FmtUnit;
|
||||
@@ -59,8 +58,8 @@ impl<T: ThinAtom> AtomDynfo for ThinAtomDynfo<T> {
|
||||
&'a self,
|
||||
AtomCtx(buf, _, sys): AtomCtx<'a>,
|
||||
key: Sym,
|
||||
req: Pin<&'m1 mut dyn Read>,
|
||||
rep: Pin<&'m2 mut dyn Write>,
|
||||
req: Pin<&'m1 mut dyn AsyncRead>,
|
||||
rep: Pin<&'m2 mut dyn AsyncWrite>,
|
||||
) -> LocalBoxFuture<'a, bool> {
|
||||
Box::pin(async move {
|
||||
let ms = self.ms.get_or_init(self.msbuild.pack(sys.clone())).await;
|
||||
@@ -76,7 +75,7 @@ impl<T: ThinAtom> AtomDynfo for ThinAtomDynfo<T> {
|
||||
fn serialize<'a, 'b: 'a>(
|
||||
&'a self,
|
||||
ctx: AtomCtx<'a>,
|
||||
write: Pin<&'b mut dyn Write>,
|
||||
write: Pin<&'b mut dyn AsyncWrite>,
|
||||
) -> LocalBoxFuture<'a, Option<Vec<Expr>>> {
|
||||
Box::pin(async {
|
||||
T::decode(Pin::new(&mut &ctx.0[..])).await.encode(write).await;
|
||||
|
||||
@@ -3,10 +3,10 @@ use std::marker::PhantomData;
|
||||
use std::pin::Pin;
|
||||
use std::rc::Rc;
|
||||
|
||||
use async_std::channel::{Receiver, RecvError, Sender, bounded};
|
||||
use async_std::sync::Mutex;
|
||||
use futures::channel::mpsc::{Receiver, Sender, channel};
|
||||
use futures::future::Fuse;
|
||||
use futures::{FutureExt, select};
|
||||
use futures::lock::Mutex;
|
||||
use futures::{FutureExt, SinkExt, StreamExt, select};
|
||||
use never::Never;
|
||||
use orchid_base::error::OrcRes;
|
||||
|
||||
@@ -22,20 +22,20 @@ enum Command {
|
||||
}
|
||||
|
||||
struct BuilderCoroutineData {
|
||||
work: Mutex<Fuse<Pin<Box<dyn Future<Output = GExpr>>>>>,
|
||||
work: Fuse<Pin<Box<dyn Future<Output = GExpr>>>>,
|
||||
cmd_recv: Receiver<Command>,
|
||||
}
|
||||
#[derive(Clone)]
|
||||
struct BuilderCoroutine(Rc<BuilderCoroutineData>);
|
||||
struct BuilderCoroutine(Rc<Mutex<BuilderCoroutineData>>);
|
||||
impl BuilderCoroutine {
|
||||
pub async fn run(self) -> GExpr {
|
||||
let cmd = {
|
||||
let mut work = self.0.work.lock().await;
|
||||
let this = &mut *self.0.lock().await;
|
||||
select! {
|
||||
ret_val = &mut *work => { return ret_val },
|
||||
cmd_res = self.0.cmd_recv.recv().fuse() => match cmd_res {
|
||||
Ok(cmd) => cmd,
|
||||
Err(RecvError) => return (&mut *work).await
|
||||
ret_val = &mut this.work => { return ret_val },
|
||||
cmd_res = this.cmd_recv.next().fuse() => match cmd_res {
|
||||
Some(cmd) => cmd,
|
||||
None => return (&mut this.work).await
|
||||
},
|
||||
}
|
||||
};
|
||||
@@ -65,17 +65,17 @@ impl Atomic for Replier {
|
||||
impl OwnedAtom for Replier {
|
||||
type Refs = Never;
|
||||
async fn val(&self) -> Cow<'_, Self::Data> { Cow::Owned(()) }
|
||||
async fn call(self, arg: Expr) -> GExpr {
|
||||
async fn call(mut self, arg: Expr) -> GExpr {
|
||||
let _ = self.reply.send(arg).await;
|
||||
self.builder.run().await
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn exec<R: ToExpr>(f: impl for<'a> AsyncFnOnce(ExecHandle<'a>) -> R + 'static) -> GExpr {
|
||||
let (cmd_snd, cmd_recv) = bounded(1);
|
||||
let (cmd_snd, cmd_recv) = channel(0);
|
||||
let work =
|
||||
async { f(ExecHandle(cmd_snd, PhantomData)).await.to_expr().await }.boxed_local().fuse();
|
||||
let coro = BuilderCoroutine(Rc::new(BuilderCoroutineData { cmd_recv, work: Mutex::new(work) }));
|
||||
let coro = BuilderCoroutine(Rc::new(Mutex::new(BuilderCoroutineData { cmd_recv, work })));
|
||||
coro.run().await
|
||||
}
|
||||
|
||||
@@ -84,13 +84,13 @@ static WEIRD_DROP_ERR: &str = "Coroutine dropped while we are being polled someh
|
||||
pub struct ExecHandle<'a>(Sender<Command>, PhantomData<&'a ()>);
|
||||
impl ExecHandle<'_> {
|
||||
pub async fn exec<T: TryFromExpr>(&mut self, val: impl ToExpr) -> OrcRes<T> {
|
||||
let (reply_snd, reply_recv) = bounded(1);
|
||||
let (reply_snd, mut reply_recv) = channel(0);
|
||||
self.0.send(Command::Execute(val.to_expr().await, reply_snd)).await.expect(WEIRD_DROP_ERR);
|
||||
T::try_from_expr(reply_recv.recv().await.expect(WEIRD_DROP_ERR)).await
|
||||
T::try_from_expr(reply_recv.next().await.expect(WEIRD_DROP_ERR)).await
|
||||
}
|
||||
pub async fn register(&mut self, val: impl ToExpr) -> Expr {
|
||||
let (reply_snd, reply_recv) = bounded(1);
|
||||
let (reply_snd, mut reply_recv) = channel(0);
|
||||
self.0.send(Command::Register(val.to_expr().await, reply_snd)).await.expect(WEIRD_DROP_ERR);
|
||||
reply_recv.recv().await.expect(WEIRD_DROP_ERR)
|
||||
reply_recv.next().await.expect(WEIRD_DROP_ERR)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,11 +5,10 @@ use std::num::NonZero;
|
||||
use std::pin::Pin;
|
||||
use std::rc::Rc;
|
||||
|
||||
use async_std::channel::{self, Receiver, Sender};
|
||||
use async_std::stream;
|
||||
use async_std::sync::Mutex;
|
||||
use futures::channel::mpsc::{Receiver, Sender, channel};
|
||||
use futures::future::{LocalBoxFuture, join_all};
|
||||
use futures::{FutureExt, StreamExt, stream_select};
|
||||
use futures::lock::Mutex;
|
||||
use futures::{FutureExt, SinkExt, StreamExt, stream, stream_select};
|
||||
use hashbrown::HashMap;
|
||||
use itertools::Itertools;
|
||||
use orchid_api::{ExtMsgSet, IntReq};
|
||||
@@ -85,16 +84,16 @@ pub async fn with_atom_record<'a, F: Future<Output = SysCtx>, T>(
|
||||
pub struct ExtensionOwner {
|
||||
_interner_cell: Rc<RefCell<Option<Interner>>>,
|
||||
_systems_lock: Rc<Mutex<HashMap<api::SysId, SystemRecord>>>,
|
||||
out_recv: Receiver<Vec<u8>>,
|
||||
out_recv: Mutex<Receiver<Vec<u8>>>,
|
||||
out_send: Sender<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl ExtPort for ExtensionOwner {
|
||||
fn send<'a>(&'a self, msg: &'a [u8]) -> LocalBoxFuture<'a, ()> {
|
||||
Box::pin(async { self.out_send.send(msg.to_vec()).boxed_local().await.unwrap() })
|
||||
Box::pin(async { self.out_send.clone().send(msg.to_vec()).boxed_local().await.unwrap() })
|
||||
}
|
||||
fn recv(&self) -> LocalBoxFuture<'_, Option<Vec<u8>>> {
|
||||
Box::pin(async { (self.out_recv.recv().await).ok() })
|
||||
Box::pin(async { self.out_recv.lock().await.next().await })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,9 +109,9 @@ pub fn extension_init(
|
||||
.collect_vec();
|
||||
let systems_lock = Rc::new(Mutex::new(HashMap::<api::SysId, SystemRecord>::new()));
|
||||
let ext_header = api::ExtensionHeader { name: data.name.to_string(), systems: decls.clone() };
|
||||
let (out_send, in_recv) = channel::bounded::<Vec<u8>>(1);
|
||||
let (in_send, out_recv) = channel::bounded::<Vec<u8>>(1);
|
||||
let (exit_send, exit_recv) = channel::bounded(1);
|
||||
let (out_send, in_recv) = channel::<Vec<u8>>(1);
|
||||
let (in_send, out_recv) = channel::<Vec<u8>>(1);
|
||||
let (exit_send, exit_recv) = channel(1);
|
||||
let logger = Logger::new(log_strategy);
|
||||
let msg_logger = Logger::new(msg_logs);
|
||||
let interner_cell = Rc::new(RefCell::new(None::<Interner>));
|
||||
@@ -136,9 +135,15 @@ pub fn extension_init(
|
||||
};
|
||||
let rn = ReqNot::<api::ExtMsgSet>::new(
|
||||
msg_logger.clone(),
|
||||
move |a, _| clone!(in_send; Box::pin(async move { in_send.send(a.to_vec()).await.unwrap() })),
|
||||
clone!(systems_weak, exit_send, get_ctx; move |n, _| {
|
||||
clone!(systems_weak, exit_send, get_ctx; async move {
|
||||
move |a, _| {
|
||||
clone!(in_send mut);
|
||||
Box::pin(async move { in_send.send(a.to_vec()).await.unwrap() })
|
||||
},
|
||||
{
|
||||
clone!(systems_weak, exit_send, get_ctx);
|
||||
move |n, _| {
|
||||
clone!(systems_weak, exit_send mut, get_ctx);
|
||||
async move {
|
||||
match n {
|
||||
api::HostExtNotif::Exit => exit_send.send(()).await.unwrap(),
|
||||
api::HostExtNotif::SystemDrop(api::SystemDrop(sys_id)) =>
|
||||
@@ -148,10 +153,12 @@ pub fn extension_init(
|
||||
api::HostExtNotif::AtomDrop(api::AtomDrop(sys_id, atom)) => {
|
||||
let ctx = get_ctx(sys_id).await;
|
||||
take_atom(atom, &ctx).await.dyn_free(ctx.clone()).await
|
||||
},
|
||||
}
|
||||
}
|
||||
}.boxed_local())
|
||||
}),
|
||||
.boxed_local()
|
||||
}
|
||||
},
|
||||
{
|
||||
clone!(logger, get_ctx, init_ctx, systems_weak, interner_weak, decls, msg_logger);
|
||||
move |hand, req| {
|
||||
@@ -174,7 +181,7 @@ pub fn extension_init(
|
||||
});
|
||||
let lazy_mems = Mutex::new(HashMap::new());
|
||||
let ctx = init_ctx(new_sys.id, cted.clone(), hand.reqnot()).await;
|
||||
let const_root = stream::from_iter(cted.inst().dyn_env())
|
||||
let const_root = stream::iter(cted.inst().dyn_env())
|
||||
.then(|mem| {
|
||||
let (req, lazy_mems) = (&hand, &lazy_mems);
|
||||
clone!(i, ctx; async move {
|
||||
@@ -375,7 +382,7 @@ pub fn extension_init(
|
||||
ExtInit {
|
||||
header: ext_header,
|
||||
port: Box::new(ExtensionOwner {
|
||||
out_recv,
|
||||
out_recv: Mutex::new(out_recv),
|
||||
out_send,
|
||||
_interner_cell: interner_cell,
|
||||
_systems_lock: systems_lock,
|
||||
|
||||
@@ -10,10 +10,9 @@ use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
use std::rc::Rc;
|
||||
|
||||
use async_std::io::Write;
|
||||
use async_std::sync::Mutex;
|
||||
use futures::FutureExt;
|
||||
use futures::future::LocalBoxFuture;
|
||||
use futures::lock::Mutex;
|
||||
use futures::{AsyncWrite, FutureExt};
|
||||
use itertools::Itertools;
|
||||
use never::Never;
|
||||
use orchid_api_traits::Encode;
|
||||
@@ -111,7 +110,7 @@ impl OwnedAtom for Fun {
|
||||
}
|
||||
}
|
||||
async fn call(self, arg: Expr) -> GExpr { self.call_ref(arg).await }
|
||||
async fn serialize(&self, _: SysCtx, write: Pin<&mut (impl Write + ?Sized)>) -> Self::Refs {
|
||||
async fn serialize(&self, _: SysCtx, write: Pin<&mut (impl AsyncWrite + ?Sized)>) -> Self::Refs {
|
||||
self.path.to_api().encode(write).await;
|
||||
self.args.clone()
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ pub mod expr;
|
||||
pub mod func_atom;
|
||||
pub mod gen_expr;
|
||||
pub mod lexer;
|
||||
pub mod msg;
|
||||
// pub mod msg;
|
||||
pub mod other_system;
|
||||
pub mod parser;
|
||||
pub mod reflection;
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
use std::pin::pin;
|
||||
|
||||
use async_once_cell::OnceCell;
|
||||
use async_std::io::{self, Stdout};
|
||||
use async_std::sync::Mutex;
|
||||
use futures::lock::Mutex;
|
||||
use orchid_base::msg::{recv_msg, send_msg};
|
||||
|
||||
static STDOUT: OnceCell<Mutex<Stdout>> = OnceCell::new();
|
||||
|
||||
pub async fn send_parent_msg(msg: &[u8]) -> io::Result<()> {
|
||||
let stdout_lk = STDOUT.get_or_init(async { Mutex::new(io::stdout()) }).await;
|
||||
let mut stdout_g = stdout_lk.lock().await;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use std::cell::OnceCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use async_std::sync::Mutex;
|
||||
use futures::FutureExt;
|
||||
use futures::lock::Mutex;
|
||||
use memo_map::MemoMap;
|
||||
use orchid_base::interner::Tok;
|
||||
use orchid_base::name::{NameLike, VPath};
|
||||
|
||||
@@ -62,7 +62,7 @@ pub trait SystemCtor: Send + Sync + 'static {
|
||||
type Instance: System;
|
||||
const NAME: &'static str;
|
||||
const VERSION: f64;
|
||||
fn inst() -> Option<Self::Instance>;
|
||||
fn inst(deps: <Self::Deps as DepDef>::Sat) -> Self::Instance;
|
||||
}
|
||||
|
||||
pub trait DynSystemCtor: Send + Sync + 'static {
|
||||
@@ -81,8 +81,8 @@ impl<T: SystemCtor> DynSystemCtor for T {
|
||||
}
|
||||
fn new_system(&self, api::NewSystem { system: _, id: _, depends }: &api::NewSystem) -> CtedObj {
|
||||
let mut ids = depends.iter().copied();
|
||||
let inst = Arc::new(T::inst().expect("Constructor did not create system"));
|
||||
let deps = T::Deps::create(&mut || ids.next().unwrap());
|
||||
let inst = Arc::new(T::inst(deps.clone()));
|
||||
Arc::new(Cted::<T> { deps, inst })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,23 +4,27 @@ use crate::entrypoint::ExtensionData;
|
||||
pub async fn tokio_main(data: ExtensionData) {
|
||||
use std::io::Write;
|
||||
use std::mem;
|
||||
use std::pin::Pin;
|
||||
use std::pin::{Pin, pin};
|
||||
use std::rc::Rc;
|
||||
|
||||
use async_std::io;
|
||||
use async_once_cell::OnceCell;
|
||||
use futures::StreamExt;
|
||||
use futures::future::LocalBoxFuture;
|
||||
use futures::lock::Mutex;
|
||||
use futures::stream::FuturesUnordered;
|
||||
use orchid_api_traits::{Decode, Encode};
|
||||
use orchid_base::msg::{recv_msg, send_msg};
|
||||
use tokio::io;
|
||||
use tokio::io::Stdout;
|
||||
use tokio::task::{LocalSet, spawn_local};
|
||||
use tokio_util::compat::{Compat, TokioAsyncReadCompatExt, TokioAsyncWriteCompatExt};
|
||||
|
||||
use crate::api;
|
||||
use crate::entrypoint::extension_init;
|
||||
use crate::msg::{recv_parent_msg, send_parent_msg};
|
||||
|
||||
let local_set = LocalSet::new();
|
||||
local_set.spawn_local(async {
|
||||
let host_header = api::HostHeader::decode(Pin::new(&mut async_std::io::stdin())).await;
|
||||
let host_header = api::HostHeader::decode(Pin::new(&mut tokio::io::stdin().compat())).await;
|
||||
let init =
|
||||
Rc::new(extension_init(data, host_header, Rc::new(|fut| mem::drop(spawn_local(fut)))));
|
||||
let mut buf = Vec::new();
|
||||
@@ -32,7 +36,7 @@ pub async fn tokio_main(data: ExtensionData) {
|
||||
let mut io = FuturesUnordered::<LocalBoxFuture<()>>::new();
|
||||
io.push(Box::pin(async {
|
||||
loop {
|
||||
match recv_parent_msg().await {
|
||||
match recv_msg(pin!(io::stdin().compat())).await {
|
||||
Ok(msg) => init.send(&msg[..]).await,
|
||||
Err(e) if e.kind() == io::ErrorKind::BrokenPipe => break,
|
||||
Err(e) if e.kind() == io::ErrorKind::UnexpectedEof => break,
|
||||
@@ -42,7 +46,10 @@ pub async fn tokio_main(data: ExtensionData) {
|
||||
}));
|
||||
io.push(Box::pin(async {
|
||||
while let Some(msg) = init.recv().await {
|
||||
send_parent_msg(&msg[..]).await.unwrap();
|
||||
static STDOUT: OnceCell<Mutex<Compat<Stdout>>> = OnceCell::new();
|
||||
let stdout_lk = STDOUT.get_or_init(async { Mutex::new(io::stdout().compat_write()) }).await;
|
||||
let mut stdout_g = stdout_lk.lock().await;
|
||||
send_msg(pin!(&mut *stdout_g), &msg[..]).await.expect("Parent pipe broken");
|
||||
}
|
||||
}));
|
||||
io.next().await;
|
||||
|
||||
@@ -6,14 +6,14 @@ edition = "2024"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
async-lock = "3.4.1"
|
||||
async-once-cell = "0.5.4"
|
||||
async-process = "2.3.0"
|
||||
async-std = "1.13.0"
|
||||
async-process = "2.4.0"
|
||||
async-stream = "0.3.6"
|
||||
bound = "0.6.0"
|
||||
derive_destructure = "1.0.0"
|
||||
futures = "0.3.31"
|
||||
hashbrown = "0.15.2"
|
||||
futures = { version = "0.3.31", features = ["std"] }
|
||||
hashbrown = "0.16.0"
|
||||
itertools = "0.14.0"
|
||||
lazy_static = "1.5.0"
|
||||
memo-map = "0.3.3"
|
||||
@@ -23,7 +23,7 @@ orchid-api = { version = "0.1.0", path = "../orchid-api" }
|
||||
orchid-api-traits = { version = "0.1.0", path = "../orchid-api-traits" }
|
||||
orchid-base = { version = "0.1.0", path = "../orchid-base" }
|
||||
ordered-float = "5.0.0"
|
||||
paste = "1.0.15"
|
||||
pastey = "0.1.1"
|
||||
substack = "1.1.1"
|
||||
test_executors = "0.3.2"
|
||||
test_executors = "0.3.5"
|
||||
trait-set = "0.3.0"
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::num::{NonZero, NonZeroU16};
|
||||
use std::rc::{Rc, Weak};
|
||||
use std::{fmt, ops};
|
||||
|
||||
use async_std::sync::RwLock;
|
||||
use async_lock::RwLock;
|
||||
use hashbrown::HashMap;
|
||||
use orchid_api::SysId;
|
||||
use orchid_base::builtin::Spawner;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::mem;
|
||||
|
||||
use async_std::sync::RwLockWriteGuard;
|
||||
use async_lock::RwLockWriteGuard;
|
||||
use bound::Bound;
|
||||
use futures::FutureExt;
|
||||
use orchid_base::error::OrcErrv;
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::num::NonZeroU64;
|
||||
use std::rc::{Rc, Weak};
|
||||
use std::{fmt, mem};
|
||||
|
||||
use async_std::sync::RwLock;
|
||||
use async_lock::RwLock;
|
||||
use futures::FutureExt;
|
||||
use hashbrown::HashSet;
|
||||
use itertools::Itertools;
|
||||
|
||||
@@ -5,12 +5,12 @@ use std::num::NonZeroU64;
|
||||
use std::pin::pin;
|
||||
use std::rc::{Rc, Weak};
|
||||
|
||||
use async_std::channel::{self, Sender};
|
||||
use async_std::sync::Mutex;
|
||||
use async_stream::stream;
|
||||
use derive_destructure::destructure;
|
||||
use futures::channel::mpsc::{Sender, channel};
|
||||
use futures::future::{join, join_all};
|
||||
use futures::{StreamExt, stream};
|
||||
use futures::lock::Mutex;
|
||||
use futures::{SinkExt, StreamExt, stream};
|
||||
use hashbrown::HashMap;
|
||||
use itertools::Itertools;
|
||||
use orchid_api_traits::Request;
|
||||
@@ -45,12 +45,12 @@ pub struct ExtensionData {
|
||||
next_pars: RefCell<NonZeroU64>,
|
||||
exprs: ExprStore,
|
||||
exiting_snd: Sender<()>,
|
||||
lex_recur: Mutex<HashMap<api::ParsId, channel::Sender<ReqPair<api::SubLex>>>>,
|
||||
lex_recur: Mutex<HashMap<api::ParsId, Sender<ReqPair<api::SubLex>>>>,
|
||||
}
|
||||
impl Drop for ExtensionData {
|
||||
fn drop(&mut self) {
|
||||
let reqnot = self.reqnot.clone();
|
||||
let exiting_snd = self.exiting_snd.clone();
|
||||
let mut exiting_snd = self.exiting_snd.clone();
|
||||
(self.ctx.spawn)(Box::pin(async move {
|
||||
reqnot.notify(api::HostExtNotif::Exit).await;
|
||||
exiting_snd.send(()).await.unwrap()
|
||||
@@ -64,7 +64,7 @@ impl Extension {
|
||||
pub fn new(init: ExtInit, logger: Logger, msg_logger: Logger, ctx: Ctx) -> io::Result<Self> {
|
||||
Ok(Self(Rc::new_cyclic(|weak: &Weak<ExtensionData>| {
|
||||
let init = Rc::new(init);
|
||||
let (exiting_snd, exiting_rcv) = channel::bounded::<()>(1);
|
||||
let (exiting_snd, exiting_rcv) = channel::<()>(0);
|
||||
(ctx.spawn)(clone!(init, weak, ctx; Box::pin(async move {
|
||||
let rcv_stream = stream! { loop { yield init.recv().await } };
|
||||
let mut event_stream = pin!(stream::select(exiting_rcv.map(|()| None), rcv_stream));
|
||||
@@ -147,13 +147,14 @@ impl Extension {
|
||||
hand.handle(fw, &sys.request(body.clone()).await).await
|
||||
},
|
||||
api::ExtHostReq::SubLex(sl) => {
|
||||
let (rep_in, rep_out) = channel::bounded(1);
|
||||
let (rep_in, mut rep_out) = channel(0);
|
||||
{
|
||||
let lex_g = this.0.lex_recur.lock().await;
|
||||
let req_in = lex_g.get(&sl.id).expect("Sublex for nonexistent lexid");
|
||||
let mut req_in =
|
||||
lex_g.get(&sl.id).cloned().expect("Sublex for nonexistent lexid");
|
||||
req_in.send(ReqPair(sl.clone(), rep_in)).await.unwrap();
|
||||
}
|
||||
hand.handle(&sl, &rep_out.recv().await.unwrap()).await
|
||||
hand.handle(&sl, &rep_out.next().await.unwrap()).await
|
||||
},
|
||||
api::ExtHostReq::ExprReq(api::ExprReq::Inspect(
|
||||
ins @ api::Inspect { target },
|
||||
@@ -265,7 +266,7 @@ impl Extension {
|
||||
// get unique lex ID
|
||||
let id = api::ParsId(self.next_pars());
|
||||
// create and register channel
|
||||
let (req_in, req_out) = channel::bounded(1);
|
||||
let (req_in, mut req_out) = channel(0);
|
||||
self.0.lex_recur.lock().await.insert(id, req_in); // lex_recur released
|
||||
let (ret, ()) = join(
|
||||
async {
|
||||
@@ -277,7 +278,7 @@ impl Extension {
|
||||
res
|
||||
},
|
||||
async {
|
||||
while let Ok(ReqPair(sublex, rep_in)) = req_out.recv().await {
|
||||
while let Some(ReqPair(sublex, mut rep_in)) = req_out.next().await {
|
||||
(rep_in.send(r(sublex.pos).await).await)
|
||||
.expect("Response channel dropped while request pending")
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use async_std::sync::Mutex;
|
||||
use futures::FutureExt;
|
||||
use futures::lock::Mutex;
|
||||
use orchid_base::error::{OrcErrv, OrcRes, mk_errv};
|
||||
use orchid_base::interner::Tok;
|
||||
use orchid_base::location::SrcRange;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use std::cell::RefCell;
|
||||
use std::io::Write;
|
||||
use std::io::{self, Write};
|
||||
use std::pin::Pin;
|
||||
|
||||
use async_process::{self, Child, ChildStdin, ChildStdout};
|
||||
use async_std::io::{self, BufReadExt, BufReader};
|
||||
use async_std::sync::Mutex;
|
||||
use futures::AsyncWriteExt;
|
||||
use futures::future::LocalBoxFuture;
|
||||
use futures::io::BufReader;
|
||||
use futures::lock::Mutex;
|
||||
use futures::{self, AsyncBufReadExt, AsyncWriteExt};
|
||||
use orchid_api_traits::{Decode, Encode};
|
||||
use orchid_base::builtin::{ExtInit, ExtPort};
|
||||
use orchid_base::logging::Logger;
|
||||
|
||||
@@ -4,8 +4,8 @@ use std::cell::RefCell;
|
||||
use std::rc::{Rc, Weak};
|
||||
use std::slice;
|
||||
|
||||
use async_lock::RwLock;
|
||||
use async_once_cell::OnceCell;
|
||||
use async_std::sync::RwLock;
|
||||
use futures::{FutureExt, StreamExt, stream};
|
||||
use hashbrown::HashMap;
|
||||
use hashbrown::hash_map::Entry;
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
[package]
|
||||
name = "orchid-macros"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
@@ -1,3 +0,0 @@
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
||||
@@ -5,13 +5,12 @@ edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
async-once-cell = "0.5.4"
|
||||
async-std = "1.13.0"
|
||||
async-stream = "0.3.6"
|
||||
futures = "0.3.31"
|
||||
hashbrown = "0.15.2"
|
||||
futures = { version = "0.3.31", features = ["std"] }
|
||||
hashbrown = "0.16.0"
|
||||
itertools = "0.14.0"
|
||||
never = "0.1.0"
|
||||
once_cell = "1.20.2"
|
||||
once_cell = "1.21.3"
|
||||
orchid-api = { version = "0.1.0", path = "../orchid-api" }
|
||||
orchid-api-derive = { version = "0.1.0", path = "../orchid-api-derive" }
|
||||
orchid-api-traits = { version = "0.1.0", path = "../orchid-api-traits" }
|
||||
@@ -20,9 +19,9 @@ orchid-extension = { version = "0.1.0", path = "../orchid-extension", features =
|
||||
"tokio",
|
||||
] }
|
||||
ordered-float = "5.0.0"
|
||||
rust_decimal = "1.36.0"
|
||||
rust_decimal = "1.37.2"
|
||||
substack = "1.1.1"
|
||||
tokio = { version = "1.43.0", features = ["full"] }
|
||||
tokio = { version = "1.47.1", features = ["full"] }
|
||||
|
||||
[dev-dependencies]
|
||||
test_executors = "0.3.2"
|
||||
test_executors = "0.3.5"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use std::pin::pin;
|
||||
|
||||
use async_std::stream;
|
||||
use futures::{FutureExt, StreamExt};
|
||||
use futures::{FutureExt, StreamExt, stream};
|
||||
use hashbrown::HashMap;
|
||||
use itertools::Itertools;
|
||||
use orchid_api::Paren;
|
||||
@@ -54,7 +53,7 @@ impl Parser for LetLine {
|
||||
pub async fn dealias_mac_v(aliased: Vec<MacTree>, ctx: &ConstCtx, rep: &Reporter) -> Vec<MacTree> {
|
||||
let keys = glossary_v(&aliased).collect_vec();
|
||||
let mut names: HashMap<_, _> = HashMap::new();
|
||||
let mut stream = pin!(ctx.names(&keys).zip(stream::from_iter(&keys)));
|
||||
let mut stream = pin!(ctx.names(&keys).zip(stream::iter(&keys)));
|
||||
while let Some((canonical, local)) = stream.next().await {
|
||||
match canonical {
|
||||
Err(e) => rep.report(e),
|
||||
@@ -91,7 +90,7 @@ pub async fn parse_tokv(line: PSnippet<'_>, ctx: &impl ParseCtx) -> Vec<MacTree>
|
||||
}
|
||||
|
||||
async fn parse_tokv_no_lambdas(line: &[PTokTree], ctx: &impl ParseCtx) -> Vec<MacTree> {
|
||||
stream::from_iter(line).filter_map(|tt| parse_tok(tt, ctx)).collect().await
|
||||
stream::iter(line).filter_map(|tt| parse_tok(tt, ctx)).collect().await
|
||||
}
|
||||
|
||||
pub async fn parse_tok(tree: &PTokTree, ctx: &impl ParseCtx) -> Option<MacTree> {
|
||||
|
||||
@@ -3,8 +3,7 @@ use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use async_once_cell::OnceCell;
|
||||
use async_std::stream;
|
||||
use futures::StreamExt;
|
||||
use futures::{StreamExt, stream};
|
||||
use hashbrown::{HashMap, HashSet};
|
||||
use itertools::Itertools;
|
||||
use never::Never;
|
||||
@@ -159,7 +158,7 @@ impl Parser for MacroLine {
|
||||
.get_or_init(async {
|
||||
let rep = Reporter::new();
|
||||
let rules = rules.borrow_mut().take().expect("once cell initializer runs");
|
||||
let rules = stream::from_iter(rules)
|
||||
let rules = stream::iter(rules)
|
||||
.then(|(body_name, placeholders, index, pos, pattern_macv)| {
|
||||
let cctx = &cctx;
|
||||
let rep = &rep;
|
||||
@@ -182,7 +181,7 @@ impl Parser for MacroLine {
|
||||
}
|
||||
}
|
||||
})
|
||||
.flat_map(stream::from_iter)
|
||||
.flat_map(stream::iter)
|
||||
.collect::<Vec<_>>()
|
||||
.await;
|
||||
let own_kws = keywords.keys().cloned().collect_vec();
|
||||
|
||||
@@ -5,6 +5,7 @@ use orchid_base::reqnot::Receipt;
|
||||
use orchid_extension::atom::{AtomDynfo, AtomicFeatures};
|
||||
use orchid_extension::entrypoint::ExtReq;
|
||||
use orchid_extension::lexer::LexerObj;
|
||||
use orchid_extension::other_system::SystemHandle;
|
||||
use orchid_extension::parser::ParserObj;
|
||||
use orchid_extension::system::{System, SystemCard};
|
||||
use orchid_extension::system_ctor::SystemCtor;
|
||||
@@ -13,7 +14,7 @@ use orchid_extension::tree::GenMember;
|
||||
use crate::macros::instantiate_tpl::InstantiateTplCall;
|
||||
use crate::macros::let_line::LetLine;
|
||||
use crate::macros::macro_lib::gen_macro_lib;
|
||||
use crate::macros::macro_line::MacroLine;
|
||||
use crate::macros::macro_line::{Macro, MacroLine};
|
||||
use crate::macros::mactree_lexer::MacTreeLexer;
|
||||
use crate::macros::recur_state::RecurState;
|
||||
use crate::{MacTree, StdSystem};
|
||||
@@ -25,13 +26,18 @@ impl SystemCtor for MacroSystem {
|
||||
type Instance = Self;
|
||||
const NAME: &'static str = "macros";
|
||||
const VERSION: f64 = 0.00_01;
|
||||
fn inst() -> Option<Self::Instance> { Some(Self) }
|
||||
fn inst(_: SystemHandle<StdSystem>) -> Self::Instance { Self }
|
||||
}
|
||||
impl SystemCard for MacroSystem {
|
||||
type Ctor = Self;
|
||||
type Req = Never;
|
||||
fn atoms() -> impl IntoIterator<Item = Option<Box<dyn AtomDynfo>>> {
|
||||
[Some(InstantiateTplCall::dynfo()), Some(MacTree::dynfo()), Some(RecurState::dynfo())]
|
||||
[
|
||||
Some(InstantiateTplCall::dynfo()),
|
||||
Some(MacTree::dynfo()),
|
||||
Some(RecurState::dynfo()),
|
||||
Some(Macro::dynfo()),
|
||||
]
|
||||
}
|
||||
}
|
||||
impl System for MacroSystem {
|
||||
|
||||
@@ -25,7 +25,7 @@ impl SystemCtor for StdSystem {
|
||||
type Instance = Self;
|
||||
const NAME: &'static str = "orchid::std";
|
||||
const VERSION: f64 = 0.00_01;
|
||||
fn inst() -> Option<Self::Instance> { Some(Self) }
|
||||
fn inst(_: ()) -> Self::Instance { Self }
|
||||
}
|
||||
impl SystemCard for StdSystem {
|
||||
type Ctor = Self;
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::ops::Deref;
|
||||
use std::pin::Pin;
|
||||
use std::rc::Rc;
|
||||
|
||||
use async_std::io::Write;
|
||||
use futures::AsyncWrite;
|
||||
use orchid_api_derive::Coding;
|
||||
use orchid_api_traits::{Encode, Request};
|
||||
use orchid_base::error::{OrcRes, mk_errv};
|
||||
@@ -46,7 +46,7 @@ impl Deref for StrAtom {
|
||||
impl OwnedAtom for StrAtom {
|
||||
type Refs = ();
|
||||
async fn val(&self) -> Cow<'_, Self::Data> { Cow::Owned(()) }
|
||||
async fn serialize(&self, _: SysCtx, sink: Pin<&mut (impl Write + ?Sized)>) -> Self::Refs {
|
||||
async fn serialize(&self, _: SysCtx, sink: Pin<&mut (impl AsyncWrite + ?Sized)>) -> Self::Refs {
|
||||
self.deref().encode(sink).await
|
||||
}
|
||||
async fn print_atom<'a>(&'a self, _: &'a (impl FmtCtx + ?Sized + 'a)) -> FmtUnit {
|
||||
@@ -72,7 +72,7 @@ impl OwnedAtom for IntStrAtom {
|
||||
async fn print_atom<'a>(&'a self, _: &'a (impl FmtCtx + ?Sized + 'a)) -> FmtUnit {
|
||||
format!("{:?}i", *self.0).into()
|
||||
}
|
||||
async fn serialize(&self, _: SysCtx, write: Pin<&mut (impl Write + ?Sized)>) {
|
||||
async fn serialize(&self, _: SysCtx, write: Pin<&mut (impl AsyncWrite + ?Sized)>) {
|
||||
self.0.encode(write).await
|
||||
}
|
||||
async fn deserialize(mut ctx: impl DeserializeCtx, _: ()) -> Self {
|
||||
|
||||
Reference in New Issue
Block a user