forked from Orchid/orchid
Method refactor now compiles
This commit is contained in:
@@ -26,7 +26,6 @@ orchid-extension = { version = "0.1.0", path = "../orchid-extension", optional =
|
||||
ordered-float = "5.1.0"
|
||||
pastey = "0.2.1"
|
||||
substack = "1.1.1"
|
||||
test_executors = "0.4.1"
|
||||
tokio = { version = "1.49.0", features = ["process"], optional = true }
|
||||
tokio-util = { version = "0.7.18", features = ["compat"], optional = true }
|
||||
trait-set = "0.3.0"
|
||||
|
||||
@@ -3,10 +3,14 @@ use std::rc::{Rc, Weak};
|
||||
|
||||
use async_once_cell::OnceCell;
|
||||
use derive_destructure::destructure;
|
||||
#[cfg(feature = "orchid-extension")]
|
||||
use orchid_api_traits::{Request, UnderRoot};
|
||||
use orchid_base::format::{FmtCtx, FmtUnit, Format, take_first_fmt};
|
||||
use orchid_base::location::Pos;
|
||||
use orchid_base::reqnot::ClientExt;
|
||||
use orchid_base::tree::AtomRepr;
|
||||
#[cfg(feature = "orchid-extension")]
|
||||
use orchid_extension::atom::AtomMethod;
|
||||
|
||||
use crate::api;
|
||||
use crate::ctx::Ctx;
|
||||
@@ -56,6 +60,21 @@ impl AtomHand {
|
||||
Self(Rc::new(AtomData { owner, drop, data, display: OnceCell::new() }))
|
||||
}
|
||||
#[must_use]
|
||||
#[cfg(feature = "orchid-extension")]
|
||||
pub async fn ipc<M: Request + UnderRoot<Root: AtomMethod>>(
|
||||
&self,
|
||||
method: M,
|
||||
) -> Option<M::Response> {
|
||||
use orchid_api_traits::{Decode, Encode};
|
||||
use orchid_base::name::Sym;
|
||||
|
||||
let name = Sym::parse(<M as UnderRoot>::Root::NAME).await.unwrap();
|
||||
let mut buf = Vec::new();
|
||||
method.into_root().encode_vec(&mut buf);
|
||||
let reply_buf = self.req(name.to_api(), buf).await?;
|
||||
Some(M::Response::decode_slice(&mut &reply_buf[..]))
|
||||
}
|
||||
#[must_use]
|
||||
pub async fn call(self, arg: Expr) -> Expr {
|
||||
let owner_sys = self.0.owner.clone();
|
||||
let ctx = owner_sys.ctx();
|
||||
|
||||
@@ -2,9 +2,13 @@ use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use futures::io::BufReader;
|
||||
use futures::{AsyncBufReadExt, StreamExt};
|
||||
use hashbrown::HashMap;
|
||||
use libloading::Library;
|
||||
use libloading::{Library, Symbol};
|
||||
use orchid_base::binary::vt_to_future;
|
||||
use orchid_base::logging::log;
|
||||
use unsync_pipe::pipe;
|
||||
|
||||
use crate::api;
|
||||
use crate::ctx::Ctx;
|
||||
@@ -23,23 +27,16 @@ fn load_dylib(path: &Path) -> Result<Arc<Library>, libloading::Error> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "tokio")]
|
||||
pub async fn ext_dylib(path: &Path, ctx: Ctx) -> Result<ExtPort, libloading::Error> {
|
||||
use futures::io::BufReader;
|
||||
use futures::{AsyncBufReadExt, StreamExt};
|
||||
use libloading::Symbol;
|
||||
use unsync_pipe::pipe;
|
||||
|
||||
let (write_input, input) = pipe(1024);
|
||||
let (output, read_output) = pipe(1024);
|
||||
let (log, read_log) = pipe(1024);
|
||||
let (write_log, read_log) = pipe(1024);
|
||||
let log_path = path.to_string_lossy().to_string();
|
||||
let _ = ctx.spawn(async move {
|
||||
use orchid_base::logging::log;
|
||||
let mut lines = BufReader::new(read_log).lines();
|
||||
while let Some(line) = lines.next().await {
|
||||
match line {
|
||||
Ok(line) => writeln!(log("stderr"), "{log_path} err> {line}").await,
|
||||
Ok(line) => writeln!(log("stderr"), "dylib {log_path} err> {line}").await,
|
||||
Err(e) => match e.kind() {
|
||||
io::ErrorKind::BrokenPipe | io::ErrorKind::UnexpectedEof => break,
|
||||
_ => panic!("Error while reading stderr {e}"),
|
||||
@@ -56,7 +53,7 @@ pub async fn ext_dylib(path: &Path, ctx: Ctx) -> Result<ExtPort, libloading::Err
|
||||
let _ = unsafe { (data as *mut Ctx).as_mut().unwrap().spawn(vt_to_future(vt)) };
|
||||
}
|
||||
let spawner = api::binary::SpawnerBin { data, drop, spawn };
|
||||
let cx = api::binary::ExtensionContext { input, output, log, spawner };
|
||||
let cx = api::binary::ExtensionContext { input, output, log: write_log, spawner };
|
||||
unsafe { (entrypoint)(cx) };
|
||||
Ok(ExtPort { input: Box::pin(write_input), output: Box::pin(read_output) })
|
||||
}
|
||||
|
||||
45
orchid-host/src/inline.rs
Normal file
45
orchid-host/src/inline.rs
Normal file
@@ -0,0 +1,45 @@
|
||||
#[cfg(feature = "orchid-extension")]
|
||||
use orchid_extension as ox;
|
||||
|
||||
#[cfg(feature = "orchid-extension")]
|
||||
use crate::ctx::Ctx;
|
||||
#[cfg(feature = "orchid-extension")]
|
||||
use crate::extension::ExtPort;
|
||||
|
||||
#[cfg(feature = "orchid-extension")]
|
||||
pub async fn ext_inline(builder: ox::entrypoint::ExtensionBuilder, ctx: Ctx) -> ExtPort {
|
||||
use std::io;
|
||||
use std::rc::Rc;
|
||||
|
||||
use futures::io::BufReader;
|
||||
use futures::{AsyncBufReadExt, StreamExt};
|
||||
use orchid_base::logging::log;
|
||||
use unsync_pipe::pipe;
|
||||
|
||||
let (in_stdin, out_stdin) = pipe(1024);
|
||||
let (in_stdout, out_stdout) = pipe(1024);
|
||||
let (in_stderr, out_stderr) = pipe(1024);
|
||||
|
||||
let name = builder.name;
|
||||
|
||||
std::mem::drop(ctx.spawn(async move {
|
||||
let mut lines = BufReader::new(out_stderr).lines();
|
||||
while let Some(line) = lines.next().await {
|
||||
match line {
|
||||
Ok(line) => writeln!(log("stderr"), "inline {name} err> {line}").await,
|
||||
Err(e) => match e.kind() {
|
||||
io::ErrorKind::BrokenPipe | io::ErrorKind::UnexpectedEof => break,
|
||||
_ => panic!("Error while reading stderr {e}"),
|
||||
},
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
builder.build(ox::ext_port::ExtPort {
|
||||
input: Box::pin(out_stdin),
|
||||
output: Box::pin(in_stdout),
|
||||
log: Box::pin(in_stderr),
|
||||
spawn: Rc::new(move |fut| std::mem::drop(ctx.spawn(fut))),
|
||||
});
|
||||
ExtPort { input: Box::pin(in_stdin), output: Box::pin(out_stdout) }
|
||||
}
|
||||
@@ -3,15 +3,18 @@ use orchid_api as api;
|
||||
pub mod atom;
|
||||
pub mod ctx;
|
||||
pub mod dealias;
|
||||
#[cfg(feature = "tokio")]
|
||||
pub mod dylib;
|
||||
pub mod execute;
|
||||
pub mod expr;
|
||||
pub mod expr_store;
|
||||
pub mod extension;
|
||||
pub mod inline;
|
||||
pub mod lex;
|
||||
pub mod logger;
|
||||
pub mod parse;
|
||||
pub mod parsed;
|
||||
#[cfg(feature = "tokio")]
|
||||
pub mod subprocess;
|
||||
mod sys_parser;
|
||||
pub mod system;
|
||||
|
||||
@@ -3,14 +3,12 @@ use std::{io, process};
|
||||
use futures::io::BufReader;
|
||||
use futures::{self, AsyncBufReadExt, StreamExt};
|
||||
use orchid_base::logging::log;
|
||||
#[cfg(feature = "tokio")]
|
||||
use tokio_util::compat::{TokioAsyncReadCompatExt, TokioAsyncWriteCompatExt};
|
||||
|
||||
use crate::ctx::Ctx;
|
||||
use crate::extension::ExtPort;
|
||||
|
||||
#[cfg(feature = "tokio")]
|
||||
pub async fn ext_command(cmd: std::process::Command, ctx: Ctx) -> io::Result<ExtPort> {
|
||||
pub async fn ext_command(cmd: process::Command, ctx: Ctx) -> io::Result<ExtPort> {
|
||||
let name = cmd.get_program().to_string_lossy().to_string();
|
||||
let mut child = tokio::process::Command::from(cmd)
|
||||
.stdin(process::Stdio::piped())
|
||||
@@ -25,9 +23,13 @@ pub async fn ext_command(cmd: std::process::Command, ctx: Ctx) -> io::Result<Ext
|
||||
let _ = child;
|
||||
let mut lines = BufReader::new(child_stderr.compat()).lines();
|
||||
while let Some(line) = lines.next().await {
|
||||
// route stderr with an empty category string. This is not the intended logging
|
||||
// method
|
||||
writeln!(log("stderr"), "{} err> {}", name, line.expect("Readline implies this")).await;
|
||||
match line {
|
||||
Ok(line) => writeln!(log("stderr"), "subproc {name} err> {line}").await,
|
||||
Err(e) => match e.kind() {
|
||||
io::ErrorKind::BrokenPipe | io::ErrorKind::UnexpectedEof => break,
|
||||
_ => panic!("Error while reading stderr {e}"),
|
||||
},
|
||||
}
|
||||
}
|
||||
}));
|
||||
Ok(ExtPort { input: Box::pin(stdin.compat_write()), output: Box::pin(stdout.compat()) })
|
||||
|
||||
Reference in New Issue
Block a user