some more restorations
This commit is contained in:
@@ -19,6 +19,7 @@ packages/
|
||||
|
||||
## Important
|
||||
- usage of any git commands is strictly forbidden!
|
||||
- in case it takes too long finding smth or figuring smth out. stop and ask the user. (goal is not to do stuff as autonomous as possible)
|
||||
|
||||
## Key Components
|
||||
|
||||
|
||||
9025
Cargo.lock
generated
9025
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
97
Cargo.toml
97
Cargo.toml
@@ -1,29 +1,9 @@
|
||||
[package]
|
||||
name = "mize"
|
||||
version = "0.0.1"
|
||||
edition = "2021"
|
||||
license = "GPL-3.0"
|
||||
description = 'A strongly typed "filesystem" for the age of connectivity.'
|
||||
repository = "https://git.ppc.social/ppc/mize"
|
||||
|
||||
[lib]
|
||||
name = "mize"
|
||||
path = "src/lib.rs"
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[features]
|
||||
default = [ "target-os" ]
|
||||
target-os = [ "clap", "home", "nix", "sysinfo", "ciborium/default", "tracing-subscriber", "async", "tracing-subscriber/env-filter", "libloading", "ciborium-io", "tracing-core", "tar", "flate2", "http_req", "tokio/net", "tokio", "tokio/rt-multi-thread", "tokio/io-util" ]
|
||||
target-js = [ "wasm-bindgen", "console_error_panic_hook", "web-sys", "web-sys/Worker", "web-sys/Window", "web-sys/Request", "web-sys/RequestInit", "web-sys/RequestMode", "web-sys/Response", "web-sys/WorkerOptions", "web-sys/WorkerType", "serde-wasm-bindgen", "wasm-bindgen-futures", "wee_alloc", "ciborium/default" ]
|
||||
async = [ "tokio", ]
|
||||
|
||||
[workspace]
|
||||
members = [
|
||||
"marts",
|
||||
"macros",
|
||||
"apps/os",
|
||||
"apps/obsidian-plugin",
|
||||
"marts/spacetime",
|
||||
]
|
||||
default-members = [
|
||||
"apps/obsidian-plugin",
|
||||
@@ -31,78 +11,5 @@ default-members = [
|
||||
]
|
||||
resolver = "2"
|
||||
|
||||
[package.metadata.wasm-pack.profile.dev]
|
||||
wasm-opt = false # for debug build times
|
||||
|
||||
|
||||
[dependencies]
|
||||
# core dependencies
|
||||
colored = "2.0.0"
|
||||
uuid = "1.3.0"
|
||||
ciborium = { version = "0.2.2", default-features = false }
|
||||
serde = "1.0.203"
|
||||
interner = { git = "https://github.com/c2vi/interner" }
|
||||
tracing = "0.1.40"
|
||||
serde_json = { version = "1.0.117", optional = false }
|
||||
toml = { version = "0.8.13", features = ["parse"], optional = false }
|
||||
dyn-clone = "1.0.17"
|
||||
sha2 = "0.10.8"
|
||||
flume = { version = "0.11.1", default-features = false, features = [ "async" ] }
|
||||
mize_macros = { path = "./macros" }
|
||||
async-trait = "0.1.89"
|
||||
|
||||
# wasm dependencies
|
||||
wasm-bindgen = { version = "0.2.84", optional = true }
|
||||
console_error_panic_hook = { version = "0.1.7", optional = true }
|
||||
web-sys = { version = "0.3.70", optional = true }
|
||||
serde-wasm-bindgen = { version = "0.6.5", optional = true }
|
||||
wasm-bindgen-futures = { version = "0.4.49", optional = true }
|
||||
wee_alloc = { version = "0.4.5", optional = true }
|
||||
|
||||
# os dependencies
|
||||
clap = { version = "4.4.11", features = ["cargo"], optional = true }
|
||||
home = { version = "0.5.9", optional = true }
|
||||
daemonize = { version = "0.5.0", optional = true }
|
||||
nix = { version = "0.27.1", features = ["signal"], optional = true }
|
||||
sysinfo = { version = "0.30.12", optional = true }
|
||||
tracing-subscriber = { version = "0.3.18", optional = true }
|
||||
tokio = { version = "1.46.1", features = ["sync", "rt" ], optional = true, default-features = false }
|
||||
libloading = { version = "0.8.5", optional = true }
|
||||
ciborium-io = { version = "0.2.2", optional = true }
|
||||
tracing-core = { version = "0.1.32", optional = true }
|
||||
tar = { version = "0.4.42", optional = true }
|
||||
flate2 = { version = "1.0.33", optional = true }
|
||||
http_req = { version = "0.12.0", default-features = false, features = [ "rust-tls" ], optional = true }
|
||||
#http_req = { git = "https://github.com/c2vi/http_req", optional = true, default-features = false, features = [ "native-tls" ] }
|
||||
|
||||
# bare dependencies
|
||||
|
||||
# unused dependencies
|
||||
axum = { version = "0.6.1", features = ["ws", "headers"], optional = true }
|
||||
axum-extra = { version = "0.4.2", features = ["spa"], optional = true }
|
||||
axum-macros = { version = "0.3.0", optional = true }
|
||||
#tokio-core = "0.1.18"
|
||||
#tokio-io = "0.1.13"
|
||||
|
||||
#tokio-stream = { version = "0.1.9", optional = true }
|
||||
#derive_more = "0.99.17"
|
||||
#futures-util = "0.3.24"
|
||||
#itertools = "0.10.5"
|
||||
#lazy_static = "1.4.0"
|
||||
#rmp-serde = "1.1.1"
|
||||
#rmpv = { version = "1.0.0", features = ["serde", "with-serde"] }
|
||||
#toml = "0.5.10"
|
||||
#tower-http = "0.3.5"
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
wasm-bindgen-test = { version = "0.3.34" }
|
||||
|
||||
[profile.release]
|
||||
# Tell `rustc` to optimize for small code size.
|
||||
opt-level = "s"
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
# to make uuid be able to use browser apis for generating random numbers
|
||||
# needs to be the same version as uuid uses
|
||||
getrandom = { version = "0.4.3", features = ["wasm_js"] }
|
||||
[workspace.dependencies]
|
||||
mize = { path = "core" }
|
||||
|
||||
@@ -4,5 +4,4 @@ version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
mize = { path = "../.." }
|
||||
marts = { path = "../../marts" }
|
||||
mize = { workspace = true }
|
||||
|
||||
@@ -4,8 +4,7 @@ version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
mize = { path = "../../" }
|
||||
marts = { path = "../../marts" }
|
||||
mize = { workspace = true }
|
||||
clap = { version = "4.5.59", features = ["string"] }
|
||||
tracing = "0.1.44"
|
||||
|
||||
|
||||
@@ -56,3 +56,4 @@ tracing-core = { version = "0.1.32", optional = true }
|
||||
tar = { version = "0.4.42", optional = true }
|
||||
flate2 = { version = "1.0.33", optional = true }
|
||||
http_req = { version = "0.12.0", default-features = false, features = [ "rust-tls" ], optional = true }
|
||||
cmd_lib = { version = "2.0.1", optional = true }
|
||||
|
||||
0
core/src/c_api.rs
Normal file
0
core/src/c_api.rs
Normal file
367
core/src/error.rs
Normal file
367
core/src/error.rs
Normal file
@@ -0,0 +1,367 @@
|
||||
use colored::Colorize;
|
||||
#[cfg(feature = "target-js")]
|
||||
use wasm_bindgen::JsValue;
|
||||
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::io;
|
||||
use std::string::FromUtf8Error;
|
||||
use tracing::{debug, error, info, trace, warn};
|
||||
|
||||
//use crate::proto::MizeMessage;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! mize_err {
|
||||
($($arg:tt)*) => { MizeError::new().msg(format!( $($arg)*)) };
|
||||
}
|
||||
|
||||
pub type MizeResult<T> = Result<T, MizeError>;
|
||||
|
||||
pub trait MizeResultTrait<T> {
|
||||
fn critical(self) -> T;
|
||||
fn as_std(self) -> Result<T, MizeErrorWhichImplementsError>;
|
||||
}
|
||||
|
||||
pub trait IntoMizeResult<T, S> {
|
||||
fn mres(self) -> MizeResult<T>;
|
||||
fn mres_msg(self, msg: S) -> MizeResult<T>
|
||||
where
|
||||
S: std::fmt::Display;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MizeError {
|
||||
pub category: Vec<String>,
|
||||
pub code: u32,
|
||||
pub messages: Vec<String>,
|
||||
//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 {
|
||||
file: String,
|
||||
line: u32,
|
||||
column: u32,
|
||||
}
|
||||
|
||||
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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
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 }
|
||||
}
|
||||
}
|
||||
|
||||
impl MizeError {
|
||||
#[track_caller]
|
||||
pub fn code(code: u32) -> MizeError {
|
||||
let caller_location = std::panic::Location::caller();
|
||||
|
||||
get_error_by_code(code, caller_location)
|
||||
}
|
||||
|
||||
pub fn set_code(mut self, code: u32) -> MizeError {
|
||||
self.code = code;
|
||||
return self;
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
pub fn new() -> MizeError {
|
||||
let caller_location = std::panic::Location::caller();
|
||||
|
||||
return MizeError {
|
||||
category: Vec::new(),
|
||||
code: 0,
|
||||
messages: Vec::new(),
|
||||
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,
|
||||
{
|
||||
self.messages.push(format!("{}", msg));
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn category<T>(mut self, category: T) -> MizeError
|
||||
where
|
||||
T: Into<String>,
|
||||
{
|
||||
self.category.push(category.into());
|
||||
return self;
|
||||
}
|
||||
|
||||
fn send(self) -> MizeError {
|
||||
self
|
||||
}
|
||||
|
||||
fn add_to_err_item(self) -> MizeError {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn log(self) -> MizeError {
|
||||
println!("[ {} ] MizeError encountered!", "ERROR".red());
|
||||
|
||||
if let Some(ref location) = self.code_location {
|
||||
println!("[ {} ] {}", "LOCATION".yellow(), location);
|
||||
};
|
||||
|
||||
println!("[ {} ] {}", "BACKTRACE".yellow(), self.backtrace);
|
||||
|
||||
for msg in &self.messages {
|
||||
println!("[ {} ] {}", "MSG".yellow(), msg);
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn handle(self) -> MizeError {
|
||||
return self.send().add_to_err_item().log();
|
||||
}
|
||||
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
for msg in msg_iter {
|
||||
error!("{} {}", "MSG".red(), msg)
|
||||
}
|
||||
if let Some(location) = self.code_location {
|
||||
error!("{} {}", "LOCATION".red(), location)
|
||||
}
|
||||
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>
|
||||
where E: std::fmt::Display
|
||||
;
|
||||
fn handle(self) -> Result<T, MizeError>;
|
||||
|
||||
fn is_critical(self) -> T;
|
||||
}
|
||||
|
||||
impl<T> MizeResultExtension<T> for Result<T, MizeError> {
|
||||
fn msg<E>(mut self, msg: E) -> Result<T, MizeError>
|
||||
where E: std::fmt::Display
|
||||
{
|
||||
match self {
|
||||
Err(ref mut e) => {
|
||||
e.msg.push(format!("{}", msg));
|
||||
return self;
|
||||
},
|
||||
Ok(something) => Ok(something),
|
||||
}
|
||||
}
|
||||
fn handle(self) -> Result<T, MizeError> {
|
||||
match self {
|
||||
Err(e) => {
|
||||
Err(e.send().add_to_err_item().write_to_stderr())
|
||||
},
|
||||
Ok(something) => Ok(something)
|
||||
}
|
||||
}
|
||||
fn is_critical(self) -> T {
|
||||
self.expect("Aborting because of a critical Error")
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
impl From<FromUtf8Error> for MizeError {
|
||||
#[track_caller]
|
||||
fn from(utf_err: FromUtf8Error) -> MizeError{
|
||||
let caller_location = std::panic::Location::caller();
|
||||
|
||||
let mut err = MizeError::code(109).msg(format!("From std::string::FromUtf8Error: {}", utf_err));
|
||||
err.code_location = Some(caller_location.into());
|
||||
return err;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
impl<T: Display> From<T> for MizeError {
|
||||
#[track_caller]
|
||||
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
|
||||
))
|
||||
.location(caller_location.into())
|
||||
}
|
||||
}
|
||||
|
||||
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 }),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E, S> IntoMizeResult<T, S> for Result<T, E>
|
||||
where
|
||||
E: std::fmt::Display,
|
||||
{
|
||||
#[track_caller]
|
||||
fn mres(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
|
||||
))),
|
||||
}
|
||||
}
|
||||
#[track_caller]
|
||||
fn mres_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()
|
||||
.category("misc")
|
||||
.msg(format!("{}", msg))
|
||||
.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(),
|
||||
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"),
|
||||
_ => err,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MizeErrorWhichImplementsError {
|
||||
inner: MizeError,
|
||||
}
|
||||
|
||||
impl Display for MizeErrorWhichImplementsError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "MizeError envountered!");
|
||||
|
||||
if let Some(ref location) = self.inner.code_location {
|
||||
write!(f, "[ {} ] {}", "LOCATION".yellow(), location);
|
||||
};
|
||||
|
||||
write!(f, "[ {} ] {}", "BACKTRACE".yellow(), self.inner.backtrace);
|
||||
|
||||
for msg in &self.inner.messages {
|
||||
write!(f, "[ {} ] {}", "MSG".yellow(), msg);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MizeError> for MizeErrorWhichImplementsError {
|
||||
fn from(value: MizeError) -> Self {
|
||||
MizeErrorWhichImplementsError { inner: value }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for MizeErrorWhichImplementsError {}
|
||||
|
||||
// i hate rust sometimes.
|
||||
// why can't i impl IntoMizeResult for any type. and the extra concrete impl of it for JsValue overrides the more generic one.
|
||||
#[cfg(feature = "target-js")]
|
||||
pub trait IntoMizeResultJsValue<T> {
|
||||
fn mres(self) -> MizeResult<T>;
|
||||
}
|
||||
|
||||
#[cfg(feature = "target-js")]
|
||||
impl<T> IntoMizeResultJsValue<T> for Result<T, JsValue> {
|
||||
fn mres(self) -> MizeResult<T> {
|
||||
match self {
|
||||
Ok(value) => Ok(value),
|
||||
Err(err) => Err(mize_err!("From JsValue: {:?}", err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
172
core/src/lib.rs
Normal file
172
core/src/lib.rs
Normal file
@@ -0,0 +1,172 @@
|
||||
#![allow(warnings)]
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::fmt::format;
|
||||
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! out {
|
||||
($($arg:tt)*) => {
|
||||
// format_args! handles string interpolation safely at compile time
|
||||
if let Err(e) = $crate::write_to_mize_stdout(format_args!($($arg)*)) {
|
||||
// Choose your error handling behavior here (panic, print to stderr, or ignore)
|
||||
eprintln!("out! macro failed to write!!");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn write_to_mize_stdout(args: std::fmt::Arguments) -> MizeResult<()> {
|
||||
println!("{}", format_args!(args));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub mod prelude {
|
||||
pub use super::*;
|
||||
pub use instance::Mize;
|
||||
pub use error::MizeError;
|
||||
pub use crate::mize_err;
|
||||
pub use error::MizeResult;
|
||||
pub use item::{Item, ItemData, IntoItemData};
|
||||
pub use config::*;
|
||||
}
|
||||
pub use flume;
|
||||
|
||||
|
||||
|
||||
// the core part has the code that can run on any platform
|
||||
pub mod config;
|
||||
pub mod error;
|
||||
pub mod id;
|
||||
pub mod instance;
|
||||
pub mod item;
|
||||
pub mod memstore;
|
||||
pub mod proto;
|
||||
pub mod types;
|
||||
pub mod c_api;
|
||||
|
||||
pub use async_trait::async_trait;
|
||||
pub use ciborium;
|
||||
pub use error::MizeError;
|
||||
pub use error::MizeResult;
|
||||
pub use instance::Mize;
|
||||
pub use instance::{
|
||||
MizePart,
|
||||
};
|
||||
pub use mize_macros::*;
|
||||
use std::path::PathBuf;
|
||||
|
||||
// platform specific stuff
|
||||
pub mod platform {
|
||||
use crate::{Mize, MizeResult};
|
||||
|
||||
#[cfg(feature = "target-js")]
|
||||
pub mod js;
|
||||
|
||||
#[cfg(feature = "target-os")]
|
||||
pub mod os;
|
||||
|
||||
pub fn init(mize: &mut Mize) -> MizeResult<()> {
|
||||
#[cfg(feature = "target-os")] {
|
||||
os::os_instance_init(mize)?;
|
||||
}
|
||||
|
||||
#[cfg(feature = "target-js")] {
|
||||
js::wasm_instance_init(mize)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn load_part(mize: &mut Mize, part_name: &str, path: Option<String>) -> MizeResult<()> {
|
||||
#[cfg(feature = "target-os")] {
|
||||
os::load_part(mize, part_name, path)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
pub fn fetch_part(mize: &mut Mize, part_name: &str) -> MizeResult<String> {
|
||||
#[cfg(feature = "target-os")] {
|
||||
os::fetch_part(mize, part_name)?;
|
||||
}
|
||||
Ok("alsdkjf".to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////// include_native! macro /////////////////////////////////////
|
||||
// A macro to register methods of a foreign type (like clap::Command) with mize.
|
||||
// This generates bindings for the type to be stored in the native_values registry.
|
||||
|
||||
// Usage 1: New simplified syntax (string name, type path, list of method names)
|
||||
// ```ignore
|
||||
// include_native!("Command", clap::Command, [new, arg, subcommand]);
|
||||
// ```
|
||||
//
|
||||
// This expands to:
|
||||
// ```ignore
|
||||
// opt("Command")
|
||||
// .method("new", |args| {
|
||||
// let this = get_config("Command")?.native_mut::<clap::Command>()?;
|
||||
// let result = this.new();
|
||||
// Ok(from_native(result))
|
||||
// })
|
||||
// .method("arg", |args| {
|
||||
// let this = get_config("Command")?.native_mut::<clap::Command>()?;
|
||||
// let result = this.arg();
|
||||
// Ok(from_native(result))
|
||||
// })
|
||||
// .method("subcommand", |args| {
|
||||
// let this = get_config("Command")?.native_mut::<clap::Command>()?;
|
||||
// let result = this.subcommand();
|
||||
// Ok(from_native(result))
|
||||
// });
|
||||
// ```
|
||||
//
|
||||
// Usage 2: Traditional syntax (type path, method signatures in braces)
|
||||
// ```ignore
|
||||
// include_native!(clap::Command, {
|
||||
// fn arg(&mut self, arg: clap::Arg) -> &mut clap::Command;
|
||||
// fn subcommand(&mut self, cmd: clap::Command) -> &mut clap::Command;
|
||||
// });
|
||||
// ```
|
||||
//
|
||||
// This expands to:
|
||||
// ```ignore
|
||||
// opt("clap::Command")
|
||||
// .method("arg", |args| {
|
||||
// let arg = args.arr_nth(0)?.native::<clap::Arg>()?;
|
||||
// let this = get_config("clap::Command")?.native_mut::<clap::Command>()?;
|
||||
// let result = this.arg(arg);
|
||||
// Ok(from_native(result))
|
||||
// })
|
||||
// .method("subcommand", |args| {
|
||||
// let cmd = args.arr_nth(0)?.native::<clap::Command>()?;
|
||||
// let this = get_config("clap::Command")?.native_mut::<clap::Command>()?;
|
||||
// let result = this.subcommand(cmd);
|
||||
// Ok(from_native(result))
|
||||
// });
|
||||
// ```
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! include_native {
|
||||
// New simplified syntax: ("name", type_path, [method1, method2, ...])
|
||||
($name:literal, $type_path:ty, [$($method:ident),* $(,)?]) => {
|
||||
$crate::config::opt($name)
|
||||
$(
|
||||
.method(stringify!($method), |args| {
|
||||
let this = $crate::c_api::get_global_mize()?
|
||||
.get_config($name)?
|
||||
.native_mut::<$type_path>()?;
|
||||
let result = this.$method();
|
||||
Ok($crate::item::ItemData::from_native(result)?)
|
||||
})
|
||||
)*
|
||||
};
|
||||
|
||||
// Traditional syntax: (type_path, { fn method1(...) -> ...; fn method2(...) -> ...; })
|
||||
($type_path:ty, { $($methods:tt)* }) => {
|
||||
$crate::config::opt(stringify!($type_path))
|
||||
// TODO: parse method signatures and generate appropriate bindings
|
||||
// For now, this is a placeholder for the traditional syntax
|
||||
};
|
||||
}
|
||||
152
core/src/memstore.rs
Normal file
152
core/src/memstore.rs
Normal file
@@ -0,0 +1,152 @@
|
||||
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 tracing::{instrument, trace};
|
||||
|
||||
use crate::error::{IntoMizeResult, MizeError, MizeResult};
|
||||
use crate::id::MizeId;
|
||||
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)]
|
||||
pub struct MemStore {
|
||||
inner: Arc<Mutex<MemStoreInner>>,
|
||||
}
|
||||
|
||||
pub type MemStoreId = u64;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct MemStoreInner {
|
||||
map: HashMap<u64, ItemData>,
|
||||
next_id: u64,
|
||||
}
|
||||
|
||||
impl Store for MemStore {
|
||||
fn set(&self, id: MizeId, data: ItemData) -> MizeResult<()> {
|
||||
let mut inner = self.inner.lock()?;
|
||||
|
||||
if let Some(old_data) = inner.map.get(&id_to_u64(id.clone())?) {
|
||||
//if there is already data there, set at the correct path
|
||||
let mut old_data = old_data.to_owned();
|
||||
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(());
|
||||
}
|
||||
fn get_links(&self, item: Item) -> MizeResult<Vec<MizeId>> {
|
||||
let inner = self.inner.lock()?;
|
||||
|
||||
Ok(Vec::new())
|
||||
}
|
||||
fn get_backlinks(&self, item: Item) -> MizeResult<Vec<MizeId>> {
|
||||
let inner = self.inner.lock()?;
|
||||
|
||||
Ok(Vec::new())
|
||||
}
|
||||
fn new_id(&self) -> MizeResult<String> {
|
||||
let mut inner = self.inner.lock()?;
|
||||
|
||||
let id_string = format!("{}", inner.next_id);
|
||||
inner.next_id += 1;
|
||||
return Ok(id_string);
|
||||
}
|
||||
|
||||
#[instrument(name="fn.MemStore::get_value_raw" skip(self))]
|
||||
fn get_value_raw(&self, id: MizeId) -> MizeResult<Vec<u8>> {
|
||||
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 path = id.path();
|
||||
let mut id_iter = path.iter();
|
||||
id_iter.next();
|
||||
let id_without_first = id_iter.collect();
|
||||
|
||||
Ok(get_raw_from_cbor(&cbor_val.0, id_without_first)?.to_owned())
|
||||
}
|
||||
|
||||
fn get_value_data_full(&self, id: MizeId) -> MizeResult<ItemData> {
|
||||
let inner = self.inner.lock()?;
|
||||
|
||||
let data = match inner.map.get(&id_to_u64(id.clone())?) {
|
||||
Some(val) => val.to_owned(),
|
||||
None => ItemData::new(),
|
||||
};
|
||||
|
||||
let new_path = id.after_store_part();
|
||||
let ret_data = data.get_path(new_path)?;
|
||||
|
||||
return Ok(ret_data);
|
||||
}
|
||||
fn id_iter(&self) -> MizeResult<IdIter> {
|
||||
IdIter::new(Box::new(self.to_owned()))
|
||||
}
|
||||
|
||||
fn next_id(&self, prev_id_str: &str) -> MizeResult<Option<String>> {
|
||||
let inner = self.inner.lock()?;
|
||||
|
||||
let mut id = str_to_u64(prev_id_str)?;
|
||||
|
||||
loop {
|
||||
id += 1;
|
||||
|
||||
if id > inner.next_id {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
if inner.map.contains_key(&id) {
|
||||
println!("returning: {}", id);
|
||||
return Ok(Some(format!("{}", id)));
|
||||
} else {
|
||||
// try id +1
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn first_id(&self) -> MizeResult<String> {
|
||||
Ok("0".to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
impl MemStore {
|
||||
pub fn new() -> MemStore {
|
||||
let inner = MemStoreInner {
|
||||
map: HashMap::new(),
|
||||
next_id: 0,
|
||||
};
|
||||
return MemStore {
|
||||
inner: Arc::new(Mutex::new(inner)),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn id_to_u64(id: MizeId) -> MizeResult<u64> {
|
||||
str_to_u64(id.store_part())
|
||||
}
|
||||
|
||||
fn str_to_u64(id_str: &str) -> MizeResult<u64> {
|
||||
id_str.parse().mres_msg(format!(
|
||||
"Could not parse the store_part of mizeid {} into a u64 for the MemStore",
|
||||
id_str
|
||||
))
|
||||
}
|
||||
@@ -303,7 +303,7 @@ fn get_part_path(mize: &mut Mize, part_name: &str, _path: Option<String>) -> Miz
|
||||
}
|
||||
|
||||
pub fn load_part(mize: &mut Mize, part_name: &str, path: Option<String>) -> MizeResult<()> {
|
||||
let part_path = get_part_path(mize, part_name, path)?;
|
||||
let part_path = get_part_path(mize, part_name, path)?;
|
||||
|
||||
let lib = unsafe { libloading::Library::new(part_path)? };
|
||||
|
||||
|
||||
434
core/src/proto/mod.rs
Normal file
434
core/src/proto/mod.rs
Normal file
@@ -0,0 +1,434 @@
|
||||
use core::fmt;
|
||||
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, Mize},
|
||||
item::{IntoItemData, ItemData},
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct MizeMessage {
|
||||
value: CborValue,
|
||||
pub conn_id: u64,
|
||||
}
|
||||
|
||||
impl MizeMessage {
|
||||
pub fn bytes(&self) -> Vec<u8> {
|
||||
let mut writer = Vec::new();
|
||||
ciborium::into_writer(&self.value, &mut writer).unwrap();
|
||||
writer
|
||||
}
|
||||
pub fn into_writer(&self, writer: &mut impl io::Write) -> MizeResult<()> {
|
||||
Ok(ciborium::into_writer(&self.value, writer)?)
|
||||
}
|
||||
}
|
||||
|
||||
// msg items
|
||||
static MSG_CMD: u16 = 1;
|
||||
static MSG_ID: u16 = 2;
|
||||
static MSG_DATA: u16 = 3;
|
||||
|
||||
// cmds
|
||||
static CMD_GET: u16 = 1;
|
||||
static CMD_UPDATE: u16 = 2;
|
||||
static CMD_GIVE: u16 = 3;
|
||||
static CMD_CREATE: u16 = 4;
|
||||
static CMD_CREATE_REPLY: u16 = 5;
|
||||
static CMD_UPDATE_REQUEST: u16 = 6;
|
||||
static CMD_GET_SUB: u16 = 7;
|
||||
static CMD_SUB: u16 = 8;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum MessageCmd {
|
||||
Get,
|
||||
Update,
|
||||
Give,
|
||||
Create,
|
||||
CreateReply,
|
||||
UpdateRequest,
|
||||
GetSub,
|
||||
Sub,
|
||||
Custom(ItemData),
|
||||
}
|
||||
|
||||
impl MizeMessage {
|
||||
pub fn new(value: CborValue, conn_id: u64) -> MizeMessage {
|
||||
MizeMessage { value, conn_id }
|
||||
}
|
||||
|
||||
pub fn new_custom<T: IntoItemData, U: IntoItemData>(
|
||||
custom_cmd: T,
|
||||
value: U,
|
||||
conn_id: u64,
|
||||
) -> MizeMessage {
|
||||
let value = value.into_item_data();
|
||||
let custom_cmd = custom_cmd.into_item_data();
|
||||
|
||||
let cmd = (CborValue::Integer(MSG_CMD.into()), custom_cmd.0);
|
||||
let data = (CborValue::Integer(MSG_DATA.into()), value.cbor().to_owned());
|
||||
let msg_value = CborValue::Map(vec![cmd, data]);
|
||||
|
||||
MizeMessage {
|
||||
value: msg_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 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]);
|
||||
|
||||
MizeMessage::new(value, conn_id)
|
||||
}
|
||||
|
||||
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 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]);
|
||||
|
||||
MizeMessage::new(value, conn_id)
|
||||
}
|
||||
|
||||
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 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]);
|
||||
|
||||
MizeMessage::new(value, conn_id)
|
||||
}
|
||||
|
||||
pub fn new_create(conn_id: u64) -> MizeMessage {
|
||||
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 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]);
|
||||
|
||||
MizeMessage::new(value, conn_id)
|
||||
}
|
||||
|
||||
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 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]);
|
||||
|
||||
MizeMessage::new(value, conn_id)
|
||||
}
|
||||
|
||||
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 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]);
|
||||
|
||||
MizeMessage::new(value, conn_id)
|
||||
}
|
||||
|
||||
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 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]);
|
||||
|
||||
MizeMessage::new(value, conn_id)
|
||||
}
|
||||
|
||||
pub fn value(self) -> CborValue {
|
||||
self.value
|
||||
}
|
||||
|
||||
pub fn cmd(&self) -> MizeResult<MessageCmd> {
|
||||
// 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"));
|
||||
}
|
||||
};
|
||||
|
||||
//check if in this map there is a cmd, otherwise return err
|
||||
let val_of_c = {
|
||||
let mut tmp_val = 0;
|
||||
for (key, val) in msg_as_map {
|
||||
if let CborValue::Integer(key_int) = key {
|
||||
// number one indicates the cmd field
|
||||
let one: Integer = 1.into();
|
||||
if key_int == &one {
|
||||
if let CborValue::Integer(val_int) = val {
|
||||
tmp_val = val_int.to_owned().into();
|
||||
} else {
|
||||
return Ok(MessageCmd::Custom(ItemData(val.to_owned())));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if tmp_val == 0 {
|
||||
return Err(MizeError::new().msg("error getting the cmd value form a msg"));
|
||||
}
|
||||
tmp_val
|
||||
};
|
||||
|
||||
// match on value of cmd
|
||||
let cmd = match val_of_c {
|
||||
1 => MessageCmd::Get,
|
||||
2 => MessageCmd::Update,
|
||||
3 => MessageCmd::Give,
|
||||
4 => MessageCmd::Create,
|
||||
5 => MessageCmd::CreateReply,
|
||||
6 => MessageCmd::UpdateRequest,
|
||||
7 => MessageCmd::GetSub,
|
||||
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 = {
|
||||
let mut data = &CborValue::Null;
|
||||
for (key, val) in msg_as_map {
|
||||
if let CborValue::Integer(key_int) = key {
|
||||
// number 2 indicates the id field
|
||||
let two: Integer = 2.into();
|
||||
if key_int == &two {
|
||||
data = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
if data == &CborValue::Null {
|
||||
return Err(MizeError::new().msg("error getting the data value form a msg"));
|
||||
}
|
||||
match data {
|
||||
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()),
|
||||
_ => {
|
||||
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: &Mize) -> MizeResult<MizeId> {
|
||||
let id_str = self.id_str()?;
|
||||
return instance.new_id(id_str);
|
||||
}
|
||||
|
||||
pub fn data(&mut self) -> MizeResult<ItemData> {
|
||||
// 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 data = {
|
||||
let mut tmp_val = &CborValue::Null;
|
||||
let mut found = false;
|
||||
for (key, val) in msg_as_map {
|
||||
if let CborValue::Integer(key_int) = key {
|
||||
// number three indicates the data field
|
||||
let three: Integer = 3.into();
|
||||
if key_int == &three {
|
||||
tmp_val = val;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return Err(MizeError::new().msg("error getting the data value form a msg"));
|
||||
}
|
||||
tmp_val
|
||||
};
|
||||
|
||||
return Ok(data.to_owned().into_item_data());
|
||||
}
|
||||
}
|
||||
|
||||
// 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))
|
||||
.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!()
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
match self.to_owned().id_str() {
|
||||
Ok(id) => {
|
||||
let id_str = id.join("/");
|
||||
writeln!(f, "\tid: {:?}", id_str);
|
||||
}
|
||||
Err(e) => {
|
||||
writeln!(f, "\t msg has no id");
|
||||
//err = true;
|
||||
}
|
||||
}
|
||||
|
||||
match self.to_owned().data() {
|
||||
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)
|
||||
{
|
||||
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)
|
||||
.mres_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 value = self.to_owned().value();
|
||||
value
|
||||
.serialize(&mut serde_json::Serializer::pretty(display_writer))
|
||||
.map_err(|serde_err| std::fmt::Error)
|
||||
}
|
||||
}
|
||||
0
core/src/types/mod.rs
Normal file
0
core/src/types/mod.rs
Normal file
@@ -2,100 +2,8 @@ use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{Data, DeriveInput, Fields, parse_macro_input};
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn mize_part(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(item as DeriveInput);
|
||||
let struct_name = &input.ident;
|
||||
|
||||
// Parse name from attribute
|
||||
let part_name = if !attr.is_empty() {
|
||||
let lit: syn::LitStr = parse_macro_input!(attr);
|
||||
lit.value()
|
||||
} else {
|
||||
struct_name.to_string().to_lowercase()
|
||||
};
|
||||
|
||||
// Verify mize field exists
|
||||
let has_mize = match &input.data {
|
||||
Data::Struct(s) => match &s.fields {
|
||||
Fields::Named(f) => f
|
||||
.named
|
||||
.iter()
|
||||
.any(|field| field.ident.as_ref().map(|i| i == "mize").unwrap_or(false)),
|
||||
_ => false,
|
||||
},
|
||||
_ => false,
|
||||
};
|
||||
|
||||
if !has_mize {
|
||||
return syn::Error::new_spanned(struct_name, "Struct must have a 'mize: Mize' field")
|
||||
.to_compile_error()
|
||||
.into();
|
||||
}
|
||||
|
||||
let part_getter_fn_name_str = format!("make_mize_part_{}", part_name);
|
||||
let part_getter_fn_name = syn::Ident::new(&part_getter_fn_name_str, struct_name.span());
|
||||
|
||||
let expanded = quote! {
|
||||
#input
|
||||
|
||||
// impl the default new impl
|
||||
impl mize::MizePartGenerated for #struct_name {
|
||||
fn name_generated(&self) -> &'static str {
|
||||
#part_name
|
||||
}
|
||||
fn get_mize_generated(&mut self) -> &mut Mize {
|
||||
&mut self.mize
|
||||
}
|
||||
fn as_any_generated(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
fn as_any_mut_generated(&mut self) -> &mut dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
fn into_any_generated(self: Box<Self>) -> Box<dyn std::any::Any> {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl mize::MizePartCreateGenerated for #struct_name {
|
||||
fn create_generated(mize: Mize) -> Self {
|
||||
Self {
|
||||
mize,
|
||||
.. Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use mize::instance::MizePartCreateThisSucks;
|
||||
|
||||
impl MizePartCreateThisSucks for #struct_name {}
|
||||
|
||||
// the function to get the part from a .so file
|
||||
#[unsafe(no_mangle)]
|
||||
extern "C" fn #part_getter_fn_name(part: &mut Box<dyn MizePart + Send + Sync>, mut mize: Mize) {
|
||||
#struct_name::create_this_sucks(&mut mize);
|
||||
}
|
||||
|
||||
/*
|
||||
impl std::ops::Deref for mize::MizePartGuard<#struct_name> {
|
||||
type Target = #struct_name;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&*self.part.as_ref().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::DerefMut for mize::MizePartGuard<#struct_name> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut *self.part.as_mut().unwrap()
|
||||
}
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
TokenStream::from(expanded)
|
||||
}
|
||||
|
||||
//////////////////////////////////// data! macro ///////////////////////////////////////
|
||||
// A procedural macro to define data in Nix-style and expand to a `ciborium::Value` (CBOR).
|
||||
|
||||
Reference in New Issue
Block a user