graphix-shell 0.9.0

A dataflow language for UIs and network programming
Documentation
use ahash::AHashMap;
use anyhow::Result;
use arcstr::ArcStr;
use graphix_compiler::{env::Env, ExecCtx};
use graphix_package::{CustomDisplay, IndexSet, MainThreadHandle, Package};
use graphix_rt::{CompExp, GXExt, GXHandle, GXRt};
use netidx_core::path::Path;
use tokio::sync::oneshot;

pub(crate) struct RegisterResult {
    pub root: ArcStr,
    pub main_program: Option<&'static str>,
}

pub(crate) fn register<X: GXExt>(
    ctx: &mut ExecCtx<GXRt<X>, X::UserEvent>,
    modules: &mut AHashMap<Path, ArcStr>,
) -> Result<RegisterResult> {
    let mut root_mods = IndexSet::new();
    graphix_package_core::P::register(ctx, modules, &mut root_mods)?;
    graphix_package_array::P::register(ctx, modules, &mut root_mods)?;
    graphix_package_list::P::register(ctx, modules, &mut root_mods)?;
    graphix_package_str::P::register(ctx, modules, &mut root_mods)?;
    graphix_package_map::P::register(ctx, modules, &mut root_mods)?;
    graphix_package_sys::P::register(ctx, modules, &mut root_mods)?;
    graphix_package_args::P::register(ctx, modules, &mut root_mods)?;
    graphix_package_http::P::register(ctx, modules, &mut root_mods)?;
    graphix_package_json::P::register(ctx, modules, &mut root_mods)?;
    graphix_package_toml::P::register(ctx, modules, &mut root_mods)?;
    graphix_package_pack::P::register(ctx, modules, &mut root_mods)?;
    graphix_package_xls::P::register(ctx, modules, &mut root_mods)?;
    graphix_package_sqlite::P::register(ctx, modules, &mut root_mods)?;
    graphix_package_db::P::register(ctx, modules, &mut root_mods)?;
    graphix_package_hbs::P::register(ctx, modules, &mut root_mods)?;
    graphix_package_re::P::register(ctx, modules, &mut root_mods)?;
    graphix_package_rand::P::register(ctx, modules, &mut root_mods)?;
    graphix_package_tui::P::register(ctx, modules, &mut root_mods)?;
    #[cfg(feature = "gui")]
    graphix_package_gui::P::register(ctx, modules, &mut root_mods)?;
    let mut parts = Vec::new();
    for name in &root_mods {
        if name == "core" {
            parts.push(format!("mod core;\nuse core"));
        } else {
            parts.push(format!("mod {name}"));
        }
    }
    Ok(RegisterResult { root: ArcStr::from(parts.join(";\n")), main_program: None })
}

pub(crate) struct Cdc<X: GXExt> {
    pub stop: oneshot::Receiver<()>,
    pub custom: Box<dyn CustomDisplay<X>>,
}

pub(crate) enum CustomResult<X: GXExt> {
    Custom(Cdc<X>),
    NotCustom(CompExp<X>),
}

pub(crate) async fn maybe_init_custom<X: GXExt>(
    gx: &GXHandle<X>,
    env: &Env,
    e: CompExp<X>,
    run_on_main: &MainThreadHandle,
) -> Result<CustomResult<X>> {
    macro_rules! try_pkg {
        ($pkg:path) => {
            if <$pkg>::is_custom(gx, env, &e) {
                let (tx, rx) = oneshot::channel();
                return <$pkg>::init_custom(gx, env, tx, e, run_on_main.clone())
                    .await
                    .map(|custom| CustomResult::Custom(Cdc { stop: rx, custom }));
            }
        };
    }
    try_pkg!(graphix_package_core::P);
    try_pkg!(graphix_package_array::P);
    try_pkg!(graphix_package_list::P);
    try_pkg!(graphix_package_str::P);
    try_pkg!(graphix_package_map::P);
    try_pkg!(graphix_package_sys::P);
    try_pkg!(graphix_package_args::P);
    try_pkg!(graphix_package_http::P);
    try_pkg!(graphix_package_json::P);
    try_pkg!(graphix_package_toml::P);
    try_pkg!(graphix_package_pack::P);
    try_pkg!(graphix_package_xls::P);
    try_pkg!(graphix_package_sqlite::P);
    try_pkg!(graphix_package_db::P);
    try_pkg!(graphix_package_hbs::P);
    try_pkg!(graphix_package_re::P);
    try_pkg!(graphix_package_rand::P);
    try_pkg!(graphix_package_tui::P);
    #[cfg(feature = "gui")]
    try_pkg!(graphix_package_gui::P);
    Ok(CustomResult::NotCustom(e))
}