some MizePart stuff and other stuff
This commit is contained in:
4102
Cargo.lock
generated
Normal file
4102
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
7
Cargo.toml
Normal file
7
Cargo.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
"parts/js",
|
||||
"apps/ppc",
|
||||
"parts/mize"
|
||||
, "parts/cli"]
|
||||
8
apps/ppc/Cargo.toml
Normal file
8
apps/ppc/Cargo.toml
Normal file
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "ppc"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
mize = { path = "../../parts/mize" }
|
||||
js_part = { path = "../../parts/js" }
|
||||
20
apps/ppc/src/main.rs
Normal file
20
apps/ppc/src/main.rs
Normal file
@@ -0,0 +1,20 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use config::Config;
|
||||
use deno_part::JsPart;
|
||||
use mize::{Mize, MizeError, MizePart, MizeResult, add_parts, mize_err};
|
||||
use clap::crate_version;
|
||||
|
||||
fn main() {
|
||||
let mut mize = Mize::new();
|
||||
|
||||
add_parts!(&mut mize, Cli::new(&mut mize, "ppc"));
|
||||
let cli = Cli::get(&mut mize);
|
||||
cli.with_cmd(|cmd| cmd.version(crate_version!()).author("ppc").about("the ppc desktop program"));
|
||||
cli.subcommand("test", |sub_matches| {
|
||||
println!("test ppc...");
|
||||
Ok(())
|
||||
});
|
||||
|
||||
mize.run();
|
||||
}
|
||||
8
parts/cli/Cargo.toml
Normal file
8
parts/cli/Cargo.toml
Normal file
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "cli"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.5.57", features = ["cargo"] }
|
||||
mize = { path = "../../parts/mize"}
|
||||
72
parts/cli/src/lib.rs
Normal file
72
parts/cli/src/lib.rs
Normal file
@@ -0,0 +1,72 @@
|
||||
use clap::{ArgMatches, Command};
|
||||
use std::any::Any;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use mize::{Mize, MizePart, MizeResult, instance::MizePartGuard};
|
||||
|
||||
struct CliPart {
|
||||
mize: Mize,
|
||||
cmd: Option<Command>,
|
||||
actions: HashMap<String, fn(&ArgMatches) -> MizeResult<()>>,
|
||||
}
|
||||
|
||||
pub fn new(mize: Mize) -> CliPart {
|
||||
CliPart {
|
||||
mize,
|
||||
cmd: None,
|
||||
actions: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
impl MizePart for CliPart {
|
||||
fn name(&self) -> &'static str {
|
||||
"cli"
|
||||
}
|
||||
fn get_mize(&mut self) -> &mut Mize {
|
||||
&mut self.mize
|
||||
}
|
||||
fn init(&mut self, _mize: &mut Mize) -> MizeResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
fn opts(&self, mize: &mut Mize) {
|
||||
mize.new_opt("cli.name");
|
||||
}
|
||||
fn run(&mut self, _mize: &mut Mize) -> MizeResult<()> {
|
||||
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());
|
||||
Ok(())
|
||||
}
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
fn as_any_mut(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
fn into_any(self: Box<CliPart>) -> Box<dyn Any> {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl CliPart {
|
||||
pub fn subcommand(
|
||||
&mut self,
|
||||
cmd: 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);
|
||||
self.cmd = Some(cmd);
|
||||
self.cmd.as_mut().unwrap()
|
||||
}
|
||||
pub fn get(mize: &mut Mize) -> MizePartGuard<CliPart> {
|
||||
let mut dyn_guard = mize.get_part("cli").unwrap();
|
||||
let part = dyn_guard.part.take().unwrap();
|
||||
let cli_part = part.into_any().downcast::<CliPart>().unwrap();
|
||||
MizePartGuard {
|
||||
mize: dyn_guard.mize.clone(),
|
||||
part: Some(*cli_part),
|
||||
}
|
||||
}
|
||||
}
|
||||
9
parts/js/Cargo.toml
Normal file
9
parts/js/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "js_part"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
deno_core = "0.383.0"
|
||||
mize = { path = "../../parts/mize" }
|
||||
tokio = { version = "1.49.0", features = ["full"] }
|
||||
41
parts/js/src/lib.rs
Normal file
41
parts/js/src/lib.rs
Normal file
@@ -0,0 +1,41 @@
|
||||
use deno_core::error::AnyError;
|
||||
use mize::{Mize, MizePart, MizeResult};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct JsPart {
|
||||
mize: Mize,
|
||||
}
|
||||
|
||||
impl JsPart {
|
||||
pub fn new(mize: Mize) -> Self {
|
||||
JsPart { mize }
|
||||
}
|
||||
}
|
||||
|
||||
impl MizePart for JsPart {
|
||||
fn name(&self) -> &'static str {
|
||||
"js"
|
||||
}
|
||||
|
||||
fn get_mize(&mut self) -> &mut Mize {
|
||||
&mut self.mize
|
||||
}
|
||||
|
||||
fn init(&mut self, mize: &mut Mize) -> MizeResult<()> {
|
||||
println!("deno part init");
|
||||
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
|
||||
}
|
||||
@@ -1,10 +1,7 @@
|
||||
use std::process::Command;
|
||||
use std::env;
|
||||
//use std::env;
|
||||
|
||||
fn main() {
|
||||
|
||||
// compile the string plugin
|
||||
//let _out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
//let mut string_module = Command::new("bash");
|
||||
//string_module.arg("-c");
|
||||
//string_module.arg("echo hiiiiiiiiiiiiiiiii");
|
||||
@@ -24,5 +21,5 @@ fn main() {
|
||||
|
||||
//to outdir (), using the nightly feature --out-dir to have the result there. By default I get a libhearts.rlib
|
||||
|
||||
println!("cargo:rustc-link-arg=-zstack-size=0x1000000");
|
||||
//println!("cargo:rustc-link-arg=-zstack-size=0x1000000");
|
||||
}
|
||||
|
||||
42
parts/mize/flake.lock
generated
42
parts/mize/flake.lock
generated
@@ -2,11 +2,11 @@
|
||||
"nodes": {
|
||||
"crane": {
|
||||
"locked": {
|
||||
"lastModified": 1725125250,
|
||||
"narHash": "sha256-CB20rDD5eHikF6mMTTJdwPP1qvyoiyyw1RDUzwIaIF8=",
|
||||
"lastModified": 1769737823,
|
||||
"narHash": "sha256-DrBaNpZ+sJ4stXm+0nBX7zqZT9t9P22zbk6m5YhQxS4=",
|
||||
"owner": "ipetkov",
|
||||
"repo": "crane",
|
||||
"rev": "96fd12c7100e9e05fa1a0a5bd108525600ce282f",
|
||||
"rev": "b2f45c3830aa96b7456a4c4bc327d04d7a43e1ba",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -23,11 +23,11 @@
|
||||
"rust-analyzer-src": "rust-analyzer-src"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1748327829,
|
||||
"narHash": "sha256-TJwbWCsyT9yJkBRTnqKE/YDTiXuEdYHb37WLK4TcAwE=",
|
||||
"lastModified": 1770102568,
|
||||
"narHash": "sha256-VYwA9FmakKJ3zLfAd7bdj9xIB9PzfISLoYh6eZl+EuQ=",
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"rev": "26fbcc33a5e94d6d0dc5f467eca8f7a746a54e6c",
|
||||
"rev": "592daa37b5a3175c61541329b64d6c1972303bc1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -41,11 +41,11 @@
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1701680307,
|
||||
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -57,11 +57,11 @@
|
||||
"mize_modules": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1725362504,
|
||||
"narHash": "sha256-U0IQ+3SiyLb24BTDUvlnE30LdjjJWJ/P6dHPqxArJXk=",
|
||||
"lastModified": 1739053120,
|
||||
"narHash": "sha256-It6j1D3c3eO/O0ptHvZ3c9Ynei08DXX5n6DYonW3g+s=",
|
||||
"owner": "c2vi",
|
||||
"repo": "mize-modules",
|
||||
"rev": "fa3b462cbe3e63fc9ecada6c4445d366e58a6f86",
|
||||
"rev": "3bba470c849f7cbaf7eb7858c26aa1c64fd00b33",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -72,11 +72,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1703637592,
|
||||
"narHash": "sha256-8MXjxU0RfFfzl57Zy3OfXCITS0qWDNLzlBAdwxGZwfY=",
|
||||
"lastModified": 1770115704,
|
||||
"narHash": "sha256-KHFT9UWOF2yRPlAnSXQJh6uVcgNcWlFqqiAZ7OVlHNc=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "cfc3698c31b1fb9cdcf10f36c9643460264d0ca8",
|
||||
"rev": "e6eae2ee2110f3d31110d5c222cd395303343b08",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -99,11 +99,11 @@
|
||||
"rust-analyzer-src": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1748295258,
|
||||
"narHash": "sha256-ejRVtsT7fat4mGgDQpgIGKJP+vbr9r4Mo84jRb2bndk=",
|
||||
"lastModified": 1770026591,
|
||||
"narHash": "sha256-VZlloygYDmozJwbZZkCSNpiPhNdOW/AA0b6LmNBZ3xU=",
|
||||
"owner": "rust-lang",
|
||||
"repo": "rust-analyzer",
|
||||
"rev": "7fa66d67a72bcad236b50907e14f7464c47ecede",
|
||||
"rev": "74eca73f3b0a41b80228b8e499c7547cc8b2effa",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -120,11 +120,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1725157860,
|
||||
"narHash": "sha256-DhqyM7XJYKj+WAEaYwMtXaYX66tA+lOd31sd5QkxLDM=",
|
||||
"lastModified": 1770088046,
|
||||
"narHash": "sha256-4hfYDnUTvL1qSSZEA4CEThxfz+KlwSFQ30Z9jgDguO0=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "1fd72e343c6890f695243a37b367a1e3b90a49ee",
|
||||
"rev": "71f9daa4e05e49c434d08627e755495ae222bc34",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
46
parts/mize/src/core/config.rs
Normal file
46
parts/mize/src/core/config.rs
Normal file
@@ -0,0 +1,46 @@
|
||||
use crate::MizeResult;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
use crate::item::ItemData;
|
||||
use crate::Mize;
|
||||
|
||||
type ConfigThunk = Box<dyn Fn() -> ItemData + Send + Sync>;
|
||||
|
||||
pub struct ConfigOpt {
|
||||
pub name: String,
|
||||
pub val: Option<ItemData>,
|
||||
pub thunk: Option<ConfigThunk>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ConfigOptNameAndMize {
|
||||
pub name: String,
|
||||
pub mize: Mize,
|
||||
}
|
||||
|
||||
impl ConfigOptNameAndMize {
|
||||
pub fn default_val(self, val: ItemData) -> ConfigOptNameAndMize {
|
||||
let mut config_opts = self.mize.config_opts.lock().unwrap();
|
||||
let opt = config_opts.get_mut(&self.name).unwrap();
|
||||
opt.val = Some(val);
|
||||
self.clone()
|
||||
}
|
||||
pub fn fun(self, thunk: ConfigThunk) -> Self {
|
||||
let mut config_opts = self.mize.config_opts.lock().unwrap();
|
||||
let opt = config_opts.get_mut(&self.name).unwrap();
|
||||
opt.thunk = Some(thunk);
|
||||
self.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn gather_config(mize: &mut Mize) -> MizeResult<()> {
|
||||
let mut config_opts = mize.config_opts.lock().unwrap();
|
||||
let parts = mize.parts.lock().unwrap();
|
||||
|
||||
for part in parts.values() {
|
||||
part.as_deref().unwrap().opts(&mut mize.clone());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,16 +1,15 @@
|
||||
use colored::Colorize;
|
||||
use core::result::Result;
|
||||
use core::result::Result::Ok;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::format;
|
||||
use std::fmt::Debug;
|
||||
use std::fmt::Display;
|
||||
use std::fmt::format;
|
||||
use std::string::FromUtf8Error;
|
||||
use std::io;
|
||||
use colored::Colorize;
|
||||
use tracing::{trace, debug, info, warn, error};
|
||||
|
||||
use crate::proto::MizeMessage;
|
||||
use std::string::FromUtf8Error;
|
||||
use tracing::{debug, error, info, trace, warn};
|
||||
|
||||
//use crate::proto::MizeMessage;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! mize_err {
|
||||
@@ -26,7 +25,9 @@ pub trait MizeResultTrait<T> {
|
||||
|
||||
pub trait IntoMizeResult<T, S> {
|
||||
fn mize_result(self) -> MizeResult<T>;
|
||||
fn mize_result_msg(self, msg: S) -> MizeResult<T> where S: std::fmt::Display ;
|
||||
fn mize_result_msg(self, msg: S) -> MizeResult<T>
|
||||
where
|
||||
S: std::fmt::Display;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -34,16 +35,18 @@ pub struct MizeError {
|
||||
pub category: Vec<String>,
|
||||
pub code: u32,
|
||||
pub messages: Vec<String>,
|
||||
pub caused_by_msg: Option<CausedByMessage>,
|
||||
//pub caused_by_msg: Option<CausedByMessage>,
|
||||
pub code_location: Option<MizeCodeLocation>,
|
||||
pub backtrace: String,
|
||||
}
|
||||
|
||||
/*
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CausedByMessage {
|
||||
// peer: &Connection, // TODO: add later
|
||||
msg: Box<MizeMessage>,
|
||||
}
|
||||
*/
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MizeCodeLocation {
|
||||
@@ -54,16 +57,20 @@ pub struct MizeCodeLocation {
|
||||
|
||||
impl Display for MizeCodeLocation {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "file: {} line: {} column: {}", self.file, self.line, self.column)
|
||||
write!(
|
||||
f,
|
||||
"file: {} line: {} column: {}",
|
||||
self.file, self.line, self.column
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&std::panic::Location <'_>> for MizeCodeLocation {
|
||||
impl From<&std::panic::Location<'_>> for MizeCodeLocation {
|
||||
fn from(panic_location: &std::panic::Location) -> MizeCodeLocation {
|
||||
let file = panic_location.file().to_string();
|
||||
let line = panic_location.line();
|
||||
let column = panic_location.column();
|
||||
MizeCodeLocation {file, line, column}
|
||||
MizeCodeLocation { file, line, column }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,25 +95,28 @@ impl MizeError {
|
||||
category: Vec::new(),
|
||||
code: 0,
|
||||
messages: Vec::new(),
|
||||
caused_by_msg: None,
|
||||
code_location: Some(caller_location.into()),
|
||||
backtrace: format!("{}", std::backtrace::Backtrace::capture()),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn msg<E>(mut self, msg: E) -> MizeError
|
||||
where E: std::fmt::Display
|
||||
where
|
||||
E: std::fmt::Display,
|
||||
{
|
||||
self.messages.push(format!("{}", msg));
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn category<T>(mut self, category: T) -> MizeError where T: Into<String> {
|
||||
pub fn category<T>(mut self, category: T) -> MizeError
|
||||
where
|
||||
T: Into<String>,
|
||||
{
|
||||
self.category.push(category.into());
|
||||
return self;
|
||||
}
|
||||
|
||||
fn send(self) -> MizeError{
|
||||
fn send(self) -> MizeError {
|
||||
self
|
||||
}
|
||||
|
||||
@@ -134,15 +144,20 @@ impl MizeError {
|
||||
return self.send().add_to_err_item().log();
|
||||
}
|
||||
|
||||
pub fn critical(self){
|
||||
pub fn critical(self) {
|
||||
let mut msg_iter = self.messages.iter();
|
||||
match msg_iter.next() {
|
||||
None => {
|
||||
error!("{} MizeError with code: {}", "CRITICAL".red(), self.code);
|
||||
},
|
||||
}
|
||||
Some(msg) => {
|
||||
error!("{} MizeError with code: {} - {}", "CRITICAL".red(), self.code, msg);
|
||||
},
|
||||
error!(
|
||||
"{} MizeError with code: {} - {}",
|
||||
"CRITICAL".red(),
|
||||
self.code,
|
||||
msg
|
||||
);
|
||||
}
|
||||
}
|
||||
for msg in msg_iter {
|
||||
error!("{} {}", "MSG".red(), msg)
|
||||
@@ -150,23 +165,16 @@ impl MizeError {
|
||||
if let Some(location) = self.code_location {
|
||||
error!("{} {}", "LOCATION".red(), location)
|
||||
}
|
||||
if let Some(caused_by_msg) = self.caused_by_msg {
|
||||
error!("{} {:?}", "CAUSED_BY_MESSAGE".red(), caused_by_msg)
|
||||
}
|
||||
panic!();
|
||||
}
|
||||
|
||||
pub fn location(mut self, location: MizeCodeLocation) -> MizeError {
|
||||
|
||||
self.code_location = Some(location);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
pub trait MizeResultExtension<T> {
|
||||
fn extra_msg<E>(self, msg: E) -> Result<T, MizeError>
|
||||
@@ -221,70 +229,90 @@ impl<T: Display> From<T> for MizeError {
|
||||
fn from(value: T) -> Self {
|
||||
let caller_location = std::panic::Location::caller();
|
||||
MizeError::new()
|
||||
.msg(format!("From {}: {}", std::any::type_name_of_val(&value), value))
|
||||
.msg(format!(
|
||||
"From {}: {}",
|
||||
std::any::type_name_of_val(&value),
|
||||
value
|
||||
))
|
||||
.location(caller_location.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl <T> MizeResultTrait<T> for MizeResult<T> {
|
||||
impl<T> MizeResultTrait<T> for MizeResult<T> {
|
||||
fn critical(self) -> T {
|
||||
match self {
|
||||
Ok(val) => val,
|
||||
Err(err) => {
|
||||
err.critical();
|
||||
unreachable!()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
fn as_std(self) -> Result<T, MizeErrorWhichImplementsError> {
|
||||
match self {
|
||||
Ok(val) => Ok(val),
|
||||
Err(err) => {
|
||||
Err(MizeErrorWhichImplementsError { inner: err })
|
||||
},
|
||||
Err(err) => Err(MizeErrorWhichImplementsError { inner: err }),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E, S> IntoMizeResult<T, S> for Result<T, E> where E: std::fmt::Display {
|
||||
impl<T, E, S> IntoMizeResult<T, S> for Result<T, E>
|
||||
where
|
||||
E: std::fmt::Display,
|
||||
{
|
||||
#[track_caller]
|
||||
fn mize_result(self) -> MizeResult<T> {
|
||||
let caller_location = std::panic::Location::caller();
|
||||
|
||||
match self {
|
||||
Ok(val) => MizeResult::Ok(val),
|
||||
Err(err) => MizeResult::Err(MizeError::new()
|
||||
.category("misc")
|
||||
.msg(format!("From {}: {}", std::any::type_name_of_val(&err), err))),
|
||||
Err(err) => MizeResult::Err(MizeError::new().category("misc").msg(format!(
|
||||
"From {}: {}",
|
||||
std::any::type_name_of_val(&err),
|
||||
err
|
||||
))),
|
||||
}
|
||||
}
|
||||
#[track_caller]
|
||||
fn mize_result_msg(self, msg: S) -> MizeResult<T> where S: std::fmt::Display {
|
||||
fn mize_result_msg(self, msg: S) -> MizeResult<T>
|
||||
where
|
||||
S: std::fmt::Display,
|
||||
{
|
||||
let caller_location = std::panic::Location::caller();
|
||||
match self {
|
||||
Ok(val) => MizeResult::Ok(val),
|
||||
Err(err) => MizeResult::Err(MizeError::new()
|
||||
Err(err) => MizeResult::Err(
|
||||
MizeError::new()
|
||||
.category("misc")
|
||||
.msg(format!("{}", msg))
|
||||
.msg(format!("From {}: {}", std::any::type_name_of_val(&err), err))),
|
||||
.msg(format!(
|
||||
"From {}: {}",
|
||||
std::any::type_name_of_val(&err),
|
||||
err
|
||||
)),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn get_error_by_code(code: u32, caller_location: &std::panic::Location) -> MizeError {
|
||||
let err = MizeError {
|
||||
category: Vec::new(),
|
||||
code: 0,
|
||||
messages: Vec::new(),
|
||||
caused_by_msg: None,
|
||||
code_location: Some(caller_location.into()),
|
||||
backtrace: format!("{}", std::backtrace::Backtrace::capture()),
|
||||
};
|
||||
|
||||
match code {
|
||||
109 => err.set_code(109).category("decoding").msg("conversion from utf8 failed"),
|
||||
108 => err.set_code(108).category("decoding").msg("serde deserialisation failed"),
|
||||
109 => err
|
||||
.set_code(109)
|
||||
.category("decoding")
|
||||
.msg("conversion from utf8 failed"),
|
||||
108 => err
|
||||
.set_code(108)
|
||||
.category("decoding")
|
||||
.msg("serde deserialisation failed"),
|
||||
_ => err,
|
||||
}
|
||||
}
|
||||
@@ -305,7 +333,7 @@ impl Display for MizeErrorWhichImplementsError {
|
||||
write!(f, "[ {} ] {}", "BACKTRACE".yellow(), self.inner.backtrace);
|
||||
|
||||
for msg in &self.inner.messages {
|
||||
write!(f,"[ {} ] {}", "MSG".yellow(), msg);
|
||||
write!(f, "[ {} ] {}", "MSG".yellow(), msg);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -318,5 +346,3 @@ impl From<MizeError> for MizeErrorWhichImplementsError {
|
||||
}
|
||||
|
||||
impl std::error::Error for MizeErrorWhichImplementsError {}
|
||||
|
||||
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
use core::fmt;
|
||||
use std::{collections::binary_heap::Iter, fmt::write, hash::Hash};
|
||||
use interner::{shared::{SharedPool, SharedString, SharedVecString}, Pooled};
|
||||
use interner::{
|
||||
shared::{SharedPool, SharedString, SharedVecString},
|
||||
Pooled,
|
||||
};
|
||||
use std::collections::hash_map::RandomState;
|
||||
use std::path::Path;
|
||||
use std::{collections::binary_heap::Iter, fmt::write, hash::Hash};
|
||||
|
||||
use crate::{instance::{store::Store, Instance}, mize_err};
|
||||
use crate::error::{MizeResult, MizeError, MizeResultTrait};
|
||||
use crate::error::{MizeError, MizeResult, MizeResultTrait};
|
||||
use crate::{
|
||||
instance::{store::Store, Mize},
|
||||
mize_err,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
|
||||
pub struct MizeId {
|
||||
@@ -14,7 +20,7 @@ pub struct MizeId {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
|
||||
pub struct Namespace ( pub SharedString );
|
||||
pub struct Namespace(pub SharedString);
|
||||
|
||||
impl Namespace {
|
||||
pub fn as_string(&self) -> SharedString {
|
||||
@@ -28,14 +34,16 @@ impl Namespace {
|
||||
}
|
||||
|
||||
pub trait IntoMizeId {
|
||||
fn to_mize_id(self, instance: &Instance) -> MizeResult<MizeId>;
|
||||
fn to_mize_id(self, instance: &Mize) -> MizeResult<MizeId>;
|
||||
}
|
||||
|
||||
|
||||
impl MizeId {
|
||||
pub fn store_part(&self) -> &str {
|
||||
self.path.iter().nth(0)
|
||||
.expect("an empty MizeId found, that should absolutely not be possible!!!!").as_str()
|
||||
self.path
|
||||
.iter()
|
||||
.nth(0)
|
||||
.expect("an empty MizeId found, that should absolutely not be possible!!!!")
|
||||
.as_str()
|
||||
}
|
||||
|
||||
pub fn nth_part(&self, n: usize) -> MizeResult<&str> {
|
||||
@@ -74,34 +82,37 @@ impl fmt::Display for MizeId {
|
||||
}
|
||||
|
||||
impl IntoMizeId for &str {
|
||||
fn to_mize_id(self, instance: &Instance) -> MizeResult<MizeId> {
|
||||
fn to_mize_id(self, instance: &Mize) -> MizeResult<MizeId> {
|
||||
instance.id_from_string(self.to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoMizeId for String {
|
||||
fn to_mize_id(self, instance: &Instance) -> MizeResult<MizeId> {
|
||||
fn to_mize_id(self, instance: &Mize) -> MizeResult<MizeId> {
|
||||
instance.id_from_string(self)
|
||||
}
|
||||
}
|
||||
impl IntoMizeId for &String {
|
||||
fn to_mize_id(self, instance: &Instance) -> MizeResult<MizeId> {
|
||||
fn to_mize_id(self, instance: &Mize) -> MizeResult<MizeId> {
|
||||
instance.id_from_string(self.to_owned())
|
||||
}
|
||||
}
|
||||
impl IntoMizeId for Vec<String> {
|
||||
fn to_mize_id(self, instance: &Instance) -> MizeResult<MizeId> {
|
||||
fn to_mize_id(self, instance: &Mize) -> MizeResult<MizeId> {
|
||||
instance.id_from_vec_string(self)
|
||||
}
|
||||
}
|
||||
impl IntoMizeId for Vec<&String> {
|
||||
fn to_mize_id(self, instance: &Instance) -> MizeResult<MizeId> {
|
||||
let owned = self.into_iter().map(|s| s.to_owned()).collect::<Vec<String>>();
|
||||
fn to_mize_id(self, instance: &Mize) -> MizeResult<MizeId> {
|
||||
let owned = self
|
||||
.into_iter()
|
||||
.map(|s| s.to_owned())
|
||||
.collect::<Vec<String>>();
|
||||
instance.id_from_vec_string(owned)
|
||||
}
|
||||
}
|
||||
impl IntoMizeId for &[&str] {
|
||||
fn to_mize_id(self, instance: &Instance) -> MizeResult<MizeId> {
|
||||
fn to_mize_id(self, instance: &Mize) -> MizeResult<MizeId> {
|
||||
let mut vec: Vec<String> = Vec::new();
|
||||
for i in self {
|
||||
vec.push((*i).to_owned())
|
||||
@@ -110,7 +121,7 @@ impl IntoMizeId for &[&str] {
|
||||
}
|
||||
}
|
||||
impl IntoMizeId for Vec<&str> {
|
||||
fn to_mize_id(self, instance: &Instance) -> MizeResult<MizeId> {
|
||||
fn to_mize_id(self, instance: &Mize) -> MizeResult<MizeId> {
|
||||
let mut vec: Vec<String> = Vec::new();
|
||||
for i in self {
|
||||
vec.push((*i).to_owned())
|
||||
@@ -119,7 +130,7 @@ impl IntoMizeId for Vec<&str> {
|
||||
}
|
||||
}
|
||||
impl IntoMizeId for MizeId {
|
||||
fn to_mize_id(self, instance: &Instance) -> MizeResult<MizeId> {
|
||||
fn to_mize_id(self, instance: &Mize) -> MizeResult<MizeId> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
@@ -127,33 +138,41 @@ impl IntoMizeId for MizeId {
|
||||
// would only work with a global id_pool
|
||||
// for now use Instance::new_id()
|
||||
//impl<T: Into<String>> From<T> for MizeId {
|
||||
//fn from(value: T) -> Self {
|
||||
//let string = value.into();
|
||||
//let path: Vec<String> = string.split("/").map(|v| v.to_owned()).collect();
|
||||
//return MizeId { MIZE_ID_POOL.get(path) }
|
||||
//}
|
||||
//fn from(value: T) -> Self {
|
||||
//let string = value.into();
|
||||
//let path: Vec<String> = string.split("/").map(|v| v.to_owned()).collect();
|
||||
//return MizeId { MIZE_ID_POOL.get(path) }
|
||||
//}
|
||||
//}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::instance::Instance;
|
||||
use crate::instance::Mize;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_id() -> MizeResult<()> {
|
||||
let instance = Instance::empty()?;
|
||||
let instance = Mize::empty()?;
|
||||
|
||||
let id_one = instance.new_id("0/config/hi")?;
|
||||
assert_eq!(instance.get_namespace()?, id_one.namespace());
|
||||
assert_eq!("0", id_one.store_part());
|
||||
assert_eq!(vec!["config".to_owned(), "hi".to_owned()], id_one.after_store_part());
|
||||
assert_eq!(
|
||||
vec!["config".to_owned(), "hi".to_owned()],
|
||||
id_one.after_store_part()
|
||||
);
|
||||
|
||||
let id_two = instance.new_id("test.ns:hello/config/hi")?;
|
||||
assert_eq!(instance.namespace_from_string("test.ns".to_owned())?, id_two.namespace());
|
||||
assert_eq!(
|
||||
instance.namespace_from_string("test.ns".to_owned())?,
|
||||
id_two.namespace()
|
||||
);
|
||||
assert_eq!("hello", id_two.store_part());
|
||||
assert_eq!(vec!["config".to_owned(), "hi".to_owned()], id_one.after_store_part());
|
||||
assert_eq!(
|
||||
vec!["config".to_owned(), "hi".to_owned()],
|
||||
id_one.after_store_part()
|
||||
);
|
||||
|
||||
let id_three = instance.new_id("0/")?;
|
||||
assert_eq!(instance.get_namespace()?, id_three.namespace());
|
||||
@@ -161,7 +180,10 @@ mod test {
|
||||
assert_eq!(Vec::<String>::new(), id_three.after_store_part());
|
||||
|
||||
let id_four = instance.new_id("test.ns:0/")?;
|
||||
assert_eq!(instance.namespace_from_string("test.ns".to_owned())?, id_four.namespace());
|
||||
assert_eq!(
|
||||
instance.namespace_from_string("test.ns".to_owned())?,
|
||||
id_four.namespace()
|
||||
);
|
||||
assert_eq!("0", id_four.store_part());
|
||||
assert_eq!(Vec::<String>::new(), id_four.after_store_part());
|
||||
|
||||
@@ -172,9 +194,6 @@ mod test {
|
||||
|
||||
//TODO: add the parsing form mize:// urls....
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use flume::{Sender, Receiver};
|
||||
use tracing::{trace, debug, info, warn, error};
|
||||
use flume::{Receiver, Sender};
|
||||
use tracing::{debug, error, info, trace, warn};
|
||||
|
||||
use crate::error::{IntoMizeResult, MizeError, MizeResult};
|
||||
use crate::id::Namespace;
|
||||
use crate::mize_err;
|
||||
use crate::proto::MizeMessage;
|
||||
use crate::error::{MizeError, MizeResult, IntoMizeResult};
|
||||
|
||||
use super::Instance;
|
||||
use super::Mize;
|
||||
use crate::item::{get_raw_from_cbor, Item, ItemData};
|
||||
|
||||
// only created with Instance::new_connection()
|
||||
@@ -17,8 +17,8 @@ pub struct Connection {
|
||||
pub ns: Option<Namespace>,
|
||||
}
|
||||
|
||||
pub trait ConnListener : Send + Sync {
|
||||
fn listen(self, instance: Instance) -> MizeResult<()>;
|
||||
pub trait ConnListener: Send + Sync {
|
||||
fn listen(self, instance: Mize) -> MizeResult<()>;
|
||||
}
|
||||
|
||||
impl Connection {
|
||||
@@ -39,7 +39,7 @@ pub fn value_raw_from_peer(item: &mut Item) -> MizeResult<ItemData> {
|
||||
let id = item.id();
|
||||
|
||||
let conn_id_str = id.nth_part(2)?;
|
||||
let conn_id : u64 = conn_id_str.parse()?;
|
||||
let conn_id: u64 = conn_id_str.parse()?;
|
||||
let tmp_path = id.path();
|
||||
let mut new_id_str = tmp_path.into_iter();
|
||||
let skipped = new_id_str.skip(4);
|
||||
@@ -55,5 +55,3 @@ pub fn value_raw_from_peer(item: &mut Item) -> MizeResult<ItemData> {
|
||||
|
||||
return Ok(data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,46 +1,48 @@
|
||||
use colored::Colorize;
|
||||
use core::fmt;
|
||||
use flume::{bounded, unbounded, Receiver, Sender};
|
||||
use interner::shared::{StringPool, VecStringPool};
|
||||
use std::any::Any;
|
||||
use std::collections::HashMap;
|
||||
use std::fs::create_dir;
|
||||
use std::{thread, vec};
|
||||
use flume::{bounded, Receiver, Sender, unbounded};
|
||||
use std::fs::File;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::{thread, vec};
|
||||
use tracing::{debug, error, info, trace, warn, Instrument};
|
||||
use uuid::Uuid;
|
||||
use std::fs::File;
|
||||
use colored::Colorize;
|
||||
use std::path::{Path, PathBuf};
|
||||
use interner::shared::{VecStringPool, StringPool};
|
||||
|
||||
|
||||
use crate::error::{MizeError, MizeResult, IntoMizeResult, MizeResultTrait};
|
||||
use crate::instance::store::Store;
|
||||
use crate::instance::updater::{ updater_thread, updater_thread_async };
|
||||
use crate::config::ConfigOptNameAndMize;
|
||||
use crate::config::{gather_config, ConfigOpt};
|
||||
use crate::error::{IntoMizeResult, MizeError, MizeResult, MizeResultTrait};
|
||||
use crate::id::{IntoMizeId, MizeId, Namespace};
|
||||
use crate::instance::store::Store;
|
||||
use crate::instance::subscription::Subscription;
|
||||
use crate::instance::updater::Operation;
|
||||
use crate::instance::updater::{updater_thread, updater_thread_async};
|
||||
use crate::item::{Item, ItemData};
|
||||
use crate::memstore::MemStore;
|
||||
use crate::instance::updater::Operation;
|
||||
use crate::{mize_err, Module};
|
||||
use crate::proto::MizeMessage;
|
||||
use crate::{mize_err, Module};
|
||||
|
||||
use self::connection::{ConnListener, Connection};
|
||||
use self::updater::handle_operation;
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
use tokio::runtime::Runtime;
|
||||
#[cfg(feature = "async")]
|
||||
use tokio::runtime::Handle;
|
||||
#[cfg(feature = "async")]
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
use core::future::Future;
|
||||
use std::thread::JoinHandle;
|
||||
|
||||
pub mod connection;
|
||||
pub mod module;
|
||||
pub mod msg_thread;
|
||||
pub mod store;
|
||||
pub mod subscription;
|
||||
pub mod updater;
|
||||
pub mod msg_thread;
|
||||
pub mod module;
|
||||
|
||||
|
||||
// console_log macro
|
||||
// that can be copied into other files for debugging purposes
|
||||
@@ -61,8 +63,17 @@ macro_rules! console_log {
|
||||
($($t:tt)*) => (unsafe { log(&format_args!($($t)*).to_string())})
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! add_parts {
|
||||
($mize:expr, $($part:expr),+) => {
|
||||
$(
|
||||
$mize.add_part(
|
||||
Box::new($part)
|
||||
);
|
||||
)+
|
||||
mize.init_parts();
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
@@ -73,16 +84,22 @@ static BUILD_TIME_CONFIG: &str = include_str!(std::env!("MIZE_BUILD_CONFIG"));
|
||||
|
||||
/// The Instance type is the heart of the mize system
|
||||
#[derive(Clone)]
|
||||
pub struct Instance {
|
||||
// a bit a lot of Mutexes isn-it???
|
||||
pub struct Mize {
|
||||
// a bit a lot of Mutexes isn't it???
|
||||
pub store: Arc<Mutex<Box<dyn Store>>>,
|
||||
connections: Arc<Mutex<Vec<Connection>>>,
|
||||
next_con_id: Arc<Mutex<u64>>,
|
||||
subs: Arc<Mutex<HashMap<MizeId, Vec<Subscription>>>>,
|
||||
pub modules: Arc<Mutex<HashMap<String, Box<dyn Module + Sync + Send >>>>,
|
||||
pub modules: Arc<Mutex<HashMap<String, Box<dyn Module + Sync + Send>>>>,
|
||||
pub id_pool: Arc<Mutex<VecStringPool>>,
|
||||
pub namespace_pool: Arc<Mutex<StringPool>>,
|
||||
|
||||
pub(crate) parts: Arc<Mutex<HashMap<&'static str, Option<Box<dyn MizePart + Sync + Send>>>>>,
|
||||
|
||||
part_names: Arc<Mutex<Vec<&'static str>>>,
|
||||
|
||||
pub config_opts: Arc<Mutex<HashMap<String, ConfigOpt>>>,
|
||||
|
||||
// the namespace the instance operates in
|
||||
pub namespace: Arc<Mutex<Namespace>>,
|
||||
|
||||
@@ -100,18 +117,84 @@ pub struct Instance {
|
||||
}
|
||||
|
||||
pub struct InstanceRef {
|
||||
inner: Arc<Mutex<Instance>>,
|
||||
inner: Arc<Mutex<Mize>>,
|
||||
}
|
||||
|
||||
pub struct InstanceAsync {
|
||||
inner: Arc<Mutex<Instance>>,
|
||||
inner: Arc<Mutex<Mize>>,
|
||||
}
|
||||
|
||||
pub struct DynMizePartGuard {
|
||||
pub mize: Mize,
|
||||
pub part: Option<Box<dyn MizePart + Send + Sync>>,
|
||||
}
|
||||
|
||||
impl Instance {
|
||||
pub fn empty() -> MizeResult<Instance> {
|
||||
pub struct MizePartGuard<T: MizePart + Send + Sync> {
|
||||
pub mize: Mize,
|
||||
pub part: Option<T>,
|
||||
}
|
||||
|
||||
impl<T: MizePart + Send + Sync + Deref<Target = T>> Deref for MizePartGuard<T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&*self.part.as_deref().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: MizePart + Send + Sync + DerefMut<Target = T>> DerefMut for MizePartGuard<T> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut *self.part.as_deref_mut().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: MizePart + Send + Sync> Drop for MizePartGuard<T> {
|
||||
fn drop(&mut self) {
|
||||
let part = self.part.take().unwrap();
|
||||
self.mize.give_back_part(Box::new(part));
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for DynMizePartGuard {
|
||||
type Target = dyn MizePart + Send + Sync;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&*self.part.as_deref().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for DynMizePartGuard {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut *self.part.as_deref_mut().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for DynMizePartGuard {
|
||||
fn drop(&mut self) {
|
||||
self.mize.give_back_part(self.part.take().unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
pub trait MizePart: Any + Send + Sync {
|
||||
fn name(&self) -> &'static str;
|
||||
fn get_mize(&mut self) -> &mut Mize;
|
||||
fn init(&mut self, mize: &mut Mize) -> MizeResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
fn run(&mut self, mize: &mut Mize) -> MizeResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
fn deps(&self) -> &'static [&'static str] {
|
||||
&[]
|
||||
}
|
||||
fn opts(&self, mize: &mut Mize) {}
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
fn as_any_mut(&self) -> &dyn Any;
|
||||
fn into_any(self: Box<Self>) -> Box<dyn Any>;
|
||||
}
|
||||
|
||||
impl Mize {
|
||||
pub fn empty() -> MizeResult<Mize> {
|
||||
let id_pool = Arc::new(Mutex::new(VecStringPool::default()));
|
||||
let namespace_pool_raw = StringPool::default();
|
||||
let connections = Arc::new(Mutex::new(Vec::new()));
|
||||
@@ -119,27 +202,38 @@ impl Instance {
|
||||
let (op_tx, op_rx) = unbounded();
|
||||
let give_msg_wait = Arc::new(Mutex::new(HashMap::new()));
|
||||
let create_msg_wait = Arc::new(Mutex::new(None));
|
||||
let namespace = Arc::new(Mutex::new(Namespace ( namespace_pool_raw.get("mize.default.namespace") )));
|
||||
let self_namespace = Arc::new(Mutex::new(Namespace ( namespace_pool_raw.get("mize.default.namespace") )));
|
||||
let namespace = Arc::new(Mutex::new(Namespace(
|
||||
namespace_pool_raw.get("mize.default.namespace"),
|
||||
)));
|
||||
let self_namespace = Arc::new(Mutex::new(Namespace(
|
||||
namespace_pool_raw.get("mize.default.namespace"),
|
||||
)));
|
||||
|
||||
|
||||
let mut instance = Instance {
|
||||
let mut instance = Mize {
|
||||
store: Arc::new(Mutex::new(Box::new(MemStore::new()))),
|
||||
connections, subs, id_pool,
|
||||
namespace, self_namespace, op_tx,
|
||||
parts: Arc::new(Mutex::new(HashMap::new())),
|
||||
part_names: Arc::new(Mutex::new(Vec::new())),
|
||||
config_opts: Arc::new(Mutex::new(HashMap::new())),
|
||||
connections,
|
||||
subs,
|
||||
id_pool,
|
||||
namespace,
|
||||
self_namespace,
|
||||
op_tx,
|
||||
namespace_pool: Arc::new(Mutex::new(namespace_pool_raw)),
|
||||
modules: Arc::new(Mutex::new(HashMap::new())),
|
||||
threads: Arc::new(Mutex::new(Vec::new())),
|
||||
next_thread_id: Arc::new(Mutex::new(0)),
|
||||
next_con_id: Arc::new(Mutex::new(1)),
|
||||
give_msg_wait, create_msg_wait,
|
||||
give_msg_wait,
|
||||
create_msg_wait,
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
runtime: Arc::new(Mutex::new(Runtime::new().mize_result_msg("Could not create async runtime")?)),
|
||||
runtime: Arc::new(Mutex::new(
|
||||
Runtime::new().mize_result_msg("Could not create async runtime")?,
|
||||
)),
|
||||
};
|
||||
|
||||
|
||||
|
||||
#[cfg(feature = "os-target")]
|
||||
{
|
||||
let instance_clone = instance.clone();
|
||||
@@ -152,7 +246,6 @@ impl Instance {
|
||||
instance.spawn("updater_thread", closure_two)?;
|
||||
}
|
||||
|
||||
|
||||
// set up async update "threads" when using wasm
|
||||
#[cfg(feature = "wasm-target")]
|
||||
{
|
||||
@@ -180,34 +273,55 @@ impl Instance {
|
||||
#[cfg(feature = "wasm-target")]
|
||||
console_log!("after loading build time config");
|
||||
|
||||
|
||||
return Ok(instance);
|
||||
}
|
||||
|
||||
pub fn new() -> MizeResult<Instance> {
|
||||
pub fn new() -> MizeResult<Mize> {
|
||||
trace!("[ {} ] Instance::new()", "CALL".yellow());
|
||||
|
||||
|
||||
let mut instance = Instance::empty()?;
|
||||
|
||||
let mut instance = Mize::empty()?;
|
||||
|
||||
instance.init();
|
||||
|
||||
|
||||
debug!("instance inited with config: {}", instance.get("0/config")?.as_data_full()?);
|
||||
|
||||
debug!(
|
||||
"instance inited with config: {}",
|
||||
instance.get("0/config")?.as_data_full()?
|
||||
);
|
||||
|
||||
return Ok(instance);
|
||||
}
|
||||
|
||||
pub fn get_part(&mut self, name: &str) -> MizeResult<DynMizePartGuard> {
|
||||
match self.parts.lock().unwrap().get_mut(name) {
|
||||
Some(part) => Ok(DynMizePartGuard {
|
||||
part: Some(part.take().unwrap()),
|
||||
mize: self.clone(),
|
||||
}),
|
||||
None => Err(mize_err!("Part not found or currently taken")),
|
||||
}
|
||||
}
|
||||
pub fn add_part(&mut self, part: Box<dyn MizePart>) -> 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()
|
||||
}
|
||||
|
||||
pub(crate) fn give_back_part(&mut self, part: Box<dyn MizePart + Send + Sync>) {
|
||||
self.parts.lock().unwrap().insert(part.name(), Some(part));
|
||||
}
|
||||
|
||||
pub fn init(&mut self) -> MizeResult<()> {
|
||||
// gather options
|
||||
gather_config(self)?;
|
||||
|
||||
// platform specific init code
|
||||
crate::platform::any::instance_init(self)?;
|
||||
|
||||
// end of platform specific init code
|
||||
|
||||
|
||||
// load the modules, ad specified in the load_modules config
|
||||
match self.get("0/config/load_modules")?.value_string() {
|
||||
Ok(modules_to_load) => {
|
||||
@@ -216,23 +330,21 @@ impl Instance {
|
||||
console_log!("loading module in Instance::init() ... {}", module);
|
||||
self.load_module(module)?;
|
||||
}
|
||||
},
|
||||
}
|
||||
Err(err) => {
|
||||
// no load_modules option is set
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
debug!("INSTANCE INIT DONE");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn with_config(config: ItemData) -> MizeResult<Instance> {
|
||||
pub fn with_config(config: ItemData) -> MizeResult<Mize> {
|
||||
trace!("[ {} ] Instance::with_config()", "CALL".yellow());
|
||||
trace!("config: {}", config);
|
||||
|
||||
let mut instance = Instance::empty()?;
|
||||
let mut instance = Mize::empty()?;
|
||||
|
||||
instance.set_blocking("0", config);
|
||||
|
||||
@@ -254,7 +366,7 @@ impl Instance {
|
||||
|
||||
let id_of_new_store = new_store.new_id()?;
|
||||
new_store.set(self.id_from_string(id_of_new_store)?, data.to_owned())?;
|
||||
};
|
||||
}
|
||||
|
||||
*old_store = new_store;
|
||||
|
||||
@@ -298,8 +410,15 @@ impl Instance {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_blocking<I: IntoMizeId, V: Into<ItemData>>(&self, id: I, value: V) -> MizeResult<()> {
|
||||
handle_operation(&mut Operation::Set(id.to_mize_id(self)?, value.into(), None), self)?;
|
||||
pub fn set_blocking<I: IntoMizeId, V: Into<ItemData>>(
|
||||
&self,
|
||||
id: I,
|
||||
value: V,
|
||||
) -> MizeResult<()> {
|
||||
handle_operation(
|
||||
&mut Operation::Set(id.to_mize_id(self)?, value.into(), None),
|
||||
self,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -309,7 +428,7 @@ impl Instance {
|
||||
match subs_inner.get_mut(&id) {
|
||||
Some(vec) => {
|
||||
vec.push(sub);
|
||||
},
|
||||
}
|
||||
None => {
|
||||
subs_inner.insert(id.clone(), vec![sub]);
|
||||
}
|
||||
@@ -330,26 +449,43 @@ impl Instance {
|
||||
}
|
||||
|
||||
pub fn id_from_string(&self, string: String) -> MizeResult<MizeId> {
|
||||
let vec_string: Vec<String> = string.split("/").map(|v| v.to_owned()).filter(|el| el.as_str() != "").collect();
|
||||
let vec_string: Vec<String> = string
|
||||
.split("/")
|
||||
.map(|v| v.to_owned())
|
||||
.filter(|el| el.as_str() != "")
|
||||
.collect();
|
||||
self.id_from_vec_string(vec_string)
|
||||
}
|
||||
|
||||
pub fn id_from_vec_string(&self, mut vec_string: Vec<String>) -> MizeResult<MizeId> {
|
||||
let id_pool_inner = self.id_pool.lock()?;
|
||||
let namespace_inner = self.namespace.lock()?;
|
||||
let first_el = vec_string.first_mut().ok_or(mize_err!("MizeId was empty"))?;
|
||||
let first_el = vec_string
|
||||
.first_mut()
|
||||
.ok_or(mize_err!("MizeId was empty"))?;
|
||||
|
||||
let id = if first_el.contains(":") { // first el is a namespace + store_part
|
||||
let id = if first_el.contains(":") {
|
||||
// first el is a namespace + store_part
|
||||
let new_first_el = first_el.clone();
|
||||
let vec: Vec<&str> = new_first_el.split(":").collect();
|
||||
let ns_part = vec.iter().nth(0).ok_or(mize_err!("should really not happen"))?;
|
||||
let store_part = vec.iter().nth(1).ok_or(mize_err!("mizeid was like 'namespace:/hi', why are you doing that"))?;
|
||||
let ns_part = vec
|
||||
.iter()
|
||||
.nth(0)
|
||||
.ok_or(mize_err!("should really not happen"))?;
|
||||
let store_part = vec.iter().nth(1).ok_or(mize_err!(
|
||||
"mizeid was like 'namespace:/hi', why are you doing that"
|
||||
))?;
|
||||
*first_el = store_part.to_owned().to_owned();
|
||||
|
||||
MizeId { path: id_pool_inner.get(vec_string), namespace: self.namespace_from_string(ns_part.to_owned().to_owned())? }
|
||||
MizeId {
|
||||
path: id_pool_inner.get(vec_string),
|
||||
namespace: self.namespace_from_string(ns_part.to_owned().to_owned())?,
|
||||
}
|
||||
} else {
|
||||
|
||||
MizeId { path: id_pool_inner.get(vec_string), namespace: namespace_inner.clone() }
|
||||
MizeId {
|
||||
path: id_pool_inner.get(vec_string),
|
||||
namespace: namespace_inner.clone(),
|
||||
}
|
||||
};
|
||||
trace!("new MizeId made: {:?}", id);
|
||||
|
||||
@@ -373,14 +509,17 @@ impl Instance {
|
||||
pub fn get_module(&mut self, name: &str) -> MizeResult<Box<dyn Module + Send + Sync>> {
|
||||
let inner = self.modules.lock()?;
|
||||
|
||||
let module = inner.get(name).ok_or(mize_err!("Couldn't get_module('{name}')"))?.clone_module();
|
||||
let module = inner
|
||||
.get(name)
|
||||
.ok_or(mize_err!("Couldn't get_module('{name}')"))?
|
||||
.clone_module();
|
||||
|
||||
Ok(module)
|
||||
}
|
||||
|
||||
pub fn namespace_from_string(&self, ns_str: String) -> MizeResult<Namespace> {
|
||||
let namespace_pool_inner = self.namespace_pool.lock()?;
|
||||
let namespace = Namespace ( namespace_pool_inner.get(ns_str) );
|
||||
let namespace = Namespace(namespace_pool_inner.get(ns_str));
|
||||
Ok(namespace)
|
||||
}
|
||||
|
||||
@@ -405,7 +544,7 @@ impl Instance {
|
||||
Ok(self.get_namespace()? == self.get_self_namespace()?)
|
||||
}
|
||||
|
||||
pub fn add_listener<T: ConnListener +'static>(&mut self, listener: T) -> MizeResult<()> {
|
||||
pub fn add_listener<T: ConnListener + 'static>(&mut self, listener: T) -> MizeResult<()> {
|
||||
let mut instance_clone = self.clone();
|
||||
self.spawn("some_listener", move || listener.listen(instance_clone));
|
||||
Ok(())
|
||||
@@ -416,7 +555,11 @@ impl Instance {
|
||||
let mut next_con_id = self.next_con_id.lock()?;
|
||||
let old_next_con_id = *next_con_id;
|
||||
|
||||
let connection = Connection { id: next_con_id.to_owned(), tx, ns: None};
|
||||
let connection = Connection {
|
||||
id: next_con_id.to_owned(),
|
||||
tx,
|
||||
ns: None,
|
||||
};
|
||||
conn_inner.push(connection);
|
||||
*next_con_id += 1;
|
||||
Ok(old_next_con_id)
|
||||
@@ -425,7 +568,12 @@ impl Instance {
|
||||
pub fn new_connection_join_namespace(&self, tx: Sender<MizeMessage>) -> MizeResult<u64> {
|
||||
let conn_id = self.new_connection(tx)?;
|
||||
|
||||
let ns_of_peer_str = self.get(format!("inst/con_by_id/{}/peer/0/config/namespace", conn_id))?.value_string()?;
|
||||
let ns_of_peer_str = self
|
||||
.get(format!(
|
||||
"inst/con_by_id/{}/peer/0/config/namespace",
|
||||
conn_id
|
||||
))?
|
||||
.value_string()?;
|
||||
let ns_of_peer = self.namespace_from_string(ns_of_peer_str)?;
|
||||
|
||||
self.connection_set_namespace(conn_id, ns_of_peer.clone());
|
||||
@@ -459,7 +607,10 @@ impl Instance {
|
||||
}
|
||||
}
|
||||
|
||||
return Err(mize_err!("Connection with id {} not known to instance", conn_id));
|
||||
return Err(mize_err!(
|
||||
"Connection with id {} not known to instance",
|
||||
conn_id
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -472,7 +623,10 @@ impl Instance {
|
||||
}
|
||||
}
|
||||
|
||||
return Err(mize_err!("Connection with id {} not known to instance", conn_id));
|
||||
return Err(mize_err!(
|
||||
"Connection with id {} not known to instance",
|
||||
conn_id
|
||||
));
|
||||
}
|
||||
|
||||
pub fn get_connection_by_ns(&self, ns: Namespace) -> MizeResult<Connection> {
|
||||
@@ -484,11 +638,17 @@ impl Instance {
|
||||
}
|
||||
}
|
||||
|
||||
return Err(mize_err!("Connection with namespace {} not known to instance", ns.as_string()));
|
||||
return Err(mize_err!(
|
||||
"Connection with namespace {} not known to instance",
|
||||
ns.as_string()
|
||||
));
|
||||
}
|
||||
|
||||
pub fn spawn(&mut self, name: &str, func: impl FnOnce() -> MizeResult<()> + Send + 'static) -> MizeResult<()> {
|
||||
|
||||
pub fn spawn(
|
||||
&mut self,
|
||||
name: &str,
|
||||
func: impl FnOnce() -> MizeResult<()> + Send + 'static,
|
||||
) -> MizeResult<()> {
|
||||
let mut threads_inner = self.threads.lock()?;
|
||||
let mut next_thread_id = self.next_thread_id.lock()?;
|
||||
|
||||
@@ -504,10 +664,14 @@ impl Instance {
|
||||
func()?;
|
||||
|
||||
let mut threads_inner = thread_mutex.lock()?;
|
||||
*threads_inner = threads_inner.clone().into_iter().filter(|el| match el {
|
||||
*threads_inner = threads_inner
|
||||
.clone()
|
||||
.into_iter()
|
||||
.filter(|el| match el {
|
||||
(my_thread_id, _) => false,
|
||||
(_, _) => true,
|
||||
}).collect();
|
||||
})
|
||||
.collect();
|
||||
debug!("thread '{}' stopped", name_to_move);
|
||||
Ok(())
|
||||
};
|
||||
@@ -528,7 +692,6 @@ impl Instance {
|
||||
}
|
||||
|
||||
pub fn give_msg_wait(&self, id: MizeId) -> MizeResult<ItemData> {
|
||||
|
||||
let mut give_msg_wait_inner = self.give_msg_wait.lock()?;
|
||||
|
||||
let (tx, rx) = bounded::<ItemData>(1);
|
||||
@@ -552,9 +715,12 @@ impl Instance {
|
||||
return Ok(data);
|
||||
}
|
||||
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
pub fn spawn_async<F: Future<Output = impl Send + 'static> + Send + 'static>(&mut self, name: &str, func: F) -> MizeResult<()> {
|
||||
pub fn spawn_async<F: Future<Output = impl Send + 'static> + Send + 'static>(
|
||||
&mut self,
|
||||
name: &str,
|
||||
func: F,
|
||||
) -> MizeResult<()> {
|
||||
let mut threads_inner = self.threads.lock()?;
|
||||
let mut next_thread_id = self.next_thread_id.lock()?;
|
||||
|
||||
@@ -567,7 +733,6 @@ impl Instance {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
pub fn async_get_handle(&self) -> Handle {
|
||||
let runtime_inner = self.runtime.lock().unwrap();
|
||||
@@ -576,10 +741,21 @@ impl Instance {
|
||||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
pub fn spawn_async_blocking<F: Future<Output = impl Send + Sync + 'static> + Send + Sync + 'static>(&mut self, name: &str, func: F) -> F::Output {
|
||||
|
||||
let mut threads_inner = self.threads.lock().expect("mutex lock failed in spawn_async_blocking");
|
||||
let mut next_thread_id = self.next_thread_id.lock().expect("mutex lock failed in spawn_async_blocking");
|
||||
pub fn spawn_async_blocking<
|
||||
F: Future<Output = impl Send + Sync + 'static> + Send + Sync + 'static,
|
||||
>(
|
||||
&mut self,
|
||||
name: &str,
|
||||
func: F,
|
||||
) -> F::Output {
|
||||
let mut threads_inner = self
|
||||
.threads
|
||||
.lock()
|
||||
.expect("mutex lock failed in spawn_async_blocking");
|
||||
let mut next_thread_id = self
|
||||
.next_thread_id
|
||||
.lock()
|
||||
.expect("mutex lock failed in spawn_async_blocking");
|
||||
|
||||
threads_inner.push((*next_thread_id, name.to_owned()));
|
||||
let runtime_inner = self.runtime.lock().unwrap();
|
||||
@@ -592,7 +768,6 @@ impl Instance {
|
||||
|
||||
let result = handle.block_on(func);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -603,15 +778,60 @@ impl Instance {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn report_error(err: MizeError) {
|
||||
err.log();
|
||||
}
|
||||
|
||||
pub fn get_config(&mut self, name: &str) -> MizeResult<ItemData> {
|
||||
let mut config_opts = self.config_opts.lock().unwrap();
|
||||
|
||||
let opt = config_opts
|
||||
.get_mut(name)
|
||||
.ok_or_else(|| mize_err!("Config opt for {name} not in config_opts"))?;
|
||||
|
||||
// get the cached value
|
||||
if let Some(val) = opt.val.clone() {
|
||||
return Ok(val);
|
||||
}
|
||||
|
||||
// Evaluate the thunk
|
||||
let thunk = opt
|
||||
.thunk
|
||||
.take()
|
||||
.ok_or_else(|| mize_err!("ConfigOpt {name} does not have a thunk"))?;
|
||||
let result = thunk();
|
||||
|
||||
// Cache the result
|
||||
opt.val = Some(result.clone());
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
pub fn new_opt(&mut self, name: &str) -> ConfigOptNameAndMize {
|
||||
let mut config_opts = self.config_opts.lock().unwrap();
|
||||
let opt = ConfigOpt {
|
||||
name: name.to_owned(),
|
||||
val: None,
|
||||
thunk: None,
|
||||
};
|
||||
config_opts.insert(name.to_string(), opt);
|
||||
ConfigOptNameAndMize {
|
||||
name: name.to_string(),
|
||||
mize: self.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(&mut self) -> MizeResult<()> {
|
||||
let mut parts = self.parts.lock().unwrap();
|
||||
for part in parts.values_mut() {
|
||||
part.as_deref_mut().unwrap().run(&mut self.clone())?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Instance {
|
||||
impl fmt::Debug for Mize {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "Mize Instance with subs: {:?}", self.subs,)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,29 +1,25 @@
|
||||
|
||||
|
||||
// https://users.rust-lang.org/t/casting-between-trait-object-types/97220/2
|
||||
|
||||
use std::ffi::OsString;
|
||||
|
||||
use crate::instance::Instance;
|
||||
use crate::error::MizeResult;
|
||||
use crate::instance::Mize;
|
||||
|
||||
pub trait Module: {
|
||||
fn init(&mut self, instance: &Instance) -> MizeResult<()>;
|
||||
pub trait Module {
|
||||
fn init(&mut self, instance: &Mize) -> MizeResult<()>;
|
||||
|
||||
fn exit(&mut self, instance: &Instance) -> MizeResult<()>;
|
||||
fn exit(&mut self, instance: &Mize) -> MizeResult<()>;
|
||||
|
||||
fn clone_module(&self) -> Box<dyn Module + Send + Sync>;
|
||||
|
||||
|
||||
// extra traits, that can be implemented
|
||||
// return None if not implemented
|
||||
|
||||
fn run_cli(&mut self, instance: &Instance, cmd_line: Vec<OsString>) -> Option<MizeResult<()>> {
|
||||
fn run_cli(&mut self, instance: &Mize, cmd_line: Vec<OsString>) -> Option<MizeResult<()>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// console_log macro
|
||||
// that can be copied into other files for debugging purposes
|
||||
#[cfg(feature = "wasm-target")]
|
||||
@@ -43,27 +39,22 @@ macro_rules! console_log {
|
||||
($($t:tt)*) => (unsafe { log(&format_args!($($t)*).to_string())})
|
||||
}
|
||||
|
||||
|
||||
pub struct EmptyModule {
|
||||
}
|
||||
|
||||
pub struct EmptyModule {}
|
||||
|
||||
impl Module for EmptyModule {
|
||||
fn init(&mut self, instance: &Instance) -> MizeResult<()> {
|
||||
fn init(&mut self, instance: &Mize) -> MizeResult<()> {
|
||||
println!("empty module fn init");
|
||||
|
||||
#[cfg(feature = "wasm-target")]
|
||||
console_log!("empty module fn init");
|
||||
Ok(())
|
||||
}
|
||||
fn exit(&mut self, instance: &Instance) -> MizeResult<()> {
|
||||
fn exit(&mut self, instance: &Mize) -> MizeResult<()> {
|
||||
println!("empty module fn exit");
|
||||
Ok(())
|
||||
|
||||
}
|
||||
|
||||
fn clone_module(&self) -> Box<dyn Module + Send + Sync> {
|
||||
Box::new(EmptyModule { })
|
||||
Box::new(EmptyModule {})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
use dyn_clone::DynClone;
|
||||
use std::fmt::Debug;
|
||||
use std::iter::Map;
|
||||
use std::option::Iter;
|
||||
use dyn_clone::DynClone;
|
||||
|
||||
use crate::error::MizeResult;
|
||||
use crate::item::{Item, ItemData};
|
||||
use crate::id::MizeId;
|
||||
use crate::memstore::MemStore;
|
||||
use crate::instance::Instance;
|
||||
use crate::instance::Mize;
|
||||
use crate::item::get_raw_from_cbor;
|
||||
use crate::item::{Item, ItemData};
|
||||
use crate::memstore::MemStore;
|
||||
|
||||
dyn_clone::clone_trait_object!(Store);
|
||||
|
||||
@@ -48,7 +48,10 @@ pub struct IdIter {
|
||||
|
||||
impl IdIter {
|
||||
pub fn new(store: Box<dyn Store>) -> MizeResult<IdIter> {
|
||||
Ok(IdIter { cur_id: store.first_id()?, store })
|
||||
Ok(IdIter {
|
||||
cur_id: store.first_id()?,
|
||||
store,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,17 +60,12 @@ impl Iterator for IdIter {
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
match self.store.next_id(&self.cur_id) {
|
||||
Err(err) => {
|
||||
Some(Err(err))
|
||||
},
|
||||
Err(err) => Some(Err(err)),
|
||||
Ok(Some(new_id)) => {
|
||||
self.cur_id = new_id.clone();
|
||||
Some(Ok(new_id))
|
||||
},
|
||||
Ok(None) => {
|
||||
None
|
||||
},
|
||||
}
|
||||
Ok(None) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
use core::fmt;
|
||||
use std::rc::Rc;
|
||||
use flume::Sender;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use tracing::trace;
|
||||
|
||||
use crate::error::MizeResult;
|
||||
use crate::id::MizeId;
|
||||
use crate::instance::connection::Connection;
|
||||
use crate::item::Item;
|
||||
use crate::error::MizeResult;
|
||||
use crate::proto::MizeMessage;
|
||||
|
||||
use super::Instance;
|
||||
use super::Mize;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Update {
|
||||
pub instance: Arc<Instance>,
|
||||
pub instance: Arc<Mize>,
|
||||
pub id: MizeId,
|
||||
}
|
||||
|
||||
@@ -45,12 +45,14 @@ impl Subscription {
|
||||
trace!("handleing update");
|
||||
match &self {
|
||||
Subscription::Connection(conn) => {
|
||||
let msg = MizeMessage::new_update(update.id.clone(), update.new_item()?.as_data_full()?, conn.id);
|
||||
let msg = MizeMessage::new_update(
|
||||
update.id.clone(),
|
||||
update.new_item()?.as_data_full()?,
|
||||
conn.id,
|
||||
);
|
||||
conn.send(msg)?;
|
||||
}
|
||||
Subscription::Closure(closure) => {
|
||||
closure(update)?
|
||||
}
|
||||
Subscription::Closure(closure) => closure(update)?,
|
||||
Subscription::Channel(tx) => {
|
||||
tx.send(update);
|
||||
}
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
|
||||
use tracing_subscriber::registry::Data;
|
||||
|
||||
use crate::item::IntoItemData;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_sort_keys() -> MizeResult<()> {
|
||||
|
||||
let mut data = ItemData::from_toml(r#"
|
||||
let mut data = ItemData::from_toml(
|
||||
r#"
|
||||
[hi]
|
||||
test = 4
|
||||
|
||||
@@ -19,9 +17,11 @@ fn test_sort_keys() -> MizeResult<()> {
|
||||
|
||||
[config.test]
|
||||
inner = "inner"
|
||||
"#)?;
|
||||
"#,
|
||||
)?;
|
||||
|
||||
let data_sorted = ItemData::from_toml(r#"
|
||||
let data_sorted = ItemData::from_toml(
|
||||
r#"
|
||||
[config]
|
||||
hi = "hello from config/hi"
|
||||
test = { inner = "inner" }
|
||||
@@ -29,19 +29,19 @@ fn test_sort_keys() -> MizeResult<()> {
|
||||
|
||||
[hi]
|
||||
test = 4
|
||||
"#)?;
|
||||
"#,
|
||||
)?;
|
||||
|
||||
data.sort_keys()?;
|
||||
|
||||
assert_eq!(data.to_json()?, data_sorted.to_json()?);
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_module_hash() -> MizeResult<()> {
|
||||
let mut instance = Instance::empty()?;
|
||||
let mut instance = Mize::empty()?;
|
||||
|
||||
use crate::platform::os::get_module_hash;
|
||||
let selector_toml = r#"
|
||||
@@ -64,7 +64,7 @@ fn test_get_module_hash() -> MizeResult<()> {
|
||||
|
||||
#[test]
|
||||
fn test_set_store_path() -> MizeResult<()> {
|
||||
let instance = Instance::empty()?;
|
||||
let instance = Mize::empty()?;
|
||||
|
||||
let store_path = "/home/me/.mize".to_owned();
|
||||
|
||||
@@ -83,23 +83,27 @@ fn test_set_store_path() -> MizeResult<()> {
|
||||
|
||||
#[test]
|
||||
fn test_set_sub_path() -> MizeResult<()> {
|
||||
let instance = Instance::empty()?;
|
||||
let instance = Mize::empty()?;
|
||||
|
||||
let data = ItemData::from_toml(r#"
|
||||
let data = ItemData::from_toml(
|
||||
r#"
|
||||
[config]
|
||||
hi = "hello from config/hi"
|
||||
|
||||
[config.test]
|
||||
inner = "inner"
|
||||
"#)?;
|
||||
"#,
|
||||
)?;
|
||||
|
||||
let data_two = ItemData::from_toml(r#"
|
||||
let data_two = ItemData::from_toml(
|
||||
r#"
|
||||
[config]
|
||||
hi = "hello from config/hi"
|
||||
|
||||
[config.test]
|
||||
inner = "new inner"
|
||||
"#)?;
|
||||
"#,
|
||||
)?;
|
||||
|
||||
let item = instance.new_item()?;
|
||||
instance.set_blocking(item.id(), data.clone())?;
|
||||
@@ -107,11 +111,23 @@ fn test_set_sub_path() -> MizeResult<()> {
|
||||
assert_eq!(item.as_data_full()?, data);
|
||||
|
||||
// try to set a sub path of item
|
||||
instance.set_blocking(vec![item.id().store_part(), "config", "test", "inner"], "new inner".into_item_data())?;
|
||||
instance.set_blocking(
|
||||
vec![item.id().store_part(), "config", "test", "inner"],
|
||||
"new inner".into_item_data(),
|
||||
)?;
|
||||
|
||||
// the contents of item should then be like data_two
|
||||
println!("item with id '{}': {}", item.id(), instance.get(vec![item.id().store_part()])?.as_data_full()?);
|
||||
assert_eq!(instance.get(vec![item.id().store_part(), "config", "test", "inner"])?.as_data_full()?, ItemData::from_string("new inner"));
|
||||
println!(
|
||||
"item with id '{}': {}",
|
||||
item.id(),
|
||||
instance.get(vec![item.id().store_part()])?.as_data_full()?
|
||||
);
|
||||
assert_eq!(
|
||||
instance
|
||||
.get(vec![item.id().store_part(), "config", "test", "inner"])?
|
||||
.as_data_full()?,
|
||||
ItemData::from_string("new inner")
|
||||
);
|
||||
assert_eq!(item.as_data_full()?, data_two);
|
||||
|
||||
Ok(())
|
||||
@@ -119,23 +135,30 @@ fn test_set_sub_path() -> MizeResult<()> {
|
||||
|
||||
#[test]
|
||||
fn test_itemdata_set_path() -> MizeResult<()> {
|
||||
let mut data = ItemData::from_toml(r#"
|
||||
let mut data = ItemData::from_toml(
|
||||
r#"
|
||||
[config]
|
||||
hi = "hello from config/hi"
|
||||
|
||||
[config.test]
|
||||
inner = "inner"
|
||||
"#)?;
|
||||
"#,
|
||||
)?;
|
||||
|
||||
let data_two = ItemData::from_toml(r#"
|
||||
let data_two = ItemData::from_toml(
|
||||
r#"
|
||||
[config]
|
||||
hi = "hello from config/hi"
|
||||
|
||||
[config.test]
|
||||
inner = "new inner"
|
||||
"#)?;
|
||||
"#,
|
||||
)?;
|
||||
|
||||
data.set_path(vec!["config", "test", "inner"], ItemData::from_string("new inner"))?;
|
||||
data.set_path(
|
||||
vec!["config", "test", "inner"],
|
||||
ItemData::from_string("new inner"),
|
||||
)?;
|
||||
|
||||
assert_eq!(data, data_two);
|
||||
|
||||
@@ -144,57 +167,71 @@ fn test_itemdata_set_path() -> MizeResult<()> {
|
||||
|
||||
#[test]
|
||||
fn test_itemdata_merge() -> MizeResult<()> {
|
||||
let mut data = ItemData::from_toml(r#"
|
||||
let mut data = ItemData::from_toml(
|
||||
r#"
|
||||
[config]
|
||||
hi = "hello from config/hi"
|
||||
|
||||
[config.test]
|
||||
inner = "inner"
|
||||
"#)?;
|
||||
"#,
|
||||
)?;
|
||||
|
||||
let data_two = ItemData::from_toml(r#"
|
||||
let data_two = ItemData::from_toml(
|
||||
r#"
|
||||
[config]
|
||||
hi = "hello from config/hi"
|
||||
|
||||
[config.test]
|
||||
inner = "new inner"
|
||||
"#)?;
|
||||
"#,
|
||||
)?;
|
||||
|
||||
assert_eq!(data.get_path(vec!["config", "test", "inner"])?, ItemData::from_string("inner"));
|
||||
assert_eq!(
|
||||
data.get_path(vec!["config", "test", "inner"])?,
|
||||
ItemData::from_string("inner")
|
||||
);
|
||||
|
||||
data.merge(data_two.clone());
|
||||
|
||||
assert_eq!(data, data_two);
|
||||
|
||||
assert_eq!(data.get_path(vec!["config", "test", "inner"])?, ItemData::from_string("new inner"));
|
||||
assert_eq!(
|
||||
data.get_path(vec!["config", "test", "inner"])?,
|
||||
ItemData::from_string("new inner")
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_item_merge() -> MizeResult<()> {
|
||||
let instance = Instance::empty()?;
|
||||
let instance = Mize::empty()?;
|
||||
|
||||
let mut item = instance.new_item()?;
|
||||
|
||||
// here the item should contain "empty" data
|
||||
assert_eq!(item.as_data_full()?, ItemData::new());
|
||||
|
||||
let data = ItemData::from_toml(r#"
|
||||
let data = ItemData::from_toml(
|
||||
r#"
|
||||
[config]
|
||||
hi = "hello from config/hi"
|
||||
|
||||
[config.test]
|
||||
inner = "inner"
|
||||
"#)?;
|
||||
"#,
|
||||
)?;
|
||||
|
||||
let data_two = ItemData::from_toml(r#"
|
||||
let data_two = ItemData::from_toml(
|
||||
r#"
|
||||
[config]
|
||||
hi = "hello from config/hi"
|
||||
|
||||
[config.test]
|
||||
inner = "new inner"
|
||||
"#)?;
|
||||
"#,
|
||||
)?;
|
||||
|
||||
item.merge(data.clone())?;
|
||||
|
||||
@@ -213,7 +250,6 @@ fn test_item_merge() -> MizeResult<()> {
|
||||
// also the item should be updated
|
||||
assert_eq!(item.as_data_full()?, data_two);
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -225,6 +261,3 @@ fn test_cant_set_non_existent_item() -> () {
|
||||
instance.set_blocking("5", "hello world".into_item_data()).expect("correct panic");
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,28 +1,23 @@
|
||||
use flume::Receiver;
|
||||
use tracing::{error, trace, warn};
|
||||
use std::borrow::BorrowMut;
|
||||
use std::sync::Arc;
|
||||
use tracing::{error, trace, warn};
|
||||
|
||||
use crate::mize_err;
|
||||
use crate::{instance::Instance, item::ItemData};
|
||||
use crate::error::{MizeError, MizeResult, MizeResultTrait};
|
||||
use crate::id::MizeId;
|
||||
use crate:: error::{MizeResult, MizeError, MizeResultTrait};
|
||||
use crate::mize_err;
|
||||
use crate::proto::{MessageCmd, MizeMessage};
|
||||
use crate::{instance::Mize, item::ItemData};
|
||||
|
||||
use super::connection::{self, Connection};
|
||||
use super::subscription::{Subscription, Update};
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Operation {
|
||||
Set(MizeId, ItemData, Option<Connection>), // bool: is_from_update_msg
|
||||
Msg(MizeMessage),
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// console_log macro
|
||||
// that can be copied into other files for debugging purposes
|
||||
#[cfg(feature = "wasm-target")]
|
||||
@@ -46,15 +41,11 @@ macro_rules! console_log {
|
||||
macro_rules! console_log {
|
||||
// Note that this is using the `log` function imported above during
|
||||
// `bare_bones`
|
||||
($($t:tt)*) => ()
|
||||
($($t:tt)*) => {};
|
||||
}
|
||||
//end of console_log macro
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
pub async fn updater_thread_async(operation_rx : Receiver<Operation>, instance: Instance) -> () {
|
||||
pub async fn updater_thread_async(operation_rx: Receiver<Operation>, instance: Mize) -> () {
|
||||
let mut count = 0;
|
||||
console_log!("inside an updater thread");
|
||||
|
||||
@@ -84,11 +75,10 @@ pub async fn updater_thread_async(operation_rx : Receiver<Operation>, instance:
|
||||
error!("OPERATION {} FAILED: {:?}", count, operation);
|
||||
err.log();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pub fn updater_thread(operation_rx : Receiver<Operation>, instance: &Instance) -> MizeResult<()> {
|
||||
pub fn updater_thread(operation_rx: Receiver<Operation>, instance: &Mize) -> MizeResult<()> {
|
||||
let mut count = 0;
|
||||
|
||||
loop {
|
||||
@@ -109,13 +99,11 @@ pub fn updater_thread(operation_rx : Receiver<Operation>, instance: &Instance) -
|
||||
error!("OPERATION FAILED: {:?}", operation);
|
||||
err.log();
|
||||
}
|
||||
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn handle_operation(operation: &mut Operation, instance: &Instance) -> MizeResult<()> {
|
||||
|
||||
pub fn handle_operation(operation: &mut Operation, instance: &Mize) -> MizeResult<()> {
|
||||
match operation {
|
||||
Operation::Set(id, value, maybe_conn) => {
|
||||
let item_data: ItemData = value.to_owned();
|
||||
@@ -130,7 +118,6 @@ pub fn handle_operation(operation: &mut Operation, instance: &Instance) -> MizeR
|
||||
id: id.clone(),
|
||||
};
|
||||
for sub in vec.iter_mut() {
|
||||
|
||||
// don't handle sub of type connection, in case the update comes from this
|
||||
// connection
|
||||
if let Some(conn) = maybe_conn {
|
||||
@@ -144,15 +131,13 @@ pub fn handle_operation(operation: &mut Operation, instance: &Instance) -> MizeR
|
||||
sub.handle(update.clone());
|
||||
}
|
||||
}
|
||||
},
|
||||
Operation::Msg(msg) => {
|
||||
handle_msg(msg, instance)?
|
||||
},
|
||||
}
|
||||
Operation::Msg(msg) => handle_msg(msg, instance)?,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_msg(msg: &mut MizeMessage, instance: &Instance) -> MizeResult<()> {
|
||||
fn handle_msg(msg: &mut MizeMessage, instance: &Mize) -> MizeResult<()> {
|
||||
match msg.cmd()? {
|
||||
MessageCmd::Get => {
|
||||
let id = msg.id(instance)?;
|
||||
@@ -160,7 +145,7 @@ fn handle_msg(msg: &mut MizeMessage, instance: &Instance) -> MizeResult<()> {
|
||||
let item = instance.get(id.clone())?;
|
||||
let msg = MizeMessage::new_give(id, item.as_data_full()?, msg.conn_id);
|
||||
connection.send(msg)?;
|
||||
},
|
||||
}
|
||||
|
||||
MessageCmd::GetSub => {
|
||||
let id = msg.id(instance)?;
|
||||
@@ -170,21 +155,23 @@ fn handle_msg(msg: &mut MizeMessage, instance: &Instance) -> MizeResult<()> {
|
||||
connection.send(msg)?;
|
||||
let sub = Subscription::from_conn(connection.clone());
|
||||
instance.sub(id, sub)?;
|
||||
},
|
||||
}
|
||||
|
||||
MessageCmd::Sub => {
|
||||
let id = msg.id(instance)?;
|
||||
let mut connection = instance.get_connection(msg.conn_id)?.clone();
|
||||
let sub = Subscription::from_conn(connection.clone());
|
||||
instance.sub(id, sub)?;
|
||||
},
|
||||
}
|
||||
|
||||
MessageCmd::Update => {
|
||||
let data = msg.data()?;
|
||||
let id = msg.id(instance)?;
|
||||
let connection = instance.get_connection(msg.conn_id)?;
|
||||
instance.op_tx.send(Operation::Set(id.clone(), data, Some(connection)));
|
||||
},
|
||||
instance
|
||||
.op_tx
|
||||
.send(Operation::Set(id.clone(), data, Some(connection)));
|
||||
}
|
||||
|
||||
// this should check, if the update is valid
|
||||
// but for now, we do just always accept it
|
||||
@@ -192,8 +179,10 @@ fn handle_msg(msg: &mut MizeMessage, instance: &Instance) -> MizeResult<()> {
|
||||
let data = msg.data()?;
|
||||
let id = msg.id(instance)?;
|
||||
let connection = instance.get_connection(msg.conn_id)?;
|
||||
instance.op_tx.send(Operation::Set(id.clone(), data, Some(connection)));
|
||||
},
|
||||
instance
|
||||
.op_tx
|
||||
.send(Operation::Set(id.clone(), data, Some(connection)));
|
||||
}
|
||||
|
||||
MessageCmd::Give => {
|
||||
let id = msg.id(instance)?;
|
||||
@@ -204,9 +193,12 @@ fn handle_msg(msg: &mut MizeMessage, instance: &Instance) -> MizeResult<()> {
|
||||
tx.send(data.clone());
|
||||
}
|
||||
} else {
|
||||
warn!("got give msg for id '{}', that has no one waiting for it", id);
|
||||
warn!(
|
||||
"got give msg for id '{}', that has no one waiting for it",
|
||||
id
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
MessageCmd::Create => {
|
||||
println!("instance.store: {:?}", instance.clone().store);
|
||||
@@ -225,10 +217,7 @@ fn handle_msg(msg: &mut MizeMessage, instance: &Instance) -> MizeResult<()> {
|
||||
}
|
||||
_ => {
|
||||
return Err(mize_err!("got a message, that is not handeled"));
|
||||
},
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,44 +1,43 @@
|
||||
use tracing::{debug, error, info, instrument, trace, warn, Instrument};
|
||||
use colored::Colorize;
|
||||
use core::fmt;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use core::fmt;
|
||||
use std::fmt::Debug;
|
||||
use std::{i128, string};
|
||||
use std::{collections::HashMap, path::PathBuf, io::Cursor, fmt::Display};
|
||||
use std::fs::File;
|
||||
use std::rc::Rc;
|
||||
use colored::Colorize;
|
||||
use std::io;
|
||||
use std::rc::Rc;
|
||||
use std::{collections::HashMap, fmt::Display, io::Cursor, path::PathBuf};
|
||||
use std::{i128, string};
|
||||
use tracing::{debug, error, info, instrument, trace, warn, Instrument};
|
||||
use tracing::{span, Level};
|
||||
|
||||
use crate::error::{MizeError, MizeResult, IntoMizeResult};
|
||||
use crate::instance::{connection, Instance};
|
||||
use crate::instance::store::Store;
|
||||
use crate::error::{IntoMizeResult, MizeError, MizeResult};
|
||||
use crate::id::MizeId;
|
||||
use crate::instance::connection::value_raw_con_by_id;
|
||||
use crate::instance::store::Store;
|
||||
use crate::instance::{connection, Mize};
|
||||
use crate::mize_err;
|
||||
use crate::proto::MizeMessage;
|
||||
use ciborium::Value as CborValue;
|
||||
use crate::instance::connection::value_raw_con_by_id;
|
||||
|
||||
|
||||
// a item always has to do with a Instance, which takes care of how it is updated
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Item<'a> {
|
||||
id: MizeId,
|
||||
pub instance: &'a Instance
|
||||
pub instance: &'a Mize,
|
||||
}
|
||||
|
||||
// without an Instance it is not an item, but only the "data of an item"
|
||||
// and this type for now is just an alias to CborValue
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ItemData ( pub CborValue );
|
||||
pub struct ItemData(pub CborValue);
|
||||
|
||||
impl Item<'_> {
|
||||
pub fn id(&self) -> MizeId {
|
||||
self.id.clone()
|
||||
}
|
||||
|
||||
pub fn new(id: MizeId, instance: &Instance) -> Item {
|
||||
pub fn new(id: MizeId, instance: &Mize) -> Item {
|
||||
Item { id, instance }
|
||||
}
|
||||
|
||||
@@ -57,31 +56,43 @@ impl Item<'_> {
|
||||
pub fn as_data_full(&self) -> MizeResult<ItemData> {
|
||||
let id = self.id();
|
||||
|
||||
|
||||
// the instance we are
|
||||
if id.store_part() == "self" {
|
||||
debug!("getting item '{}' from self", self.id());
|
||||
|
||||
match id.nth_part(1)? {
|
||||
"con_by_id" => { return value_raw_con_by_id(&mut self.clone()); },
|
||||
"con_by_id" => {
|
||||
return value_raw_con_by_id(&mut self.clone());
|
||||
}
|
||||
"namespace" => {
|
||||
let namespace_inner = self.instance.namespace.lock()?;
|
||||
return Ok(ItemData::from_string(namespace_inner.as_real_string()));
|
||||
},
|
||||
}
|
||||
"self_namespace" => {
|
||||
let namespace_inner = self.instance.self_namespace.lock()?;
|
||||
return Ok(ItemData::from_string(namespace_inner.as_real_string()));
|
||||
},
|
||||
}
|
||||
"config" => {
|
||||
let rest_path = id.path.into_iter().skip(2).map(|v| v.to_owned()).collect::<Vec<String>>().join("/");
|
||||
let id_for_store = self.instance.new_id("0/config".to_owned() + "/" + rest_path.as_str())?;
|
||||
let rest_path = id
|
||||
.path
|
||||
.into_iter()
|
||||
.skip(2)
|
||||
.map(|v| v.to_owned())
|
||||
.collect::<Vec<String>>()
|
||||
.join("/");
|
||||
let id_for_store = self
|
||||
.instance
|
||||
.new_id("0/config".to_owned() + "/" + rest_path.as_str())?;
|
||||
let store = self.instance.store.lock()?;
|
||||
let data = store.get_value_data_full(id_for_store)?;
|
||||
return Ok(data);
|
||||
}
|
||||
_ => {},
|
||||
_ => {}
|
||||
}
|
||||
return Err(mize_err!("a /self path, but the next element in the path '{:?}' is not valid", id.nth_part(1)));
|
||||
return Err(mize_err!(
|
||||
"a /self path, but the next element in the path '{:?}' is not valid",
|
||||
id.nth_part(1)
|
||||
));
|
||||
}
|
||||
|
||||
let self_namespace_inner = self.instance.self_namespace.lock()?;
|
||||
@@ -91,27 +102,31 @@ impl Item<'_> {
|
||||
|
||||
if id.store_part() == "inst" {
|
||||
match id.nth_part(1)? {
|
||||
"con_by_id" => { return value_raw_con_by_id(&mut self.clone()); },
|
||||
"con_by_id" => {
|
||||
return value_raw_con_by_id(&mut self.clone());
|
||||
}
|
||||
"namespace" => {
|
||||
let namespace_inner = self.instance.namespace.lock()?;
|
||||
return Ok(ItemData::from_string(namespace_inner.as_real_string()));
|
||||
},
|
||||
}
|
||||
"self_namespace" => {
|
||||
let namespace_inner = self.instance.self_namespace.lock()?;
|
||||
return Ok(ItemData::from_string(namespace_inner.as_real_string()));
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let store_inner = self.instance.store.lock()?;
|
||||
return store_inner.get_value_data_full(self.id());
|
||||
|
||||
|
||||
} else {
|
||||
let mut connection = self.instance.get_connection_by_ns(self.id().namespace())?;
|
||||
|
||||
debug!("getting item '{}' from connection '{}' from store", self.id(), connection.id);
|
||||
debug!(
|
||||
"getting item '{}' from connection '{}' from store",
|
||||
self.id(),
|
||||
connection.id
|
||||
);
|
||||
|
||||
let msg = MizeMessage::new_get(self.id(), connection.id);
|
||||
connection.send(msg);
|
||||
@@ -121,8 +136,7 @@ impl Item<'_> {
|
||||
}
|
||||
|
||||
#[instrument(name = "fn.ItemData::merge")]
|
||||
pub fn merge<V: Into<ItemData> + Debug >(&mut self, mut value: V) -> MizeResult<()> {
|
||||
|
||||
pub fn merge<V: Into<ItemData> + Debug>(&mut self, mut value: V) -> MizeResult<()> {
|
||||
let mut data = self.as_data_full()?;
|
||||
//let mut data = data_full.get_path(id_path_without_store_part)?;
|
||||
trace!("item::merge data: {:?}", data);
|
||||
@@ -135,25 +149,28 @@ impl Item<'_> {
|
||||
|
||||
// handle the case of /self/*
|
||||
if self.id().store_part() == "self" {
|
||||
let rest_path = self.id().path.into_iter().skip(1).map(|v| v.to_owned()).collect::<Vec<String>>().join("/");
|
||||
let id_for_store = self.instance.new_id("0".to_owned() + "/" + rest_path.as_str())?;
|
||||
let rest_path = self
|
||||
.id()
|
||||
.path
|
||||
.into_iter()
|
||||
.skip(1)
|
||||
.map(|v| v.to_owned())
|
||||
.collect::<Vec<String>>()
|
||||
.join("/");
|
||||
let id_for_store = self
|
||||
.instance
|
||||
.new_id("0".to_owned() + "/" + rest_path.as_str())?;
|
||||
|
||||
let store_inner = self.instance.store.lock()?;
|
||||
store_inner.set(id_for_store, data)?;
|
||||
|
||||
|
||||
} else if self.instance.we_are_namespace()? {
|
||||
|
||||
let store_inner = self.instance.store.lock()?;
|
||||
store_inner.set(self.id(), data)?;
|
||||
|
||||
} else {
|
||||
|
||||
let namespace = self.id().namespace();
|
||||
let mut connection = self.instance.get_connection_by_ns(namespace)?;
|
||||
let msg = MizeMessage::new_update_request(self.id(), data, connection.id);
|
||||
connection.send(msg)?;
|
||||
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -178,11 +195,12 @@ impl ItemData {
|
||||
}
|
||||
|
||||
pub fn from_toml(toml_string: &str) -> MizeResult<ItemData> {
|
||||
|
||||
let toml_deserializer = toml::Deserializer::new(&toml_string);
|
||||
|
||||
let value = CborValue::deserialize(toml_deserializer)
|
||||
.mize_result_msg(format!("Could not deserialize the toml string: {}", &toml_string))?;
|
||||
let value = CborValue::deserialize(toml_deserializer).mize_result_msg(format!(
|
||||
"Could not deserialize the toml string: {}",
|
||||
&toml_string
|
||||
))?;
|
||||
|
||||
return Ok(value.into_item_data());
|
||||
}
|
||||
@@ -197,14 +215,14 @@ impl ItemData {
|
||||
pub fn from_string<S: Into<String>>(into_string: S) -> ItemData {
|
||||
let string = into_string.into();
|
||||
let data = CborValue::Text(string);
|
||||
return ItemData (data);
|
||||
return ItemData(data);
|
||||
}
|
||||
|
||||
pub fn to_json(self) -> MizeResult<String> {
|
||||
|
||||
let mut result: Vec<u8> = Vec::new();
|
||||
|
||||
self.0.serialize(&mut serde_json::Serializer::new(&mut result))?;
|
||||
self.0
|
||||
.serialize(&mut serde_json::Serializer::new(&mut result))?;
|
||||
|
||||
Ok(String::from_utf8(result)?)
|
||||
}
|
||||
@@ -212,8 +230,10 @@ impl ItemData {
|
||||
pub fn from_json(json_str: String) -> MizeResult<ItemData> {
|
||||
let mut json_deserializer = serde_json::Deserializer::from_str(json_str.as_str());
|
||||
|
||||
let value = CborValue::deserialize(&mut json_deserializer)
|
||||
.mize_result_msg(format!("could not deserialize the json string: {}", json_str))?;
|
||||
let value = CborValue::deserialize(&mut json_deserializer).mize_result_msg(format!(
|
||||
"could not deserialize the json string: {}",
|
||||
json_str
|
||||
))?;
|
||||
|
||||
return Ok(value.into_item_data());
|
||||
}
|
||||
@@ -227,7 +247,7 @@ impl ItemData {
|
||||
}
|
||||
|
||||
pub fn from_cbor(cbor: CborValue) -> ItemData {
|
||||
ItemData (cbor)
|
||||
ItemData(cbor)
|
||||
}
|
||||
|
||||
pub fn sort_keys(&mut self) -> MizeResult<()> {
|
||||
@@ -247,7 +267,7 @@ impl ItemData {
|
||||
return CborValue::Bool(true).into_item_data();
|
||||
}
|
||||
if let Ok(int) = value_str.parse::<i128>() {
|
||||
return int.into_item_data()
|
||||
return int.into_item_data();
|
||||
}
|
||||
return CborValue::Text(value_str).into_item_data();
|
||||
}
|
||||
@@ -262,12 +282,12 @@ impl ItemData {
|
||||
|
||||
pub fn get_path<P: IntoPath>(&self, path: P) -> MizeResult<ItemData> {
|
||||
let path = path.into_path();
|
||||
Ok(item_data_get_path(&self.0, path)?.to_owned().into_item_data())
|
||||
Ok(item_data_get_path(&self.0, path)?
|
||||
.to_owned()
|
||||
.into_item_data())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
impl Default for ItemData {
|
||||
fn default() -> Self {
|
||||
ItemData::new()
|
||||
@@ -275,7 +295,6 @@ impl Default for ItemData {
|
||||
}
|
||||
|
||||
pub fn data_from_string(data_string: String) -> MizeResult<ItemData> {
|
||||
|
||||
let mut data = ItemData::new();
|
||||
|
||||
// in case it's just a string
|
||||
@@ -290,13 +309,23 @@ pub fn data_from_string(data_string: String) -> MizeResult<ItemData> {
|
||||
continue;
|
||||
}
|
||||
|
||||
let path = option.split("=").nth(0)
|
||||
.ok_or(MizeError::new().msg(format!("Failed to parse Option: option '{}' has an empty path (thing before =)", option)))?;
|
||||
let path = option
|
||||
.split("=")
|
||||
.nth(0)
|
||||
.ok_or(MizeError::new().msg(format!(
|
||||
"Failed to parse Option: option '{}' has an empty path (thing before =)",
|
||||
option
|
||||
)))?;
|
||||
|
||||
//trace!("data_from_string: path: {}", path);
|
||||
|
||||
let value = option.split("=").nth(1)
|
||||
.ok_or(MizeError::new().msg(format!("Failed to parse Option: option '{}' has an empty value (thing after =)", option)))?;
|
||||
let value = option
|
||||
.split("=")
|
||||
.nth(1)
|
||||
.ok_or(MizeError::new().msg(format!(
|
||||
"Failed to parse Option: option '{}' has an empty value (thing after =)",
|
||||
option
|
||||
)))?;
|
||||
//trace!("data_from_string: value: {}", value);
|
||||
|
||||
let mut path_vec = Vec::new();
|
||||
@@ -333,18 +362,20 @@ pub fn item_data_get_path(data: &CborValue, path: Vec<String>) -> MizeResult<&Cb
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
val => {
|
||||
return Err(MizeError::new()
|
||||
.msg(format!("Failed to get path '{:?}' from ItemData, the data at '{}' is not a map", path, path_el))
|
||||
.msg(format!(
|
||||
"Failed to get path '{:?}' from ItemData, the data at '{}' is not a map",
|
||||
path, path_el
|
||||
))
|
||||
.msg(format!("{:?} is: {:?}", path_el, val)));
|
||||
},
|
||||
}
|
||||
};
|
||||
item_data_get_path(sub_data, path_iter.collect())
|
||||
}
|
||||
|
||||
pub fn item_data_sort_keys(data: &mut CborValue) -> MizeResult<()> {
|
||||
|
||||
// for a list, sort each item of the list
|
||||
if data.is_array() {
|
||||
for el in data.as_array_mut().unwrap().iter_mut() {
|
||||
@@ -356,7 +387,7 @@ pub fn item_data_sort_keys(data: &mut CborValue) -> MizeResult<()> {
|
||||
if data.is_map() {
|
||||
let map: &mut Vec<(CborValue, CborValue)> = data.as_map_mut().unwrap();
|
||||
//map.sort_by_key(|el| el.0);
|
||||
map.sort_by(|a,b| {
|
||||
map.sort_by(|a, b| {
|
||||
match a.0.partial_cmp(&b.0) {
|
||||
Some(val) => val,
|
||||
None => {
|
||||
@@ -375,7 +406,11 @@ pub fn item_data_sort_keys(data: &mut CborValue) -> MizeResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn item_data_set_path(data: &mut CborValue, path: Vec<String>, data_to_set: &CborValue) -> MizeResult<()> {
|
||||
pub fn item_data_set_path(
|
||||
data: &mut CborValue,
|
||||
path: Vec<String>,
|
||||
data_to_set: &CborValue,
|
||||
) -> MizeResult<()> {
|
||||
//trace!("[ {} ] item_data_set_path()", "CALL".yellow());
|
||||
//trace!("[ {} ] data: {}", "ARG".yellow(), data.clone().into_item_data());
|
||||
//trace!("[ {} ] path: {:?}", "ARG".yellow(), path);
|
||||
@@ -395,11 +430,11 @@ pub fn item_data_set_path(data: &mut CborValue, path: Vec<String>, data_to_set:
|
||||
// our base case
|
||||
*data = data_to_set.to_owned();
|
||||
return Ok(());
|
||||
},
|
||||
}
|
||||
};
|
||||
match data {
|
||||
CborValue::Map(ref mut map) => {
|
||||
for (key, val) in &mut * map {
|
||||
for (key, val) in &mut *map {
|
||||
if let CborValue::Text(key_str) = key {
|
||||
if key_str == &path_el {
|
||||
//trace!("item_data_set_path: setting key {key_str} in map with recursive call");
|
||||
@@ -417,7 +452,7 @@ pub fn item_data_set_path(data: &mut CborValue, path: Vec<String>, data_to_set:
|
||||
item_data_set_path(&mut inner_value, path_iter.collect(), data_to_set);
|
||||
map.push((CborValue::Text(path_el.clone()), inner_value));
|
||||
return Ok(());
|
||||
},
|
||||
}
|
||||
CborValue::Null => {
|
||||
//trace!("item_data_set_path: CborValue::Null case");
|
||||
let mut inner_value = CborValue::Null;
|
||||
@@ -427,18 +462,21 @@ pub fn item_data_set_path(data: &mut CborValue, path: Vec<String>, data_to_set:
|
||||
*data = CborValue::Map(map_vec);
|
||||
|
||||
return Ok(());
|
||||
},
|
||||
}
|
||||
val => {
|
||||
return Err(MizeError::new()
|
||||
.msg(format!("Failed to get path '{:?}' from ItemData, the data at '{}' is not a map", path, path_el))
|
||||
.msg(format!(
|
||||
"Failed to get path '{:?}' from ItemData, the data at '{}' is not a map",
|
||||
path, path_el
|
||||
))
|
||||
.msg(format!("{:?} is: {:?}", path_el, val)));
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
return Err(MizeError::new().msg("unreachable"));
|
||||
}
|
||||
|
||||
pub fn item_data_merge(merge_into: &mut CborValue, other: &CborValue){
|
||||
pub fn item_data_merge(merge_into: &mut CborValue, other: &CborValue) {
|
||||
// needs to be recursive
|
||||
|
||||
match (merge_into, other) {
|
||||
@@ -447,7 +485,6 @@ pub fn item_data_merge(merge_into: &mut CborValue, other: &CborValue){
|
||||
(CborValue::Map(ref mut merge_into_map), CborValue::Map(ref other_map)) => {
|
||||
// go through other_map and merge those keys/values to merge_into
|
||||
for (other_key, other_val) in other_map {
|
||||
|
||||
// so find that same vale in merge_into, if exists recursively merge, else just add to
|
||||
// vec
|
||||
let mut found_value = CborValue::Null;
|
||||
@@ -462,10 +499,10 @@ pub fn item_data_merge(merge_into: &mut CborValue, other: &CborValue){
|
||||
value_found = true;
|
||||
found_value = merge_into_val.to_owned();
|
||||
// if we found it, also don't add it to new_value_for_merge_into
|
||||
|
||||
} else {
|
||||
//if not found push to new_value_for_merge_into
|
||||
new_value_for_merge_into.push((merge_into_key.to_owned(), merge_into_val.to_owned()));
|
||||
new_value_for_merge_into
|
||||
.push((merge_into_key.to_owned(), merge_into_val.to_owned()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,7 +512,6 @@ pub fn item_data_merge(merge_into: &mut CborValue, other: &CborValue){
|
||||
|
||||
// to asign push to new_value_for_merge_into, because the old was removed already
|
||||
new_value_for_merge_into.push((other_key.to_owned(), found_value));
|
||||
|
||||
} else {
|
||||
// if not found, just add the other_key/val to new_value_for_merge_into
|
||||
new_value_for_merge_into.push((other_key.to_owned(), other_val.to_owned()));
|
||||
@@ -488,8 +524,7 @@ pub fn item_data_merge(merge_into: &mut CborValue, other: &CborValue){
|
||||
|
||||
// if other is Null, don't asign
|
||||
// this is gonna have repercussions.... because it's not clean behaviour
|
||||
(merge_into, CborValue::Null) => {
|
||||
}
|
||||
(merge_into, CborValue::Null) => {}
|
||||
|
||||
// in any other case we just want to set merge_into to other
|
||||
// also this is the base case
|
||||
@@ -513,27 +548,30 @@ pub fn get_raw_from_cbor<'a>(value: &'a CborValue, path: Vec<&String>) -> MizeRe
|
||||
CborValue::Bytes(vec) => {
|
||||
trace!("[ {} ] ret value: {:?}", "RET".yellow(), &vec[..]);
|
||||
return Ok(&vec[..]);
|
||||
},
|
||||
}
|
||||
CborValue::Text(string) => {
|
||||
trace!("[ {} ] ret value: {:?}", "RET".yellow(), string.as_bytes());
|
||||
return Ok(string.as_bytes());
|
||||
},
|
||||
}
|
||||
other => {
|
||||
return Err(mize_err!("path is empty and the value: '{:?}' is neither Bytes nor Text", other));
|
||||
},
|
||||
return Err(mize_err!(
|
||||
"path is empty and the value: '{:?}' is neither Bytes nor Text",
|
||||
other
|
||||
));
|
||||
}
|
||||
};
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
match value {
|
||||
CborValue::Bytes(vec) => {
|
||||
trace!("[ {} ] ret value: {:?}", "RET".yellow(), &vec[..]);
|
||||
return Ok(&vec[..]);
|
||||
},
|
||||
}
|
||||
CborValue::Text(string) => {
|
||||
trace!("[ {} ] ret value: {:?}", "RET".yellow(), string.as_bytes());
|
||||
return Ok(string.as_bytes());
|
||||
},
|
||||
}
|
||||
CborValue::Map(map) => {
|
||||
let mut inner_val: &CborValue = &CborValue::Null;
|
||||
let mut inner_val_found = false;
|
||||
@@ -552,7 +590,14 @@ pub fn get_raw_from_cbor<'a>(value: &'a CborValue, path: Vec<&String>) -> MizeRe
|
||||
if inner_val_found == false {
|
||||
return Err(MizeError::new()
|
||||
// jesus christ, this is a pfusch...
|
||||
.msg(format!("get_raw_from_cbor: Path '{}' not Found", path.clone().into_iter().map(|v| v.to_owned()).collect::<Vec<String>>().join("/"))))
|
||||
.msg(format!(
|
||||
"get_raw_from_cbor: Path '{}' not Found",
|
||||
path.clone()
|
||||
.into_iter()
|
||||
.map(|v| v.to_owned())
|
||||
.collect::<Vec<String>>()
|
||||
.join("/")
|
||||
)));
|
||||
}
|
||||
|
||||
//path_iter.next();
|
||||
@@ -560,9 +605,11 @@ pub fn get_raw_from_cbor<'a>(value: &'a CborValue, path: Vec<&String>) -> MizeRe
|
||||
let ret_value = get_raw_from_cbor(inner_val, inner_path);
|
||||
trace!("[ {} ] ret value: {:?}", "RET".yellow(), ret_value);
|
||||
return ret_value;
|
||||
},
|
||||
_ => Err(MizeError::new()
|
||||
.msg(format!("get_raw_from_cbor: value is not a map, text or bytes ... value: {:?}", value))),
|
||||
}
|
||||
_ => Err(MizeError::new().msg(format!(
|
||||
"get_raw_from_cbor: value is not a map, text or bytes ... value: {:?}",
|
||||
value
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -613,7 +660,7 @@ impl IntoItemData for &String {
|
||||
}
|
||||
impl IntoItemData for CborValue {
|
||||
fn into_item_data(self) -> ItemData {
|
||||
ItemData ( self )
|
||||
ItemData(self)
|
||||
}
|
||||
}
|
||||
impl IntoItemData for ItemData {
|
||||
@@ -630,8 +677,9 @@ impl IntoItemData for i128 {
|
||||
impl fmt::Display for ItemData {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "ItemData: ");
|
||||
let display_writer = DisplayWriter (f);
|
||||
self.0.serialize(&mut serde_json::Serializer::pretty(display_writer))
|
||||
let display_writer = DisplayWriter(f);
|
||||
self.0
|
||||
.serialize(&mut serde_json::Serializer::pretty(display_writer))
|
||||
.map_err(|serde_err| std::fmt::Error)
|
||||
}
|
||||
}
|
||||
@@ -641,13 +689,15 @@ struct DisplayWriter<'a, 'b>(&'a mut fmt::Formatter<'b>);
|
||||
|
||||
impl<'a, 'b> io::Write for DisplayWriter<'a, 'b> {
|
||||
fn write(&mut self, bytes: &[u8]) -> std::result::Result<usize, std::io::Error> {
|
||||
|
||||
self.0.write_str(&String::from_utf8_lossy(bytes))
|
||||
self.0
|
||||
.write_str(&String::from_utf8_lossy(bytes))
|
||||
.map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err))?;
|
||||
|
||||
Ok(bytes.len())
|
||||
}
|
||||
fn flush(&mut self) -> std::result::Result<(), std::io::Error> { todo!() }
|
||||
fn flush(&mut self) -> std::result::Result<(), std::io::Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for ItemData {
|
||||
@@ -662,5 +712,3 @@ impl PartialEq for ItemData {
|
||||
}
|
||||
}
|
||||
impl Eq for ItemData {}
|
||||
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
use ciborium::Value as CborValue;
|
||||
use colored::Colorize;
|
||||
use std::collections::binary_heap::Iter;
|
||||
use std::collections::HashMap;
|
||||
use std::iter::Map;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use ciborium::Value as CborValue;
|
||||
use tracing::{instrument, trace};
|
||||
use colored::Colorize;
|
||||
|
||||
use crate::error::{IntoMizeResult, MizeError, MizeResult};
|
||||
use crate::id::MizeId;
|
||||
use crate::instance::store::{Store, IdIter};
|
||||
use crate::error::{MizeError, MizeResult, IntoMizeResult};
|
||||
use crate::item::{Item, ItemData};
|
||||
use crate::instance::Instance;
|
||||
use crate::instance::store::{IdIter, Store};
|
||||
use crate::instance::Mize;
|
||||
use crate::item::get_raw_from_cbor;
|
||||
use crate::item::{Item, ItemData};
|
||||
use crate::mize_err;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -37,13 +37,12 @@ impl Store for MemStore {
|
||||
let path = id.after_store_part();
|
||||
old_data.set_path(path, data)?;
|
||||
inner.map.insert(id_to_u64(id)?, old_data);
|
||||
|
||||
} else {
|
||||
// if no data exists for that store_part, just insert
|
||||
inner.map.insert(id_to_u64(id)?, data);
|
||||
}
|
||||
|
||||
return Ok(())
|
||||
return Ok(());
|
||||
}
|
||||
fn get_links(&self, item: Item) -> MizeResult<Vec<MizeId>> {
|
||||
let inner = self.inner.lock()?;
|
||||
@@ -68,9 +67,14 @@ impl Store for MemStore {
|
||||
trace!("[ {} ] id: {:?}", "ARG".yellow(), id);
|
||||
let inner = self.inner.lock()?;
|
||||
|
||||
let cbor_val = inner.map.get(&id_to_u64(id.clone())?)
|
||||
.ok_or(MizeError::new()
|
||||
.msg(format!("Item with store_part: {}, id: {} does not exist in MemStore", id_to_u64(id.clone())?, id)))?;
|
||||
let cbor_val = inner
|
||||
.map
|
||||
.get(&id_to_u64(id.clone())?)
|
||||
.ok_or(MizeError::new().msg(format!(
|
||||
"Item with store_part: {}, id: {} does not exist in MemStore",
|
||||
id_to_u64(id.clone())?,
|
||||
id
|
||||
)))?;
|
||||
|
||||
let path = id.path();
|
||||
let mut id_iter = path.iter();
|
||||
@@ -94,7 +98,6 @@ impl Store for MemStore {
|
||||
return Ok(ret_data);
|
||||
}
|
||||
fn id_iter(&self) -> MizeResult<IdIter> {
|
||||
|
||||
IdIter::new(Box::new(self.to_owned()))
|
||||
}
|
||||
|
||||
@@ -104,7 +107,6 @@ impl Store for MemStore {
|
||||
let mut id = str_to_u64(prev_id_str)?;
|
||||
|
||||
loop {
|
||||
|
||||
id += 1;
|
||||
|
||||
if id > inner.next_id {
|
||||
@@ -114,7 +116,6 @@ impl Store for MemStore {
|
||||
if inner.map.contains_key(&id) {
|
||||
println!("returning: {}", id);
|
||||
return Ok(Some(format!("{}", id)));
|
||||
|
||||
} else {
|
||||
// try id +1
|
||||
continue;
|
||||
@@ -129,8 +130,13 @@ impl Store for MemStore {
|
||||
|
||||
impl MemStore {
|
||||
pub fn new() -> MemStore {
|
||||
let inner = MemStoreInner { map: HashMap::new(), next_id: 0 };
|
||||
return MemStore { inner: Arc::new(Mutex::new(inner)) };
|
||||
let inner = MemStoreInner {
|
||||
map: HashMap::new(),
|
||||
next_id: 0,
|
||||
};
|
||||
return MemStore {
|
||||
inner: Arc::new(Mutex::new(inner)),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,10 +145,8 @@ fn id_to_u64(id: MizeId) -> MizeResult<u64> {
|
||||
}
|
||||
|
||||
fn str_to_u64(id_str: &str) -> MizeResult<u64> {
|
||||
id_str.parse()
|
||||
.mize_result_msg(format!("Could not parse the store_part of mizeid {} into a u64 for the MemStore", id_str))
|
||||
id_str.parse().mize_result_msg(format!(
|
||||
"Could not parse the store_part of mizeid {} into a u64 for the MemStore",
|
||||
id_str
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
use core::fmt;
|
||||
use std::io;
|
||||
use serde::Serialize;
|
||||
use std::io;
|
||||
|
||||
use ciborium::{value::Integer, Value as CborValue};
|
||||
|
||||
use crate::{error::{IntoMizeResult, MizeError, MizeResult}, id::MizeId, instance::{self, connection::Connection, Instance}, item::{IntoItemData, ItemData}};
|
||||
use crate::{
|
||||
error::{IntoMizeResult, MizeError, MizeResult},
|
||||
id::MizeId,
|
||||
instance::{self, connection::Connection, Mize},
|
||||
item::{IntoItemData, ItemData},
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct MizeMessage {
|
||||
@@ -39,18 +44,22 @@ pub enum MessageCmd {
|
||||
Sub,
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
impl MizeMessage {
|
||||
pub fn new(value: CborValue, conn_id: u64) -> MizeMessage {
|
||||
MizeMessage { value, conn_id }
|
||||
}
|
||||
|
||||
pub fn new_get(id: MizeId, conn_id: u64) -> MizeMessage {
|
||||
let id_path = id.path().into_iter().map(|string| CborValue::Text(string.to_owned())).collect();
|
||||
let id_path = id
|
||||
.path()
|
||||
.into_iter()
|
||||
.map(|string| CborValue::Text(string.to_owned()))
|
||||
.collect();
|
||||
|
||||
let cmd = (CborValue::Integer(MSG_CMD.into()), CborValue::Integer(CMD_GET.into()));
|
||||
let cmd = (
|
||||
CborValue::Integer(MSG_CMD.into()),
|
||||
CborValue::Integer(CMD_GET.into()),
|
||||
);
|
||||
let id = (CborValue::Integer(MSG_ID.into()), CborValue::Array(id_path));
|
||||
let value = CborValue::Map(vec![cmd, id]);
|
||||
|
||||
@@ -58,9 +67,16 @@ impl MizeMessage {
|
||||
}
|
||||
|
||||
pub fn new_get_sub(id: MizeId, conn_id: u64) -> MizeMessage {
|
||||
let id_path = id.path().into_iter().map(|string| CborValue::Text(string.to_owned())).collect();
|
||||
let id_path = id
|
||||
.path()
|
||||
.into_iter()
|
||||
.map(|string| CborValue::Text(string.to_owned()))
|
||||
.collect();
|
||||
|
||||
let cmd = (CborValue::Integer(MSG_CMD.into()), CborValue::Integer(CMD_GET_SUB.into()));
|
||||
let cmd = (
|
||||
CborValue::Integer(MSG_CMD.into()),
|
||||
CborValue::Integer(CMD_GET_SUB.into()),
|
||||
);
|
||||
let id = (CborValue::Integer(MSG_ID.into()), CborValue::Array(id_path));
|
||||
let value = CborValue::Map(vec![cmd, id]);
|
||||
|
||||
@@ -68,9 +84,16 @@ impl MizeMessage {
|
||||
}
|
||||
|
||||
pub fn new_sub(id: MizeId, conn_id: u64) -> MizeMessage {
|
||||
let id_path = id.path().into_iter().map(|string| CborValue::Text(string.to_owned())).collect();
|
||||
let id_path = id
|
||||
.path()
|
||||
.into_iter()
|
||||
.map(|string| CborValue::Text(string.to_owned()))
|
||||
.collect();
|
||||
|
||||
let cmd = (CborValue::Integer(MSG_CMD.into()), CborValue::Integer(CMD_SUB.into()));
|
||||
let cmd = (
|
||||
CborValue::Integer(MSG_CMD.into()),
|
||||
CborValue::Integer(CMD_SUB.into()),
|
||||
);
|
||||
let id = (CborValue::Integer(MSG_ID.into()), CborValue::Array(id_path));
|
||||
let value = CborValue::Map(vec![cmd, id]);
|
||||
|
||||
@@ -78,16 +101,26 @@ impl MizeMessage {
|
||||
}
|
||||
|
||||
pub fn new_create(conn_id: u64) -> MizeMessage {
|
||||
let cmd = (CborValue::Integer(MSG_CMD.into()), CborValue::Integer(CMD_CREATE.into()));
|
||||
let cmd = (
|
||||
CborValue::Integer(MSG_CMD.into()),
|
||||
CborValue::Integer(CMD_CREATE.into()),
|
||||
);
|
||||
let value = CborValue::Map(vec![cmd]);
|
||||
|
||||
MizeMessage::new(value, conn_id)
|
||||
}
|
||||
|
||||
pub fn new_create_reply(id: MizeId, conn_id: u64) -> MizeMessage {
|
||||
let id_path = id.path().into_iter().map(|string| CborValue::Text(string.to_owned())).collect();
|
||||
let id_path = id
|
||||
.path()
|
||||
.into_iter()
|
||||
.map(|string| CborValue::Text(string.to_owned()))
|
||||
.collect();
|
||||
|
||||
let cmd = (CborValue::Integer(MSG_CMD.into()), CborValue::Integer(CMD_CREATE_REPLY.into()));
|
||||
let cmd = (
|
||||
CborValue::Integer(MSG_CMD.into()),
|
||||
CborValue::Integer(CMD_CREATE_REPLY.into()),
|
||||
);
|
||||
let id = (CborValue::Integer(MSG_ID.into()), CborValue::Array(id_path));
|
||||
let value = CborValue::Map(vec![cmd, id]);
|
||||
|
||||
@@ -95,9 +128,16 @@ impl MizeMessage {
|
||||
}
|
||||
|
||||
pub fn new_give(id: MizeId, data: ItemData, conn_id: u64) -> MizeMessage {
|
||||
let id_path = id.path().into_iter().map(|string| CborValue::Text(string.to_owned())).collect();
|
||||
let id_path = id
|
||||
.path()
|
||||
.into_iter()
|
||||
.map(|string| CborValue::Text(string.to_owned()))
|
||||
.collect();
|
||||
|
||||
let cmd = (CborValue::Integer(MSG_CMD.into()), CborValue::Integer(CMD_GIVE.into()));
|
||||
let cmd = (
|
||||
CborValue::Integer(MSG_CMD.into()),
|
||||
CborValue::Integer(CMD_GIVE.into()),
|
||||
);
|
||||
let id = (CborValue::Integer(MSG_ID.into()), CborValue::Array(id_path));
|
||||
let data = (CborValue::Integer(MSG_DATA.into()), data.cbor().to_owned());
|
||||
let value = CborValue::Map(vec![cmd, id, data]);
|
||||
@@ -106,9 +146,16 @@ impl MizeMessage {
|
||||
}
|
||||
|
||||
pub fn new_update_request(id: MizeId, data: ItemData, conn_id: u64) -> MizeMessage {
|
||||
let id_path = id.path().into_iter().map(|string| CborValue::Text(string.to_owned())).collect();
|
||||
let id_path = id
|
||||
.path()
|
||||
.into_iter()
|
||||
.map(|string| CborValue::Text(string.to_owned()))
|
||||
.collect();
|
||||
|
||||
let cmd = (CborValue::Integer(MSG_CMD.into()), CborValue::Integer(CMD_UPDATE_REQUEST.into()));
|
||||
let cmd = (
|
||||
CborValue::Integer(MSG_CMD.into()),
|
||||
CborValue::Integer(CMD_UPDATE_REQUEST.into()),
|
||||
);
|
||||
let id = (CborValue::Integer(MSG_ID.into()), CborValue::Array(id_path));
|
||||
let data = (CborValue::Integer(MSG_DATA.into()), data.cbor().to_owned());
|
||||
let value = CborValue::Map(vec![cmd, id, data]);
|
||||
@@ -117,9 +164,16 @@ impl MizeMessage {
|
||||
}
|
||||
|
||||
pub fn new_update(id: MizeId, data: ItemData, conn_id: u64) -> MizeMessage {
|
||||
let id_path = id.path().into_iter().map(|string| CborValue::Text(string.to_owned())).collect();
|
||||
let id_path = id
|
||||
.path()
|
||||
.into_iter()
|
||||
.map(|string| CborValue::Text(string.to_owned()))
|
||||
.collect();
|
||||
|
||||
let cmd = (CborValue::Integer(MSG_CMD.into()), CborValue::Integer(CMD_UPDATE.into()));
|
||||
let cmd = (
|
||||
CborValue::Integer(MSG_CMD.into()),
|
||||
CborValue::Integer(CMD_UPDATE.into()),
|
||||
);
|
||||
let id = (CborValue::Integer(MSG_ID.into()), CborValue::Array(id_path));
|
||||
let data = (CborValue::Integer(MSG_DATA.into()), data.cbor().to_owned());
|
||||
let value = CborValue::Map(vec![cmd, id, data]);
|
||||
@@ -137,7 +191,7 @@ impl MizeMessage {
|
||||
CborValue::Map(val) => val,
|
||||
_ => {
|
||||
return Err(MizeError::new().msg("Message was not a map"));
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
//check if in this map there is a c, otherwise return err
|
||||
@@ -172,20 +226,19 @@ impl MizeMessage {
|
||||
8 => MessageCmd::Sub,
|
||||
_ => {
|
||||
return Err(MizeError::new().msg("error cmd of msg was not a valid command"));
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
return Ok(cmd);
|
||||
}
|
||||
|
||||
|
||||
pub fn id_str(&mut self) -> MizeResult<Vec<String>> {
|
||||
// return err, if msg is not a map
|
||||
let msg_as_map = match &self.value {
|
||||
CborValue::Map(val) => val,
|
||||
_ => {
|
||||
return Err(MizeError::new().msg("Message was not a map"));
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
let vec_value = {
|
||||
@@ -206,26 +259,25 @@ impl MizeMessage {
|
||||
CborValue::Array(inner) => inner,
|
||||
_ => {
|
||||
return Err(MizeError::new().msg("Id is not a vector"));
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let mut vec_string: Vec<String> = Vec::new();
|
||||
for val in vec_value {
|
||||
match val {
|
||||
CborValue::Text(text) => {
|
||||
vec_string.push(text.to_owned())
|
||||
},
|
||||
CborValue::Text(text) => vec_string.push(text.to_owned()),
|
||||
_ => {
|
||||
return Err(MizeError::new().msg("one in the vec of the id in a msg is not of type Text"));
|
||||
},
|
||||
return Err(MizeError::new()
|
||||
.msg("one in the vec of the id in a msg is not of type Text"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(vec_string)
|
||||
}
|
||||
|
||||
pub fn id(&mut self, instance: &Instance) -> MizeResult<MizeId> {
|
||||
pub fn id(&mut self, instance: &Mize) -> MizeResult<MizeId> {
|
||||
let id_str = self.id_str()?;
|
||||
return instance.new_id(id_str);
|
||||
}
|
||||
@@ -236,7 +288,7 @@ impl MizeMessage {
|
||||
CborValue::Map(val) => val,
|
||||
_ => {
|
||||
return Err(MizeError::new().msg("Message was not a map"));
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
let data = {
|
||||
@@ -252,7 +304,7 @@ impl MizeMessage {
|
||||
}
|
||||
}
|
||||
}
|
||||
if ! found {
|
||||
if !found {
|
||||
return Err(MizeError::new().msg("error getting the data value form a msg"));
|
||||
}
|
||||
tmp_val
|
||||
@@ -262,30 +314,30 @@ impl MizeMessage {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// thanks to: https://stackoverflow.com/a/61768916
|
||||
struct DisplayWriter<'a, 'b>(&'a mut fmt::Formatter<'b>);
|
||||
|
||||
impl<'a, 'b> io::Write for DisplayWriter<'a, 'b> {
|
||||
fn write(&mut self, bytes: &[u8]) -> std::result::Result<usize, std::io::Error> {
|
||||
|
||||
self.0.write_str(&String::from_utf8_lossy(bytes))
|
||||
self.0
|
||||
.write_str(&String::from_utf8_lossy(bytes))
|
||||
.map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err))?;
|
||||
|
||||
Ok(bytes.len())
|
||||
}
|
||||
fn flush(&mut self) -> std::result::Result<(), std::io::Error> { todo!() }
|
||||
fn flush(&mut self) -> std::result::Result<(), std::io::Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for MizeMessage {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
|
||||
let mut err = false;
|
||||
|
||||
match self.to_owned().cmd() {
|
||||
Ok(cmd) => {
|
||||
writeln!(f, "MizeMessage with cmd: {:?}", cmd);
|
||||
},
|
||||
}
|
||||
Err(e) => {
|
||||
writeln!(f, "MizeMessage with unparsable cmd");
|
||||
err = true;
|
||||
@@ -296,7 +348,7 @@ impl fmt::Display for MizeMessage {
|
||||
Ok(id) => {
|
||||
let id_str = id.join("/");
|
||||
writeln!(f, "\tid: {:?}", id_str);
|
||||
},
|
||||
}
|
||||
Err(e) => {
|
||||
writeln!(f, "\t msg has no id");
|
||||
//err = true;
|
||||
@@ -307,40 +359,44 @@ impl fmt::Display for MizeMessage {
|
||||
Ok(data) => {
|
||||
let value = data.cbor();
|
||||
write!(f, "\tdata: ");
|
||||
let display_writer = DisplayWriter (f);
|
||||
if let Err(e) = value.serialize(&mut serde_json::Serializer::pretty(display_writer))
|
||||
.map_err(|serde_err| std::fmt::Error) {
|
||||
let display_writer = DisplayWriter(f);
|
||||
if let Err(e) = value
|
||||
.serialize(&mut serde_json::Serializer::pretty(display_writer))
|
||||
.map_err(|serde_err| std::fmt::Error)
|
||||
{
|
||||
writeln!(f, "serialize err: {:?}", e);
|
||||
err = true;
|
||||
}
|
||||
},
|
||||
}
|
||||
Err(e) => {
|
||||
writeln!(f, "\t msg has no data");
|
||||
//err = true;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if err {
|
||||
write!(f, "Full msg: ");
|
||||
let display_writer = DisplayWriter (f);
|
||||
self.value.serialize(&mut serde_json::Serializer::pretty(display_writer))
|
||||
.map_err(|serde_err| std::fmt::Error).mize_result_msg("serialize error")
|
||||
.inspect_err(|e| { e.clone().log(); });
|
||||
let display_writer = DisplayWriter(f);
|
||||
self.value
|
||||
.serialize(&mut serde_json::Serializer::pretty(display_writer))
|
||||
.map_err(|serde_err| std::fmt::Error)
|
||||
.mize_result_msg("serialize error")
|
||||
.inspect_err(|e| {
|
||||
e.clone().log();
|
||||
});
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for MizeMessage {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "\nMizeMessage: ");
|
||||
let display_writer = DisplayWriter (f);
|
||||
let display_writer = DisplayWriter(f);
|
||||
let value = self.to_owned().value();
|
||||
value.serialize(&mut serde_json::Serializer::pretty(display_writer))
|
||||
value
|
||||
.serialize(&mut serde_json::Serializer::pretty(display_writer))
|
||||
.map_err(|serde_err| std::fmt::Error)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
|
||||
#![ allow( warnings ) ]
|
||||
#![allow(warnings)]
|
||||
|
||||
static PROTO_VERSION: u8 = 1;
|
||||
|
||||
@@ -32,20 +31,22 @@ macro_rules! test_print {
|
||||
|
||||
// the core part has the code that can run on any platform
|
||||
mod core {
|
||||
pub mod memstore;
|
||||
pub mod config;
|
||||
pub mod error;
|
||||
pub mod id;
|
||||
pub mod instance;
|
||||
pub mod item;
|
||||
pub mod id;
|
||||
pub mod memstore;
|
||||
pub mod proto;
|
||||
pub mod error;
|
||||
pub mod types;
|
||||
}
|
||||
|
||||
pub use core::*;
|
||||
pub use core::instance::module::Module;
|
||||
pub use core::instance::Instance;
|
||||
pub use core::error::MizeError;
|
||||
pub use core::error::MizeResult;
|
||||
pub use core::instance::module::Module;
|
||||
pub use core::instance::Mize;
|
||||
pub use core::instance::MizePart;
|
||||
pub use core::*;
|
||||
use std::path::PathBuf;
|
||||
|
||||
// platform specific stuff
|
||||
@@ -67,7 +68,6 @@ pub mod platform {
|
||||
#[cfg(not(any(feature = "os-target", feature = "wasm-target")))]
|
||||
pub use super::super::instance_init;
|
||||
|
||||
|
||||
//////////// load_module
|
||||
#[cfg(feature = "os-target")]
|
||||
pub use super::os::load_module;
|
||||
@@ -78,7 +78,6 @@ pub mod platform {
|
||||
#[cfg(not(any(feature = "os-target", feature = "wasm-target")))]
|
||||
pub use super::super::load_module;
|
||||
|
||||
|
||||
//////////// fetch_module
|
||||
#[cfg(feature = "os-target")]
|
||||
pub use super::os::fetch_module;
|
||||
@@ -88,16 +87,19 @@ pub mod platform {
|
||||
|
||||
#[cfg(not(any(feature = "os-target", feature = "wasm-target")))]
|
||||
pub use super::super::fetch_module;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pub fn instance_init(instance: &mut core::instance::Mize) {}
|
||||
|
||||
pub fn instance_init(instance: &mut core::instance::Instance) {}
|
||||
|
||||
|
||||
pub fn load_module(instance: &mut core::instance::Instance, name: &str, path: Option<String>) -> MizeResult<()> { Ok(()) }
|
||||
|
||||
pub fn fetch_module(instance: &mut core::instance::Instance, name: &str) -> MizeResult<String> { Ok("oh noooooooooooooo, something went really really wrong, if this ends up in the executable....".to_owned()) }
|
||||
|
||||
pub fn load_module(
|
||||
instance: &mut core::instance::Mize,
|
||||
name: &str,
|
||||
path: Option<String>,
|
||||
) -> MizeResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn fetch_module(instance: &mut core::instance::Mize, name: &str) -> MizeResult<String> {
|
||||
Ok("oh noooooooooooooo, something went really really wrong, if this ends up in the executable....".to_owned())
|
||||
}
|
||||
|
||||
@@ -1,30 +1,28 @@
|
||||
use clap::ArgMatches;
|
||||
use core::result::Result::Err;
|
||||
use core::unimplemented;
|
||||
use flume::bounded;
|
||||
use home::home_dir;
|
||||
use mize::mize_err;
|
||||
use std::ffi::OsString;
|
||||
use std::io::Read;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use clap::ArgMatches;
|
||||
use home::home_dir;
|
||||
use flume::bounded;
|
||||
use mize::mize_err;
|
||||
use std::io::Read;
|
||||
use tracing::debug;
|
||||
|
||||
use mize::error::{IntoMizeResult, MizeError, MizeResult, MizeResultTrait};
|
||||
use mize::instance::Instance;
|
||||
use mize::platform::os::config_from_cli_args;
|
||||
use mize::instance::subscription::Update;
|
||||
use mize::platform::os::fsstore::FileStore;
|
||||
use mize::instance::subscription::Subscription;
|
||||
use mize::instance::subscription::Update;
|
||||
use mize::instance::Mize;
|
||||
use mize::item::{IntoItemData, ItemData};
|
||||
|
||||
|
||||
use mize::platform::os::config_from_cli_args;
|
||||
use mize::platform::os::fsstore::FileStore;
|
||||
|
||||
pub fn get(sub_matches: &ArgMatches) -> MizeResult<()> {
|
||||
let instance = Mize::with_config(config_from_cli_args(sub_matches)?)?;
|
||||
|
||||
let instance = Instance::with_config(config_from_cli_args(sub_matches)?)?;
|
||||
|
||||
let id = sub_matches.get_one::<String>("id")
|
||||
let id = sub_matches
|
||||
.get_one::<String>("id")
|
||||
.ok_or(MizeError::new().msg("No id Argument specified"))?;
|
||||
|
||||
let item = instance.get(id)?;
|
||||
@@ -44,15 +42,12 @@ pub fn get(sub_matches: &ArgMatches) -> MizeResult<()> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
||||
pub fn call(sub_matches: &ArgMatches) -> MizeResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
pub fn create(sub_matches: &ArgMatches) -> MizeResult<()> {
|
||||
|
||||
let mut instance = Instance::with_config(config_from_cli_args(sub_matches)?)?;
|
||||
let mut instance = Mize::with_config(config_from_cli_args(sub_matches)?)?;
|
||||
|
||||
let item = instance.new_item()?;
|
||||
|
||||
@@ -62,37 +57,32 @@ pub fn create(sub_matches: &ArgMatches) -> MizeResult<()> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
||||
pub fn is_running(sub_matches: &ArgMatches) -> MizeResult<()> {
|
||||
|
||||
println!("not implemented");
|
||||
Err(mize_err!("not implemented"))
|
||||
}
|
||||
|
||||
|
||||
pub fn mount(sub_matches: &ArgMatches) -> MizeResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
pub fn run(sub_matches: &ArgMatches) -> MizeResult<()> {
|
||||
|
||||
let instance = Instance::with_config(config_from_cli_args(sub_matches)?)?;
|
||||
let instance = Mize::with_config(config_from_cli_args(sub_matches)?)?;
|
||||
|
||||
instance.wait();
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
||||
pub fn set(sub_matches: &ArgMatches) -> MizeResult<()> {
|
||||
let instance = Mize::with_config(config_from_cli_args(sub_matches)?)?;
|
||||
|
||||
let instance = Instance::with_config(config_from_cli_args(sub_matches)?)?;
|
||||
|
||||
let id = sub_matches.get_one::<String>("id")
|
||||
let id = sub_matches
|
||||
.get_one::<String>("id")
|
||||
.ok_or(MizeError::new().msg("No id Argument specified"))?;
|
||||
|
||||
let value = sub_matches.get_one::<String>("value")
|
||||
let value = sub_matches
|
||||
.get_one::<String>("value")
|
||||
.ok_or(MizeError::new().msg("No value Argument specified"))?;
|
||||
|
||||
instance.set_blocking(id, value.into_item_data())?;
|
||||
@@ -100,12 +90,11 @@ pub fn set(sub_matches: &ArgMatches) -> MizeResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
pub fn show(sub_matches: &ArgMatches) -> MizeResult<()> {
|
||||
let instance = Mize::with_config(config_from_cli_args(sub_matches)?)?;
|
||||
|
||||
let instance = Instance::with_config(config_from_cli_args(sub_matches)?)?;
|
||||
|
||||
let id = sub_matches.get_one::<String>("id")
|
||||
let id = sub_matches
|
||||
.get_one::<String>("id")
|
||||
.ok_or(MizeError::new().msg("No id Argument specified"))?;
|
||||
|
||||
let item = instance.get(id)?;
|
||||
@@ -124,14 +113,12 @@ pub fn show(sub_matches: &ArgMatches) -> MizeResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
pub fn stop(sub_matches: &ArgMatches) -> MizeResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
pub fn gui(sub_matches: &ArgMatches) -> MizeResult<()> {
|
||||
let mut instance = Instance::with_config(config_from_cli_args(sub_matches)?)?;
|
||||
let mut instance = Mize::with_config(config_from_cli_args(sub_matches)?)?;
|
||||
|
||||
instance.load_module("mme")?;
|
||||
|
||||
@@ -141,7 +128,6 @@ pub fn gui(sub_matches: &ArgMatches) -> MizeResult<()> {
|
||||
}
|
||||
|
||||
pub fn format_cbor(sub_matches: &ArgMatches) -> MizeResult<()> {
|
||||
|
||||
let mut input: Vec<u8> = Vec::new();
|
||||
let stdin = std::io::stdin();
|
||||
let mut handle = stdin.lock();
|
||||
@@ -155,20 +141,26 @@ pub fn format_cbor(sub_matches: &ArgMatches) -> MizeResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
pub fn run_from_module(cmd: &str, sub_matches: &ArgMatches) -> MizeResult<()> {
|
||||
let default = OsString::default();
|
||||
let mut sub_cmd_line: Vec<OsString> = sub_matches.get_many::<OsString>("").unwrap().map(|e| e.to_owned()).collect();
|
||||
let mut sub_cmd_line: Vec<OsString> = sub_matches
|
||||
.get_many::<OsString>("")
|
||||
.unwrap()
|
||||
.map(|e| e.to_owned())
|
||||
.collect();
|
||||
sub_cmd_line.insert(0, OsString::from_str(cmd)?);
|
||||
|
||||
let mut instance = Instance::with_config(config_from_cli_args(sub_matches)?)?;
|
||||
let mut instance = Mize::with_config(config_from_cli_args(sub_matches)?)?;
|
||||
|
||||
debug!("loading module '{}'", cmd);
|
||||
instance.load_module(cmd)?;
|
||||
|
||||
instance.get_module(cmd)?.run_cli(&instance, sub_cmd_line)
|
||||
.ok_or(mize_err!("The Module '{cmd}' does not implement the run_cli() functionality"))??;
|
||||
instance
|
||||
.get_module(cmd)?
|
||||
.run_cli(&instance, sub_cmd_line)
|
||||
.ok_or(mize_err!(
|
||||
"The Module '{cmd}' does not implement the run_cli() functionality"
|
||||
))??;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::fs::OpenOptions;
|
||||
use sysinfo::{System, Pid, ProcessRefreshKind, RefreshKind};
|
||||
use std::io::Write;
|
||||
use ciborium::Value as CborValue;
|
||||
use std::fs;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::Write;
|
||||
use std::path::{Path, PathBuf};
|
||||
use sysinfo::{Pid, ProcessRefreshKind, RefreshKind, System};
|
||||
use tracing::debug;
|
||||
|
||||
use crate::core::id::MizeId;
|
||||
use crate::core::item::{Item, ItemData};
|
||||
use crate::error::{IntoMizeResult, MizeError, MizeResult};
|
||||
use crate::instance::store::IdIter;
|
||||
use crate::instance::{self, Mize};
|
||||
use crate::item::get_raw_from_cbor;
|
||||
use crate::item::IntoItemData;
|
||||
use crate::memstore::MemStore;
|
||||
use crate::{core::instance::store::Store, mize_err};
|
||||
use crate::error::{IntoMizeResult, MizeResult, MizeError};
|
||||
use crate::core::item::{ItemData, Item};
|
||||
use crate::core::id::MizeId;
|
||||
use crate::item::get_raw_from_cbor;
|
||||
use crate::instance::{self, Instance};
|
||||
use tokio::net::UnixStream;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -24,7 +24,6 @@ pub struct FileStore {
|
||||
|
||||
impl FileStore {
|
||||
pub fn new(path_str: &str) -> MizeResult<FileStore> {
|
||||
|
||||
let path = Path::new(path_str);
|
||||
|
||||
// create that path if it does not exist
|
||||
@@ -50,19 +49,25 @@ impl FileStore {
|
||||
fs::write(path.join("next_id"), "1");
|
||||
}
|
||||
|
||||
Ok(FileStore { path: Path::new(&path).to_owned() })
|
||||
Ok(FileStore {
|
||||
path: Path::new(&path).to_owned(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn store_is_opened(store_path: String, instance: &mut Instance) -> MizeResult<bool> {
|
||||
|
||||
pub fn store_is_opened(store_path: String, instance: &mut Mize) -> MizeResult<bool> {
|
||||
// this was the old method....
|
||||
//let valid_pid_file = valid_pid_file(Path::new(&store_path))?.is_some();
|
||||
|
||||
let can_connect_to_sock = match instance.spawn_async_blocking("con_test_thread", try_connect_to_sock(store_path.clone())) {
|
||||
let can_connect_to_sock = match instance
|
||||
.spawn_async_blocking("con_test_thread", try_connect_to_sock(store_path.clone()))
|
||||
{
|
||||
Ok(_) => true,
|
||||
Err(_) => false,
|
||||
};
|
||||
debug!("MiZe Store at {} opened: {}", store_path, can_connect_to_sock);
|
||||
debug!(
|
||||
"MiZe Store at {} opened: {}",
|
||||
store_path, can_connect_to_sock
|
||||
);
|
||||
Ok(can_connect_to_sock)
|
||||
}
|
||||
}
|
||||
@@ -76,11 +81,16 @@ async fn try_connect_to_sock(store_path: String) -> MizeResult<()> {
|
||||
|
||||
impl Store for FileStore {
|
||||
fn new_id(&self) -> MizeResult<String> {
|
||||
|
||||
let mut next_id: u64 = String::from_utf8(fs::read(self.path.join("next_id"))
|
||||
.mize_result_msg(format!("could not read next_id at '{}'", self.path.display()))?)?
|
||||
let mut next_id: u64 =
|
||||
String::from_utf8(fs::read(self.path.join("next_id")).mize_result_msg(format!(
|
||||
"could not read next_id at '{}'",
|
||||
self.path.display()
|
||||
))?)?
|
||||
.parse()
|
||||
.mize_result_msg(format!("could not parse next_id at '{}' to u64", self.path.display()))?;
|
||||
.mize_result_msg(format!(
|
||||
"could not parse next_id at '{}' to u64",
|
||||
self.path.display()
|
||||
))?;
|
||||
|
||||
let id_string = format!("{}", next_id);
|
||||
|
||||
@@ -92,7 +102,11 @@ impl Store for FileStore {
|
||||
}
|
||||
|
||||
fn set(&self, id: MizeId, data: ItemData) -> MizeResult<()> {
|
||||
let path = self.path.join("store").join(id.namespace_str()).join(id.store_part());
|
||||
let path = self
|
||||
.path
|
||||
.join("store")
|
||||
.join(id.namespace_str())
|
||||
.join(id.store_part());
|
||||
fs::create_dir_all(self.path.join("store").join(id.namespace_str()))?;
|
||||
|
||||
let file = OpenOptions::new().write(true).create(true).open(path)?;
|
||||
@@ -110,12 +124,18 @@ impl Store for FileStore {
|
||||
}
|
||||
|
||||
fn get_value_raw(&self, id: MizeId) -> MizeResult<Vec<u8>> {
|
||||
let path = self.path.join("store").join(id.namespace_str()).join(id.store_part());
|
||||
let path = self
|
||||
.path
|
||||
.join("store")
|
||||
.join(id.namespace_str())
|
||||
.join(id.store_part());
|
||||
|
||||
let file = OpenOptions::new().read(true).create(true).open(path)?;
|
||||
|
||||
let cbor_val: CborValue = ciborium::from_reader(file)
|
||||
.mize_result_msg(format!("could not read file '{}' from FileStore", self.path.join("store").join(id.store_part()).display()))?;
|
||||
let cbor_val: CborValue = ciborium::from_reader(file).mize_result_msg(format!(
|
||||
"could not read file '{}' from FileStore",
|
||||
self.path.join("store").join(id.store_part()).display()
|
||||
))?;
|
||||
|
||||
let path = id.path();
|
||||
let mut id_iter = path.iter();
|
||||
@@ -126,15 +146,27 @@ impl Store for FileStore {
|
||||
}
|
||||
|
||||
fn get_value_data_full(&self, id: MizeId) -> MizeResult<ItemData> {
|
||||
let file_path = self.path.join("store").join(id.namespace_str()).join(id.store_part());
|
||||
if !file_path.exists() {
|
||||
let file_path = self
|
||||
.path
|
||||
.join("store")
|
||||
.join(id.namespace_str())
|
||||
.join(id.store_part());
|
||||
if !file_path.exists() {}
|
||||
let file = OpenOptions::new()
|
||||
.read(true)
|
||||
.open(file_path.clone())
|
||||
.map_err(|e| {
|
||||
mize_err!(
|
||||
"fsstoree: Unable to open '{}', err: {}",
|
||||
file_path.display(),
|
||||
e
|
||||
)
|
||||
})?;
|
||||
|
||||
}
|
||||
let file = OpenOptions::new().read(true).open(file_path.clone())
|
||||
.map_err(|e| mize_err!("fsstoree: Unable to open '{}', err: {}", file_path.display(), e))?;
|
||||
|
||||
let cbor_value: CborValue = ciborium::from_reader(file)
|
||||
.mize_result_msg(format!("could not read file '{}' from FileStore", self.path.join("store").join(id.store_part()).display()))?;
|
||||
let cbor_value: CborValue = ciborium::from_reader(file).mize_result_msg(format!(
|
||||
"could not read file '{}' from FileStore",
|
||||
self.path.join("store").join(id.store_part()).display()
|
||||
))?;
|
||||
let data: ItemData = cbor_value.into_item_data();
|
||||
|
||||
let tmp = id.path();
|
||||
@@ -157,7 +189,6 @@ impl Store for FileStore {
|
||||
}
|
||||
|
||||
fn valid_pid_file(path: &Path) -> MizeResult<Option<u32>> {
|
||||
|
||||
let pid_file_path = path.join("pid");
|
||||
|
||||
// if the pid file does not exist, there is no pid...
|
||||
@@ -166,10 +197,15 @@ fn valid_pid_file(path: &Path) -> MizeResult<Option<u32>> {
|
||||
}
|
||||
|
||||
// read pid file
|
||||
let pid: u32 = String::from_utf8(fs::read(&pid_file_path)
|
||||
.mize_result_msg(format!("Could not read contents of pid file at '{}'", pid_file_path.display()))?)?
|
||||
let pid: u32 = String::from_utf8(fs::read(&pid_file_path).mize_result_msg(format!(
|
||||
"Could not read contents of pid file at '{}'",
|
||||
pid_file_path.display()
|
||||
))?)?
|
||||
.parse()
|
||||
.mize_result_msg(format!("Could not parse contents of pid file at '{}' to u32", pid_file_path.display()))?;
|
||||
.mize_result_msg(format!(
|
||||
"Could not parse contents of pid file at '{}' to u32",
|
||||
pid_file_path.display()
|
||||
))?;
|
||||
|
||||
if Path::new("/proc").join(format!("{}", pid)).exists() {
|
||||
return Ok(Some(pid));
|
||||
@@ -177,4 +213,3 @@ fn valid_pid_file(path: &Path) -> MizeResult<Option<u32>> {
|
||||
return Ok(None);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +1,27 @@
|
||||
#![allow(warnings)]
|
||||
|
||||
#![ allow( warnings ) ]
|
||||
|
||||
use clap::builder::OsStr;
|
||||
use clap::{crate_version, Arg, Command};
|
||||
use clap::{ArgAction, ArgMatches};
|
||||
use std::ffi::OsString;
|
||||
use std::path::PathBuf;
|
||||
use std::process::exit;
|
||||
use clap::builder::OsStr;
|
||||
use clap::{ArgAction, ArgMatches};
|
||||
use clap::{Arg, crate_version, Command};
|
||||
|
||||
use mize::error::{MizeError, MizeResult};
|
||||
use mize::{instance, Instance};
|
||||
use mize::item::ItemData;
|
||||
use tokio::sync::{Mutex, mpsc};
|
||||
use std::sync::Arc;
|
||||
use std::io::Write;
|
||||
use colored::Colorize;
|
||||
use std::env;
|
||||
use tracing_subscriber::fmt::Subscriber;
|
||||
use tracing::Level;
|
||||
use tracing::level_filters::LevelFilter;
|
||||
use tracing_subscriber::filter::EnvFilter;
|
||||
use mize::error::{MizeError, MizeResult};
|
||||
use mize::item::ItemData;
|
||||
use mize::platform::os::logging::init_logger;
|
||||
use mize::{instance, Mize};
|
||||
use std::env;
|
||||
use std::io::Write;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::{mpsc, Mutex};
|
||||
use tracing::level_filters::LevelFilter;
|
||||
use tracing::Level;
|
||||
use tracing_subscriber::filter::EnvFilter;
|
||||
use tracing_subscriber::fmt::Subscriber;
|
||||
|
||||
use tracing::{trace, debug, info, warn, error};
|
||||
use tracing::{debug, error, info, trace, warn};
|
||||
|
||||
mod cli;
|
||||
|
||||
@@ -74,7 +73,8 @@ fn main() {
|
||||
// some unknown command passed
|
||||
Some((cmd, sub_matches)) => cli::run_from_module(cmd, sub_matches),
|
||||
|
||||
None => Err(MizeError::new().msg("No subcommand was passed. use --help to list availavle comamnds.")),
|
||||
None => Err(MizeError::new()
|
||||
.msg("No subcommand was passed. use --help to list availavle comamnds.")),
|
||||
};
|
||||
|
||||
if let Err(err) = result {
|
||||
@@ -83,105 +83,83 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
fn cli_matches() -> clap::ArgMatches {
|
||||
|
||||
|
||||
let main = Command::new(APPNAME)
|
||||
.version(crate_version!())
|
||||
.author("Sebastian Moser")
|
||||
.about("The MiZe Command line tool")
|
||||
.allow_external_subcommands(true)
|
||||
.arg(Arg::new("verbose")
|
||||
.arg(
|
||||
Arg::new("verbose")
|
||||
.long("verbose")
|
||||
.short('v')
|
||||
.action(ArgAction::Count)
|
||||
.global(true)
|
||||
.global(true),
|
||||
)
|
||||
.arg(Arg::new("log-level")
|
||||
.arg(
|
||||
Arg::new("log-level")
|
||||
.long("log-level")
|
||||
.value_name("LOGLEVEL")
|
||||
.help("set the log-level to one of OFF, ERROR, WARN, INFO, DEBUG, TRACE")
|
||||
.global(true)
|
||||
.global(true),
|
||||
)
|
||||
.arg(Arg::new("silent")
|
||||
.arg(
|
||||
Arg::new("silent")
|
||||
.long("silent")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("set the log-level to OFF")
|
||||
.global(true)
|
||||
.global(true),
|
||||
)
|
||||
.arg(Arg::new("folder")
|
||||
.arg(
|
||||
Arg::new("folder")
|
||||
.short('f')
|
||||
.long("folder")
|
||||
.help("The folder the Instance stores all it's data and the socket for connections")
|
||||
.global(true)
|
||||
.global(true),
|
||||
)
|
||||
.arg(Arg::new("config")
|
||||
.arg(
|
||||
Arg::new("config")
|
||||
.short('c')
|
||||
.long("config")
|
||||
.help("overwrite config options")
|
||||
.global(true)
|
||||
.global(true),
|
||||
)
|
||||
.arg(Arg::new("config-file")
|
||||
.arg(
|
||||
Arg::new("config-file")
|
||||
.long("config-file")
|
||||
.help("specify a config file")
|
||||
.global(true)
|
||||
.global(true),
|
||||
)
|
||||
.subcommand(
|
||||
Command::new("run")
|
||||
.aliases(["r"])
|
||||
.about("Run a MiZe Instance")
|
||||
)
|
||||
.subcommand(Command::new("stop")
|
||||
.about("Stop a MiZe Instance")
|
||||
)
|
||||
.subcommand(
|
||||
Command::new("mount")
|
||||
.aliases(["m"])
|
||||
.about("Run a MiZe Instance"),
|
||||
)
|
||||
.subcommand(Command::new("stop").about("Stop a MiZe Instance"))
|
||||
.subcommand(Command::new("mount").aliases(["m"]))
|
||||
.subcommand(
|
||||
Command::new("get")
|
||||
.aliases(["g"])
|
||||
.arg(Arg::new("id").help("The id or path to get"))
|
||||
.arg(Arg::new("recurse")
|
||||
.short('r')
|
||||
.action(ArgAction::Count)
|
||||
)
|
||||
.arg(Arg::new("recurse").short('r').action(ArgAction::Count)),
|
||||
)
|
||||
.subcommand(
|
||||
Command::new("set")
|
||||
.aliases(["s"])
|
||||
.arg(Arg::new("id").help("The id or path to set"))
|
||||
.arg(Arg::new("value").help("The value to set the path to"))
|
||||
.arg(Arg::new("value").help("The value to set the path to")),
|
||||
)
|
||||
.subcommand(
|
||||
Command::new("show")
|
||||
.aliases(["so"])
|
||||
.arg(Arg::new("id").help("The id or path to sub to and show"))
|
||||
)
|
||||
.subcommand(
|
||||
Command::new("call")
|
||||
.aliases(["c"])
|
||||
)
|
||||
.subcommand(
|
||||
Command::new("create")
|
||||
.aliases(["cr"])
|
||||
)
|
||||
.subcommand(
|
||||
Command::new("is-running")
|
||||
.aliases(["isr"])
|
||||
)
|
||||
.subcommand(
|
||||
Command::new("gui")
|
||||
)
|
||||
.subcommand(
|
||||
Command::new("format-cbor")
|
||||
.arg(Arg::new("id").help("The id or path to sub to and show")),
|
||||
)
|
||||
.subcommand(Command::new("call").aliases(["c"]))
|
||||
.subcommand(Command::new("create").aliases(["cr"]))
|
||||
.subcommand(Command::new("is-running").aliases(["isr"]))
|
||||
.subcommand(Command::new("gui"))
|
||||
.subcommand(Command::new("format-cbor"))
|
||||
.arg_required_else_help(true);
|
||||
|
||||
return main.get_matches();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
use ciborium::Value as CborValue;
|
||||
use clap::ArgMatches;
|
||||
use flate2::bufread::GzDecoder;
|
||||
use serde::Deserialize;
|
||||
use sha2::{Digest, Sha256, Sha512};
|
||||
use std::env::VarError;
|
||||
use std::fs;
|
||||
use tracing::{debug, error, info, trace, warn};
|
||||
use clap::ArgMatches;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::UNIX_EPOCH;
|
||||
use sha2::{Sha256, Sha512, Digest};
|
||||
use flate2::bufread::GzDecoder;
|
||||
use tar::Archive;
|
||||
use std::fs::File;
|
||||
use std::io::copy;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::UNIX_EPOCH;
|
||||
use tar::Archive;
|
||||
use tracing::{debug, error, info, trace, warn};
|
||||
|
||||
use crate::id::MizeId;
|
||||
use crate::instance::store::Store;
|
||||
use crate::instance::Instance;
|
||||
use crate::error::{IntoMizeResult, MizeError, MizeResult};
|
||||
use crate::id::MizeId;
|
||||
use crate::instance::module::EmptyModule;
|
||||
use crate::instance::store::Store;
|
||||
use crate::instance::Mize;
|
||||
use crate::item::{data_from_string, IntoItemData, ItemData};
|
||||
use crate::memstore::MemStore;
|
||||
use crate::{mize_err, Module};
|
||||
use crate::instance::module::EmptyModule;
|
||||
|
||||
use self::fsstore::FileStore;
|
||||
|
||||
@@ -33,8 +33,7 @@ mod unix_socket;
|
||||
use crate::platform::os::unix_socket::UnixListener;
|
||||
//mod web;
|
||||
|
||||
|
||||
pub fn os_instance_init(instance: &mut Instance) -> MizeResult<()> {
|
||||
pub fn os_instance_init(instance: &mut Mize) -> MizeResult<()> {
|
||||
// this is the code, that runs to initialize an Instance on a system with an os present.
|
||||
|
||||
////// load MIZE_CONFIG_FILE as the instance, which is item 0
|
||||
@@ -43,16 +42,19 @@ pub fn os_instance_init(instance: &mut Instance) -> MizeResult<()> {
|
||||
let config = config_from_file(config_file_path)?;
|
||||
debug!("env var MIZE_CONFIG_FILE present");
|
||||
instance.set_blocking("0", config)?;
|
||||
trace!("config after MIZE_CONFIG_FILE env var: {}", instance.get("self/config")?);
|
||||
trace!(
|
||||
"config after MIZE_CONFIG_FILE env var: {}",
|
||||
instance.get("self/config")?
|
||||
);
|
||||
}
|
||||
Err(var_err) => match var_err {
|
||||
VarError::NotPresent => {
|
||||
debug!("env var MIZE_CONFIG_FILE NOT present");
|
||||
},
|
||||
}
|
||||
VarError::NotUnicode(_) => {
|
||||
warn!("env var MIZE_CONFIG_FILE is not Unicode, so not reading it")
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
////// load config from MIZE_CONFIG env var
|
||||
@@ -61,44 +63,49 @@ pub fn os_instance_init(instance: &mut Instance) -> MizeResult<()> {
|
||||
let config = data_from_string(config_string)?;
|
||||
debug!("env var MIZE_CONFIG present");
|
||||
instance.set_blocking("self/config", config)?;
|
||||
trace!("config after MIZE_CONFIG env var: {}", instance.get("self/config")?);
|
||||
trace!(
|
||||
"config after MIZE_CONFIG env var: {}",
|
||||
instance.get("self/config")?
|
||||
);
|
||||
}
|
||||
Err(var_err) => match var_err {
|
||||
VarError::NotPresent => {
|
||||
debug!("env var MIZE_CONFIG NOT present")
|
||||
},
|
||||
}
|
||||
VarError::NotUnicode(_) => {
|
||||
warn!("env var MIZE_CONFIG is not Unicode, so not reading it")
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
////// if a config.store_path is set, upgrade to the filestore there
|
||||
let mut test = instance.get("0")?.as_data_full()?;
|
||||
let mut store_path = match instance.get("self/config/store_path")?.value_string() {
|
||||
Ok(path) => {
|
||||
path
|
||||
},
|
||||
Ok(path) => path,
|
||||
Err(e) => {
|
||||
// the default store_path: $HOME/.mize
|
||||
let home_dir = if let Some(dir) = std::env::home_dir() {
|
||||
dir
|
||||
} else {
|
||||
return Err(mize_err!("could not get home_dir and store_path is not set in the config"));
|
||||
return Err(mize_err!(
|
||||
"could not get home_dir and store_path is not set in the config"
|
||||
));
|
||||
};
|
||||
|
||||
let store_path_buff = home_dir.join(".mize");
|
||||
let store_path = store_path_buff.display().to_string();
|
||||
|
||||
instance.set_blocking("self/config/store_path", store_path.clone().into_item_data())?;
|
||||
instance.set_blocking(
|
||||
"self/config/store_path",
|
||||
store_path.clone().into_item_data(),
|
||||
)?;
|
||||
|
||||
let store_path = instance.get("self/config/store_path")?.value_string()?;
|
||||
|
||||
println!("store_path: {}", store_path);
|
||||
|
||||
store_path
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
if FileStore::store_is_opened(store_path.to_owned(), instance)? {
|
||||
@@ -117,7 +124,6 @@ pub fn os_instance_init(instance: &mut Instance) -> MizeResult<()> {
|
||||
{
|
||||
error!("CONNECTING... would connect, but that is not implemented on windows yet");
|
||||
}
|
||||
|
||||
} else {
|
||||
// else open it ourselves
|
||||
let file_store = FileStore::new(store_path.as_str())?;
|
||||
@@ -132,7 +138,7 @@ pub fn os_instance_init(instance: &mut Instance) -> MizeResult<()> {
|
||||
|
||||
#[cfg(target_family = "windows")]
|
||||
{
|
||||
warn!("would add a Listener on a local socket, but that is not yet implemented for windows");;
|
||||
warn!("would add a Listener on a local socket, but that is not yet implemented for windows");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,15 +155,24 @@ pub fn seconds_since_modification(path: &Path) -> MizeResult<u64> {
|
||||
Ok(duration.as_secs())
|
||||
}
|
||||
|
||||
pub fn get_module_hash(instance: &mut Instance, name: &str, mut options: ItemData) -> MizeResult<(String, String)> {
|
||||
|
||||
pub fn get_module_hash(
|
||||
instance: &mut Mize,
|
||||
name: &str,
|
||||
mut options: ItemData,
|
||||
) -> MizeResult<(String, String)> {
|
||||
let mut selector_data = instance.get("self/config/selector")?.as_data_full()?;
|
||||
|
||||
// handle the case, when we want a module for not the system we are running on...
|
||||
println!("get_module_hash: name: {}", name);
|
||||
let mut name_parts = name.split(".");
|
||||
if name_parts.next().ok_or(mize_err!("no 0th element in the modName"))? == "cross" {
|
||||
let system = name_parts.next().ok_or(mize_err!("no 1th element in the modName"))?;
|
||||
if name_parts
|
||||
.next()
|
||||
.ok_or(mize_err!("no 0th element in the modName"))?
|
||||
== "cross"
|
||||
{
|
||||
let system = name_parts
|
||||
.next()
|
||||
.ok_or(mize_err!("no 1th element in the modName"))?;
|
||||
let mod_name: String = name_parts.collect();
|
||||
println!("get_module_hash: mod_name: {}", mod_name);
|
||||
if mod_name == "" {
|
||||
@@ -183,7 +198,8 @@ pub fn get_module_hash(instance: &mut Instance, name: &str, mut options: ItemDat
|
||||
|
||||
let result = hasher.finalize();
|
||||
|
||||
let mut hex: String = result.iter()
|
||||
let mut hex: String = result
|
||||
.iter()
|
||||
.map(|b| format!("{:02x}", b).to_string())
|
||||
.collect::<Vec<String>>()
|
||||
.join("");
|
||||
@@ -191,25 +207,46 @@ pub fn get_module_hash(instance: &mut Instance, name: &str, mut options: ItemDat
|
||||
hex.truncate(32);
|
||||
|
||||
return Ok((hex, selector_str));
|
||||
|
||||
}
|
||||
|
||||
fn download_module(instance: &mut Instance, store_path: &str, module_url: &str, module_hash: &str, module_name: &str, module_selector: &str) -> MizeResult<()> {
|
||||
|
||||
|
||||
fn download_module(
|
||||
instance: &mut Mize,
|
||||
store_path: &str,
|
||||
module_url: &str,
|
||||
module_hash: &str,
|
||||
module_name: &str,
|
||||
module_selector: &str,
|
||||
) -> MizeResult<()> {
|
||||
let tmp_file_path_gz = format!("{}/{}.tar.gz", store_path, module_hash);
|
||||
|
||||
let tmp_gz_file = if !PathBuf::from(tmp_file_path_gz.clone()).exists() {
|
||||
|
||||
let mut tmp_gz_file = File::create(&tmp_file_path_gz)?;
|
||||
|
||||
debug!("downloading module '{}' with hash: {}", module_name, module_hash);
|
||||
debug!(
|
||||
"downloading module '{}' with hash: {}",
|
||||
module_name, module_hash
|
||||
);
|
||||
|
||||
let response = http_req::request::get(format!("http://{}/mize/dist/{}-{}.tar.gz", module_url, module_hash, module_name), &mut tmp_gz_file)?;
|
||||
let response = http_req::request::get(
|
||||
format!(
|
||||
"http://{}/mize/dist/{}-{}.tar.gz",
|
||||
module_url, module_hash, module_name
|
||||
),
|
||||
&mut tmp_gz_file,
|
||||
)?;
|
||||
|
||||
let code = response.status_code();
|
||||
if code != 200.into() {
|
||||
return Err(mize_err!("failed to get module '{}' with hash '{}' and selector: {}", module_name, module_hash, module_selector).msg(format!("the http request to fetch the module returned a status code of: {}", code)));
|
||||
return Err(mize_err!(
|
||||
"failed to get module '{}' with hash '{}' and selector: {}",
|
||||
module_name,
|
||||
module_hash,
|
||||
module_selector
|
||||
)
|
||||
.msg(format!(
|
||||
"the http request to fetch the module returned a status code of: {}",
|
||||
code
|
||||
)));
|
||||
}
|
||||
|
||||
tmp_gz_file
|
||||
@@ -233,10 +270,15 @@ fn download_module(instance: &mut Instance, store_path: &str, module_url: &str,
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn fetch_module(instance: &mut Instance, module_name: &str) -> MizeResult<String> {
|
||||
|
||||
pub fn fetch_module(instance: &mut Mize, module_name: &str) -> MizeResult<String> {
|
||||
let module_name_with_slashes = module_name.replace(".", "/");
|
||||
if let Ok(module_path) = instance.get(format!("self/config/module_dir/{}", module_name_with_slashes))?.value_string() {
|
||||
if let Ok(module_path) = instance
|
||||
.get(format!(
|
||||
"self/config/module_dir/{}",
|
||||
module_name_with_slashes
|
||||
))?
|
||||
.value_string()
|
||||
{
|
||||
// in case a dir is configured, which holds the modules output
|
||||
return Ok(module_path);
|
||||
} else {
|
||||
@@ -245,29 +287,41 @@ pub fn fetch_module(instance: &mut Instance, module_name: &str) -> MizeResult<St
|
||||
|
||||
let store_path = instance.get("self/config/store_path")?.value_string()?;
|
||||
|
||||
let (module_hash, module_selector) = get_module_hash(instance, module_name, ItemData::new())?;
|
||||
let (module_hash, module_selector) =
|
||||
get_module_hash(instance, module_name, ItemData::new())?;
|
||||
|
||||
if !PathBuf::from(format!("{}/modules/{}", store_path, module_hash.as_str())).exists() {
|
||||
// download module if it does not exist
|
||||
download_module(instance, store_path.as_str(), module_url.as_str(), module_hash.as_str(), module_name, module_selector.as_str())?;
|
||||
download_module(
|
||||
instance,
|
||||
store_path.as_str(),
|
||||
module_url.as_str(),
|
||||
module_hash.as_str(),
|
||||
module_name,
|
||||
module_selector.as_str(),
|
||||
)?;
|
||||
}
|
||||
|
||||
return Ok(format!("{}/modules/{}", store_path, module_hash.as_str()));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_module(instance: &mut Instance, module_name: &str, path: Option<String>) -> MizeResult<()> {
|
||||
|
||||
pub fn load_module(instance: &mut Mize, module_name: &str, path: Option<String>) -> MizeResult<()> {
|
||||
let module_path = if path.is_some() {
|
||||
format!("{}/lib/libmize_module_{}.so", path.unwrap(), module_name)
|
||||
|
||||
} else {
|
||||
format!("{}/lib/libmize_module_{}.so", fetch_module(instance, module_name)?, module_name)
|
||||
format!(
|
||||
"{}/lib/libmize_module_{}.so",
|
||||
fetch_module(instance, module_name)?,
|
||||
module_name
|
||||
)
|
||||
};
|
||||
|
||||
let lib = unsafe { libloading::Library::new(module_path)? };
|
||||
|
||||
let func: libloading::Symbol<unsafe extern "C" fn(&mut Box<dyn Module + Send + Sync>, Instance) -> ()> = unsafe { lib.get(format!("get_mize_module_{}", module_name).as_bytes())? };
|
||||
let func: libloading::Symbol<
|
||||
unsafe extern "C" fn(&mut Box<dyn Module + Send + Sync>, Mize) -> (),
|
||||
> = unsafe { lib.get(format!("get_mize_module_{}", module_name).as_bytes())? };
|
||||
|
||||
let mut module: Box<dyn Module + Send + Sync> = Box::new(EmptyModule {});
|
||||
|
||||
@@ -289,7 +343,6 @@ pub fn load_module(instance: &mut Instance, module_name: &str, path: Option<Stri
|
||||
}
|
||||
|
||||
pub fn config_from_cli_args(matches: &ArgMatches) -> MizeResult<ItemData> {
|
||||
|
||||
let mut config = ItemData::new();
|
||||
|
||||
if let Some(config_file_path) = matches.get_one::<String>("config-file") {
|
||||
@@ -305,9 +358,7 @@ pub fn config_from_cli_args(matches: &ArgMatches) -> MizeResult<ItemData> {
|
||||
return Ok(config);
|
||||
}
|
||||
|
||||
|
||||
pub fn config_from_file(file_path: String) -> MizeResult<ItemData> {
|
||||
|
||||
let toml_string = fs::read_to_string(&file_path)
|
||||
.mize_result_msg(format!("Could not read file {} as mize config", &file_path))?;
|
||||
|
||||
@@ -315,7 +366,3 @@ pub fn config_from_file(file_path: String) -> MizeResult<ItemData> {
|
||||
|
||||
return Ok(item_data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
use ciborium::Value as CborValue;
|
||||
use flume::{unbounded, Receiver, Sender};
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use tokio::net::{UnixListener as TokioUnixListener, UnixStream};
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt, Interest};
|
||||
use tokio::net::unix::{OwnedReadHalf, OwnedWriteHalf};
|
||||
use tokio::io::{Interest, AsyncReadExt, AsyncWriteExt};
|
||||
use flume::{Receiver, Sender, unbounded};
|
||||
use ciborium::Value as CborValue;
|
||||
use tracing::{info, warn, debug};
|
||||
use tokio::net::{UnixListener as TokioUnixListener, UnixStream};
|
||||
use tracing::{debug, info, warn};
|
||||
|
||||
use crate::error::{IntoMizeResult, MizeError, MizeResult};
|
||||
use crate::instance::connection::{ConnListener, Connection};
|
||||
use crate::instance::{self, Instance};
|
||||
use crate::error::{MizeError, MizeResult, IntoMizeResult};
|
||||
use crate::instance::{self, Mize};
|
||||
use crate::proto::{self, MizeMessage};
|
||||
|
||||
pub struct UnixListener {
|
||||
@@ -18,19 +18,30 @@ pub struct UnixListener {
|
||||
|
||||
impl UnixListener {
|
||||
pub fn new(store_path: PathBuf) -> MizeResult<UnixListener> {
|
||||
Ok(UnixListener { sock_path: store_path.join("sock").to_owned() })
|
||||
Ok(UnixListener {
|
||||
sock_path: store_path.join("sock").to_owned(),
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub fn connect(instance: &mut Mize, store_path: PathBuf) -> MizeResult<()> {
|
||||
let conn_id = instance.spawn_async_blocking(
|
||||
"unix_connection",
|
||||
connect_async(instance.clone(), store_path),
|
||||
)?;
|
||||
|
||||
pub fn connect(instance: &mut Instance, store_path: PathBuf) -> MizeResult<()> {
|
||||
let conn_id = instance.spawn_async_blocking("unix_connection", connect_async(instance.clone(), store_path) )?;
|
||||
|
||||
let ns_of_peer_str = instance.get(format!("inst/con_by_id/{}/peer/0/config/namespace", conn_id))?.value_string()?;
|
||||
let ns_of_peer_str = instance
|
||||
.get(format!(
|
||||
"inst/con_by_id/{}/peer/0/config/namespace",
|
||||
conn_id
|
||||
))?
|
||||
.value_string()?;
|
||||
let ns_of_peer = instance.namespace_from_string(ns_of_peer_str)?;
|
||||
|
||||
info!("connect_async ... ns_of_peer: {}", ns_of_peer.clone().as_string());
|
||||
info!(
|
||||
"connect_async ... ns_of_peer: {}",
|
||||
ns_of_peer.clone().as_string()
|
||||
);
|
||||
|
||||
instance.connection_set_namespace(conn_id, ns_of_peer.clone());
|
||||
instance.set_namespace(ns_of_peer);
|
||||
@@ -38,8 +49,7 @@ pub fn connect(instance: &mut Instance, store_path: PathBuf) -> MizeResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
async fn connect_async(mut instance: Instance, store_path: PathBuf) -> MizeResult<u64> {
|
||||
async fn connect_async(mut instance: Mize, store_path: PathBuf) -> MizeResult<u64> {
|
||||
let mut stream = UnixStream::connect(store_path.join("sock")).await?;
|
||||
let (unix_read, unix_write) = stream.into_split();
|
||||
|
||||
@@ -47,7 +57,6 @@ async fn connect_async(mut instance: Instance, store_path: PathBuf) -> MizeResul
|
||||
|
||||
let conn_id = instance.new_connection(send_tx)?;
|
||||
|
||||
|
||||
let cloned_instance = instance.clone();
|
||||
instance.spawn("incomming", move || {
|
||||
let result = unix_incomming(unix_read, cloned_instance, conn_id);
|
||||
@@ -58,7 +67,6 @@ async fn connect_async(mut instance: Instance, store_path: PathBuf) -> MizeResul
|
||||
Ok(())
|
||||
});
|
||||
|
||||
|
||||
let outgoing_cloned_instance = instance.clone();
|
||||
instance.spawn("outgoing", move || {
|
||||
let result = unix_outgoing(unix_write, send_rx, outgoing_cloned_instance, conn_id);
|
||||
@@ -72,31 +80,32 @@ async fn connect_async(mut instance: Instance, store_path: PathBuf) -> MizeResul
|
||||
return Ok(conn_id);
|
||||
}
|
||||
|
||||
|
||||
impl ConnListener for UnixListener {
|
||||
fn listen(self, mut instance: Instance) -> MizeResult<()> {
|
||||
fn listen(self, mut instance: Mize) -> MizeResult<()> {
|
||||
instance.spawn_async("unix listen async", unix_listen(self, instance.clone()));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async fn unix_listen(listener: UnixListener, mut instance: Instance) -> MizeResult<()> {
|
||||
async fn unix_listen(listener: UnixListener, mut instance: Mize) -> MizeResult<()> {
|
||||
// remove the file at sock_path if it already exists
|
||||
fs::remove_file(&listener.sock_path);
|
||||
|
||||
let listener = TokioUnixListener::bind(&listener.sock_path)
|
||||
.mize_result_msg(format!("Could not bind to unix socket at '{}'", listener.sock_path.display()))?;
|
||||
let listener = TokioUnixListener::bind(&listener.sock_path).mize_result_msg(format!(
|
||||
"Could not bind to unix socket at '{}'",
|
||||
listener.sock_path.display()
|
||||
))?;
|
||||
|
||||
loop {
|
||||
let (mut unix_sock, addr) = listener.accept().await
|
||||
let (mut unix_sock, addr) = listener
|
||||
.accept()
|
||||
.await
|
||||
.mize_result_msg("Error while accepting Unix sock connection")?;
|
||||
info!("new connection");
|
||||
|
||||
let (send_tx, send_rx) = unbounded::<MizeMessage>();
|
||||
let (unix_read, unix_write) = unix_sock.into_split();
|
||||
|
||||
|
||||
let conn_id = instance.new_connection(send_tx)?;
|
||||
let cloned_instance = instance.clone();
|
||||
instance.spawn("incomming", move || {
|
||||
@@ -120,21 +129,35 @@ async fn unix_listen(listener: UnixListener, mut instance: Instance) -> MizeResu
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn unix_outgoing(mut unix_write: OwnedWriteHalf, send_rx: Receiver<MizeMessage>, mut instance: Instance, conn_id: u64) -> MizeResult<()> {
|
||||
fn unix_outgoing(
|
||||
mut unix_write: OwnedWriteHalf,
|
||||
send_rx: Receiver<MizeMessage>,
|
||||
mut instance: Mize,
|
||||
conn_id: u64,
|
||||
) -> MizeResult<()> {
|
||||
for msg in send_rx {
|
||||
debug!("unix outgoing got msg: {}", msg);
|
||||
let adapter = MyCiboriumWriter { inner: &mut unix_write, instance: &mut instance };
|
||||
let adapter = MyCiboriumWriter {
|
||||
inner: &mut unix_write,
|
||||
instance: &mut instance,
|
||||
};
|
||||
let value = msg.value();
|
||||
ciborium::into_writer(&value, adapter)?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn unix_incomming(mut unix_read: OwnedReadHalf, mut instance: Instance, conn_id: u64) -> MizeResult<()> {
|
||||
fn unix_incomming(
|
||||
mut unix_read: OwnedReadHalf,
|
||||
mut instance: Mize,
|
||||
conn_id: u64,
|
||||
) -> MizeResult<()> {
|
||||
loop {
|
||||
//println!("unix incoming loop...");
|
||||
let adapter = MyCiboriumReader { inner: &mut unix_read, instance: &mut instance };
|
||||
let adapter = MyCiboriumReader {
|
||||
inner: &mut unix_read,
|
||||
instance: &mut instance,
|
||||
};
|
||||
let value: CborValue = ciborium::from_reader(adapter)?;
|
||||
if let CborValue::Integer(_) = value {
|
||||
break;
|
||||
@@ -146,10 +169,9 @@ fn unix_incomming(mut unix_read: OwnedReadHalf, mut instance: Instance, conn_id:
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
struct MyCiboriumWriter<'a> {
|
||||
inner: &'a mut OwnedWriteHalf,
|
||||
instance: &'a mut Instance,
|
||||
instance: &'a mut Mize,
|
||||
}
|
||||
|
||||
impl<'a> ciborium_io::Write for MyCiboriumWriter<'a> {
|
||||
@@ -172,7 +194,7 @@ impl<'a> ciborium_io::Write for MyCiboriumWriter<'a> {
|
||||
|
||||
struct MyCiboriumReader<'a> {
|
||||
inner: &'a mut OwnedReadHalf,
|
||||
instance: &'a mut Instance,
|
||||
instance: &'a mut Mize,
|
||||
}
|
||||
|
||||
async fn test(test: &mut OwnedReadHalf, buf: &mut [u8]) {
|
||||
@@ -209,4 +231,3 @@ impl<'a> ciborium_io::Read for MyCiboriumReader<'a> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user