ppc cli runs

This commit is contained in:
Sebastian Moser
2026-02-18 16:08:39 +01:00
parent 0b7e54dc1d
commit 56f658da1e
15 changed files with 292 additions and 292 deletions

View File

@@ -35,6 +35,7 @@ pub fn mize_part(attr: TokenStream, item: TokenStream) -> TokenStream {
let expanded = quote! {
#input
use std::any::Any;
// impl the default new impl
impl mize::MizePartGenerated for #struct_name {
@@ -45,20 +46,21 @@ pub fn mize_part(attr: TokenStream, item: TokenStream) -> TokenStream {
&mut self.mize
}
fn as_any_generated(&self) -> &dyn Any {
&self
self
}
fn as_any_mut_generated(&mut self) -> &dyn Any {
&mut self
fn as_any_mut_generated(&mut self) -> &mut dyn Any {
self
}
fn into_any_generated(self: Box<Self>) -> Box<dyn Any> {
self
}
}
impl mize::MizePartCreateGenerated for #struct_name {
fn create_generated(mize: Mize) -> Self {
Self {
mize,
... Default::default(),
.. Default::default()
}
}
}

10
crates/marts/Cargo.toml Normal file
View File

@@ -0,0 +1,10 @@
[package]
name = "marts"
description = "marts = mize_parts - parts collection of the Mize framework"
version = "0.1.0"
edition = "2021"
[dependencies]
clap = "4.5.59"
deno_core = "0.385.0"
mize = { path = "../mize/" }

View File

@@ -1,16 +1,26 @@
use clap::{ArgMatches, Command};
use std::any::Any;
use std::collections::HashMap;
use mize::{Mize, MizePart, MizeResult, instance::MizePartGuard};
use mize::{mize_part, Mize, MizePart, MizeResult};
#[mize_part("cli")]
struct CliPart {
#[derive(Default)]
pub struct CliPart {
mize: Mize,
cmd: Option<Command>,
actions: HashMap<String, fn(&ArgMatches) -> MizeResult<()>>,
}
pub fn cli(mize: &mut Mize) -> MizeResult<()> {
let cli_part = CliPart {
mize: mize.clone(),
cmd: Some(Command::new("marts-cli")),
actions: HashMap::new(),
};
mize.register_part(Box::new(cli_part))
}
impl MizePart for CliPart {
fn init(&mut self, _mize: &mut Mize) -> MizeResult<()> {
Ok(())
@@ -19,7 +29,7 @@ impl MizePart for CliPart {
let matches = self.cmd.take().unwrap().get_matches();
let sub_cmd = matches.subcommand_name().unwrap();
let action = self.actions.get(sub_cmd).unwrap();
action(matches.subcommand_matches(sub_cmd).unwrap());
action(matches.subcommand_matches(sub_cmd).unwrap())?;
Ok(())
}
fn opts(&self, mize: &mut Mize) {
@@ -30,12 +40,21 @@ impl MizePart for CliPart {
impl CliPart {
pub fn subcommand(
&mut self,
cmd: Command,
subcmd: Command,
action: fn(sub_matches: &ArgMatches) -> MizeResult<()>,
) -> &mut Command {
let cmd = self.cmd.take().unwrap().subcommand(cmd);
self.actions.insert(cmd.get_name().to_string(), action);
let name = subcmd.get_name().to_string();
let cmd = self.cmd.take().unwrap().subcommand(subcmd);
self.actions.insert(name, action);
self.cmd = Some(cmd);
self.cmd.as_mut().unwrap()
}
pub fn with_cmd(
&mut self,
func: fn(mize: Mize, cmd: Command) -> MizeResult<Command>,
) -> MizeResult<()> {
let cmd = func(self.mize.clone(), self.cmd.take().unwrap())?;
self.cmd = Some(cmd);
Ok(())
}
}

View File

@@ -1,9 +1,9 @@
use deno_core::FsModuleLoader;
use deno_core::error::AnyError;
use deno_core::{JsRuntime, ModuleSpecifier, PollEventLoopOptions, RuntimeOptions, extension, op2};
use deno_core::FsModuleLoader;
use deno_core::{extension, op2, JsRuntime, ModuleSpecifier, PollEventLoopOptions, RuntimeOptions};
use mize::async_trait;
use mize::instance::MizePartCreate;
use mize::{Mize, MizePart, MizeResult, mize_part};
use mize::{mize_part, Mize, MizePart, MizeResult};
use std::path::Path;
use std::rc::Rc;
@@ -13,38 +13,52 @@ pub struct JsPart {
js_runtime: JsRuntime,
}
// Define your custom ops for the "mize" object inside deno
#[op2(fast)]
fn op_mize_get_part(#[string] name: &str) {
println!("js wants the part {}", name);
}
#[op2]
#[string]
fn op_mize_get_config(#[string] key: &str) -> String {
format!("config_value_for_{}", key)
}
// Create an extension with your custom ops
extension!(mize_ext, ops = [op_mize_get_part, op_mize_get_config]);
impl MizePart for JsPart {
fn init(&mut self, mize: &mut Mize) -> MizeResult<()> {
println!("js part init");
Ok(())
}
}
impl MizePartCreate for JsPart {
fn create(mize: &mut Mize) -> Box<dyn MizePart> {
let mut js_runtime = JsRuntime::new(RuntimeOptions {
module_loader: Some(Rc::new(FsModuleLoader)),
extensions: vec![mize_ext::init_ops()],
..Default::default()
});
let bootstrap_code = r#"
globalThis.mize = {
get_part: (name) => Deno.core.ops.op_mize_get_part(name),
get_config: (key) => Deno.core.ops.op_mize_get_config(key),
version: "1.0.0",
// Add more methods as needed
};
"#;
js_runtime.execute_script("[bootstrap]", bootstrap_code)?;
JsPart { mize, js_runtime }
}
fn js(mize: &mut Mize) -> Box<dyn MizePart> {
let mut js_runtime = JsRuntime::new(RuntimeOptions {
module_loader: Some(Rc::new(FsModuleLoader)),
extensions: vec![mize_ext::init_ops()],
..Default::default()
});
let bootstrap_code = r#"
globalThis.mize = {
get_part: (name) => Deno.core.ops.op_mize_get_part(name),
get_config: (key) => Deno.core.ops.op_mize_get_config(key),
version: "1.0.0",
// Add more methods as needed
};
"#;
js_runtime.execute_script("[bootstrap]", bootstrap_code)?;
JsPart { mize, js_runtime }
}
impl JsPart {
pub fn part_from_js_file(
&mut self,
name: &'static str,
path: &str,
path: &'static str,
) -> Box<dyn MizePart + Send + Sync> {
Box::new(PartFromJsFileAdapter {
mize: self.mize.clone(),
@@ -52,6 +66,9 @@ impl JsPart {
js_file: path,
})
}
pub fn runtime(&mut self) -> &mut JsRuntime {
&mut self.js_runtime
}
}
#[mize_part]
@@ -70,7 +87,7 @@ impl MizePart for PartFromJsFileAdapter {
self.name
}
async fn async_init(&mut self, mize: &mut Mize) -> MizeResult<()> {
let js: JsPart = mize.get_part_native("js");
let js = mize.get_part_native::<JsPart>("js")?;
let path = self.js_file;
let js_code = format!(
r#"
@@ -96,13 +113,13 @@ impl MizePart for PartFromJsFileAdapter {
);
// Execute the script
let result = js.runtime.execute_script("[main]", js_code)?;
let result = js.runtime().execute_script("[main]", js_code)?;
// Resolve the promise and run event loop
let resolved_value = js.runtime.resolve_value(result).await?;
let resolved_value = js.runtime().resolve_value(result).await?;
// Run the event loop to completion
js.runtime
js.runtime()
.run_event_loop(PollEventLoopOptions::default())
.await?;
@@ -110,7 +127,7 @@ impl MizePart for PartFromJsFileAdapter {
Ok(())
}
async fn async_run(&mut self, mize: &mut Mize) -> MizeResult<()> {
let js: JsPart = mize.get_part_native("js");
let js = mize.get_part_native::<JsPart>("js")?;
let path = self.js_file;
let js_code = format!(
r#"
@@ -122,13 +139,13 @@ impl MizePart for PartFromJsFileAdapter {
"#
);
// Execute the script
let result = js.runtime.execute_script("[main]", js_code)?;
let result = js.runtime().execute_script("[main]", js_code)?;
// Resolve the promise and run event loop
let resolved_value = js.runtime.resolve_value(result).await?;
// Run the event loop to completion
js.runtime
js.runtime()
.run_event_loop(PollEventLoopOptions::default())
.await?;
@@ -136,33 +153,3 @@ impl MizePart for PartFromJsFileAdapter {
Ok(())
}
}
/*
async fn run_js_file(file_path: &str) -> Result<(), AnyError> {
let main_module = deno_core::resolve_path(file_path, &std::env::current_dir()?)?;
let mut js_runtime = deno_core::JsRuntime::new(deno_core::RuntimeOptions {
module_loader: Some(Rc::new(deno_core::FsModuleLoader)),
..Default::default()
});
let mod_id = js_runtime.load_main_es_module(&main_module).await?;
let result = js_runtime.mod_evaluate(mod_id);
js_runtime.run_event_loop(Default::default()).await?;
result.await
}
*/
// Define your custom ops for the "mize" object inside deno
#[op2(fast)]
fn op_mize_get_part(#[string] name: &str) {
println!("js wants the part {}", name);
}
#[op2]
#[string]
fn op_mize_get_config(#[string] key: &str) -> String {
format!("config_value_for_{}", key)
}
// Create an extension with your custom ops
extension!(mize_ext, ops = [op_mize_get_part, op_mize_get_config]);

4
crates/marts/src/lib.rs Normal file
View File

@@ -0,0 +1,4 @@
mod cli;
pub use cli::*;
//mod js;

View File

@@ -66,8 +66,8 @@ ciborium-io = { version = "0.2.2", optional = true }
tracing-core = { version = "0.1.32", optional = true }
tar = { version = "0.4.42", optional = true }
flate2 = { version = "1.0.33", optional = true }
#http_req = { version = "0.12.0", default-features = false, features = [ "rustls" ], optional = true }
http_req = { git = "https://github.com/c2vi/http_req", optional = true, default-features = false, features = [ "native-tls" ] }
http_req = { version = "0.12.0", default-features = false, features = [ "rust-tls" ], optional = true }
#http_req = { git = "https://github.com/c2vi/http_req", optional = true, default-features = false, features = [ "native-tls" ] }
# bare dependencies

View File

@@ -104,22 +104,25 @@ pub struct MizePartGuard<T: MizePart + Send + Sync + 'static> {
pub part: Option<T>,
}
impl<T: MizePart + Send + Sync + Deref<Target = T>> Deref for MizePartGuard<T> {
impl<T: MizePart + Send + Sync> Deref for MizePartGuard<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&*self.part.as_deref().unwrap()
&*self.part.as_ref().unwrap()
}
}
impl<T: MizePart + Send + Sync + DerefMut<Target = T>> DerefMut for MizePartGuard<T> {
impl<T: MizePart + Send + Sync> DerefMut for MizePartGuard<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut *self.part.as_deref_mut().unwrap()
&mut *self.part.as_mut().unwrap()
}
}
impl<T: MizePart + Send + Sync> Drop for MizePartGuard<T> {
fn drop(&mut self) {
if self.part.is_none() {
return;
}
let part = self.part.take().unwrap();
self.mize.give_back_part(Box::new(part));
}
@@ -141,6 +144,9 @@ impl DerefMut for DynMizePartGuard {
impl Drop for DynMizePartGuard {
fn drop(&mut self) {
if self.part.is_none() {
return;
}
self.mize.give_back_part(self.part.take().unwrap());
}
}
@@ -311,6 +317,11 @@ impl Mize {
self.parts.lock().unwrap().insert(part.name(), Some(part));
Ok(())
}
pub fn register_part(&mut self, part: Box<dyn MizePart + Send + Sync>) -> MizeResult<()> {
self.part_names.lock().unwrap().push(part.name());
self.parts.lock().unwrap().insert(part.name(), Some(part));
Ok(())
}
fn part_names(&mut self) -> Vec<&'static str> {
self.part_names.lock().unwrap().clone()
}
@@ -854,3 +865,9 @@ impl fmt::Debug for Mize {
write!(f, "Mize Instance with subs: {:?}", self.subs,)
}
}
impl Default for Mize {
fn default() -> Self {
Self::empty().unwrap()
}
}

View File

@@ -1,5 +0,0 @@
[package]
name = "mize_parts"
version = "0.1.0"
edition = "2021"

View File

@@ -1,3 +0,0 @@
mod cli;
mod js;

View File

@@ -4,5 +4,14 @@ version = "0.1.0"
edition = "2024"
[dependencies]
mize = { path = "../../parts/mize" }
js_part = { path = "../../parts/js" }
mize = { path = "../mize" }
marts = { path = "../marts/" }
clap = "4.5.59"
[[bin]]
name = "ppc"
path = "src/platform/os/main.rs"
[features]
default = ["target-os"]
target-os = []

View File

@@ -1,31 +0,0 @@
use std::collections::HashMap;
use clap::crate_version;
use cli_part::Cli;
use config::Config;
use deno_part::JsPart;
use mize::{
DynMizePartGuard, Mize, MizeError, MizePart, MizePartGuard, MizeResult, add_parts, mize_err,
};
fn main() {
let mut mize = Mize::new();
add_parts!(&mut mize, Cli);
let cli = mize.get_part_native::<Cli>("cli");
cli.with_cmd(|cmd| {
cmd.version(crate_version!())
.name("ppc")
.author("ppc")
.about("the ppc desktop program")
});
cli.subcommand(Command::new("test"), |sub_matches| {
println!("test ppc...");
Ok(())
});
mize.run();
}

View File

@@ -0,0 +1,35 @@
use std::collections::HashMap;
use clap::Command;
use clap::crate_version;
use mize::{Mize, MizeResult};
fn main() {
let mut mize = Mize::new().expect("failed to create mize instance");
#[cfg(feature = "target-os")]
os_main(&mut mize);
mize.run();
}
#[cfg(feature = "target-os")]
fn os_main(mize: &mut Mize) -> MizeResult<()> {
marts::cli(mize)?;
let mut cli = mize.get_part_native::<marts::CliPart>("cli")?;
cli.with_cmd(|_, cmd| {
Ok(cmd
.version(crate_version!())
.name("ppc")
.author("ppc")
.about("the ppc desktop program"))
})?;
cli.subcommand(Command::new("test"), |_| {
println!("test ppc...");
Ok(())
});
Ok(())
}

View File

@@ -23,18 +23,18 @@ serde_json = "1.0.117"
tar = "0.4.44"
umask = "2.1.0"
#mize = { git = "https://github.com/c2vi/mize", default-features = false }
mize = { path = "/home/me/work/mize", default-features = false, features = ["os-target"] }
mize = { path = "../mize", default-features = false, features = ["os-target"] }
# snix testing
#snix-cli = { git = "https://git.snix.dev/snix/snix" }
snix-tracing = { path = "./gitignore/snix/snix/tracing" }
snix-cli = { path = "./gitignore/snix/snix/cli" }
snix-store = { path = "./gitignore/snix/snix/store", features = [ "xp-composition-cli" ] }
snix-castore = { path = "./gitignore/snix/snix/castore", features = ["xp-composition-cli", "xp-composition-url-refs" ] }
snix-eval = { path = "./gitignore/snix/snix/eval" }
snix-glue = { path = "./gitignore/snix/snix/glue" }
snix-build = { path = "./gitignore/snix/snix/build" }
nix-compat = { path = "./gitignore/snix/snix/nix-compat" }
#snix-tracing = { path = "./gitignore/snix/snix/tracing" }
#snix-cli = { path = "./gitignore/snix/snix/cli" }
#snix-store = { path = "./gitignore/snix/snix/store", features = [ "xp-composition-cli" ] }
#snix-castore = { path = "./gitignore/snix/snix/castore", features = ["xp-composition-cli", "xp-composition-url-refs" ] }
#snix-eval = { path = "./gitignore/snix/snix/eval" }
#snix-glue = { path = "./gitignore/snix/snix/glue" }
#snix-build = { path = "./gitignore/snix/snix/build" }
#nix-compat = { path = "./gitignore/snix/snix/nix-compat" }
tokio = "1.45.0"
tracing = "0.1.41"
tracing-indicatif = "0.3.9"