instance init with config works + view ItemData func implemented
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -1067,6 +1067,7 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"nix",
|
"nix",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
"toml",
|
"toml",
|
||||||
"uuid",
|
"uuid",
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ path = "src/platform/os/main.rs"
|
|||||||
required-features = [ "os-target" ]
|
required-features = [ "os-target" ]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
os-target = [ "clap", "home", "env_logger", "daemonize", "nix", "toml" ]
|
os-target = [ "clap", "home", "env_logger", "daemonize", "nix", "toml", "serde_json" ]
|
||||||
wasm-target = [ "wasm-bindgen", "console_error_panic_hook", "wasm-bindgen-cli" ]
|
wasm-target = [ "wasm-bindgen", "console_error_panic_hook", "wasm-bindgen-cli" ]
|
||||||
|
|
||||||
|
|
||||||
@@ -43,6 +43,7 @@ env_logger = { version = "0.10.1", optional = true }
|
|||||||
daemonize = { version = "0.5.0", optional = true }
|
daemonize = { version = "0.5.0", optional = true }
|
||||||
nix = { version = "0.27.1", features = ["signal"], optional = true }
|
nix = { version = "0.27.1", features = ["signal"], optional = true }
|
||||||
toml = { version = "0.8.13", features = ["parse"], optional = true }
|
toml = { version = "0.8.13", features = ["parse"], optional = true }
|
||||||
|
serde_json = { version = "1.0.117", optional = true }
|
||||||
|
|
||||||
# bare dependencies
|
# bare dependencies
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use std::path::Path;
|
|||||||
use interner::shared::VecStringPool;
|
use interner::shared::VecStringPool;
|
||||||
|
|
||||||
use crate::error::{MizeError, MizeResult, IntoMizeResult, MizeResultTrait};
|
use crate::error::{MizeError, MizeResult, IntoMizeResult, MizeResultTrait};
|
||||||
|
use crate::instance;
|
||||||
use crate::instance::store::Store;
|
use crate::instance::store::Store;
|
||||||
use crate::instance::connection::Connection;
|
use crate::instance::connection::Connection;
|
||||||
use crate::id::{IntoMizeId, MizeId};
|
use crate::id::{IntoMizeId, MizeId};
|
||||||
@@ -45,17 +46,23 @@ pub enum RealmId {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
impl Instance<MemStore> {
|
impl Instance<MemStore> {
|
||||||
pub fn new() -> MizeResult<Instance<MemStore>> {
|
pub fn empty() -> Instance<MemStore> {
|
||||||
trace!("[ {} ] Instance::new()", "CALL".yellow());
|
|
||||||
|
|
||||||
let store = MemStore::new();
|
let store = MemStore::new();
|
||||||
let id_pool = VecStringPool::default();
|
let id_pool = VecStringPool::default();
|
||||||
let peers = Arc::new(Mutex::new(Vec::new()));
|
let peers = Arc::new(Mutex::new(Vec::new()));
|
||||||
let subs = Arc::new(Mutex::new(HashMap::new()));
|
let subs = Arc::new(Mutex::new(HashMap::new()));
|
||||||
let mut instance = Instance {store, peers, subs, id_pool };
|
let mut instance = Instance {store, peers, subs, id_pool };
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
pub fn new() -> MizeResult<Instance<MemStore>> {
|
||||||
|
trace!("[ {} ] Instance::new()", "CALL".yellow());
|
||||||
|
|
||||||
|
let mut instance = Instance::empty();
|
||||||
|
|
||||||
instance.init();
|
instance.init();
|
||||||
|
|
||||||
|
debug!("instance inited with conifg: {}", instance.get("0/config")?.as_data_full()?);
|
||||||
|
|
||||||
return Ok(instance);
|
return Ok(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,13 +79,16 @@ impl Instance<MemStore> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_config(config: ItemData) -> MizeResult<Instance<MemStore>> {
|
pub fn with_config(config: ItemData) -> MizeResult<Instance<MemStore>> {
|
||||||
let mut instance = Instance::new()?;
|
let mut instance = Instance::empty();
|
||||||
instance.set("0", config.clone());
|
instance.set("0", config.clone());
|
||||||
instance.init()?;
|
instance.init()?;
|
||||||
|
|
||||||
// set it again, so that the passed config data has presidence over anything the init would set
|
// set it again, so that the passed config data has presidence over anything the init would set
|
||||||
|
debug!("overwriting instance config again with the one passed to Instance::with_config()");
|
||||||
instance.set("0", config);
|
instance.set("0", config);
|
||||||
|
|
||||||
|
debug!("instance inited with conifg: {}", instance.get("0/config")?.as_data_full()?);
|
||||||
|
|
||||||
Ok(instance)
|
Ok(instance)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,5 +21,7 @@ pub trait Store {
|
|||||||
fn new_id(&self) -> MizeResult<String>;
|
fn new_id(&self) -> MizeResult<String>;
|
||||||
|
|
||||||
fn get_value_raw(&self, id: MizeId) -> MizeResult<Vec<u8>>;
|
fn get_value_raw(&self, id: MizeId) -> MizeResult<Vec<u8>>;
|
||||||
|
|
||||||
|
fn get_value_data_full(&self, id: MizeId) -> MizeResult<ItemData>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
351
src/core/item.rs
351
src/core/item.rs
@@ -1,8 +1,13 @@
|
|||||||
use log::{trace, debug, info, warn, error};
|
use log::{trace, debug, info, warn, error};
|
||||||
|
use serde::Serialize;
|
||||||
|
use core::fmt;
|
||||||
|
use std::{i128, string};
|
||||||
use std::{collections::HashMap, path::PathBuf, io::Cursor, fmt::Display};
|
use std::{collections::HashMap, path::PathBuf, io::Cursor, fmt::Display};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use colored::Colorize;
|
||||||
|
use std::io;
|
||||||
|
|
||||||
use crate::error::{MizeError, MizeResult, IntoMizeResult};
|
use crate::error::{MizeError, MizeResult, IntoMizeResult};
|
||||||
use crate::instance::Instance;
|
use crate::instance::Instance;
|
||||||
@@ -20,7 +25,8 @@ pub struct Item<'a, S: Store + Sized> {
|
|||||||
|
|
||||||
// without an Instance it is not an item, but only the "data of an item"
|
// 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
|
// and this type for now is just an alias to CborValue
|
||||||
pub type ItemData = CborValue;
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct ItemData ( pub CborValue );
|
||||||
|
|
||||||
impl<S: Store> Item<'_, S> {
|
impl<S: Store> Item<'_, S> {
|
||||||
pub fn id(&self) -> MizeId {
|
pub fn id(&self) -> MizeId {
|
||||||
@@ -31,6 +37,9 @@ impl<S: Store> Item<'_, S> {
|
|||||||
// this will call from the instance which gets the value from the store
|
// this will call from the instance which gets the value from the store
|
||||||
self.instance.store.get_value_raw(self.id())
|
self.instance.store.get_value_raw(self.id())
|
||||||
}
|
}
|
||||||
|
pub fn as_data_full(&self) -> MizeResult<ItemData> {
|
||||||
|
self.instance.store.get_value_data_full(self.id())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Store> Display for Item<'_, S> {
|
impl<S: Store> Display for Item<'_, S> {
|
||||||
@@ -46,233 +55,217 @@ impl<S: Store> Display for Item<'_, S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ItemData {
|
||||||
|
pub fn new() -> ItemData {
|
||||||
|
ItemData(CborValue::Null)
|
||||||
/*
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Item {
|
|
||||||
Cbor(ItemCbor),
|
|
||||||
Folder(ItemFolder),
|
|
||||||
Ref(ItemRef),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
pub fn merge(&mut self, other: ItemData) {
|
||||||
pub struct ItemCbor {
|
item_data_merge(self, other)
|
||||||
pub inner: CborValue,
|
|
||||||
pub id: MizeId,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
pub fn null() -> CborValue {
|
||||||
pub struct ItemFolder {
|
CborValue::Null
|
||||||
pub path: PathBuf,
|
|
||||||
pub id: MizeId,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
pub fn parse<T: Into<String>>(value: T) -> ItemData {
|
||||||
pub struct ItemRef {
|
let value_str = value.into();
|
||||||
pub store: Mutex<Rc<Itemstore>>,
|
if value_str == "false" {
|
||||||
pub id: MizeId,
|
return CborValue::Bool(false).into_item_data();
|
||||||
|
}
|
||||||
|
if value_str == "false" {
|
||||||
|
return CborValue::Bool(true).into_item_data();
|
||||||
|
}
|
||||||
|
if let Ok(int) = value_str.parse::<i128>() {
|
||||||
|
return int.into_item_data()
|
||||||
|
}
|
||||||
|
return CborValue::Text(value_str).into_item_data();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
pub fn set_path<P: IntoPath, D: IntoItemData>(&mut self, path: P, value: D) -> MizeResult<()> {
|
||||||
pub struct MizeId {
|
trace!("[ {} ] ItemData::set_path()", "CALL".yellow());
|
||||||
pub main: u64,
|
let path = path.into_path();
|
||||||
pub path: Option<Vec<String>>
|
let value = value.into_item_data();
|
||||||
|
|
||||||
|
item_data_set_path(&mut self.0, path, &value.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MizeType {
|
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())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
fn item_data_get_path(data: &CborValue, path: Vec<String>) -> MizeResult<&CborValue> {
|
||||||
|
let mut path_iter = path.clone().into_iter();
|
||||||
|
let path_el = match path_iter.nth(0) {
|
||||||
impl Display for MizeId {
|
Some(val) => val,
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
None => return Ok(data), // our base case
|
||||||
if let Some(path) = &self.path {
|
};
|
||||||
write!(f, "{}/{}", self.main, path.join("/"))
|
let mut sub_data = &CborValue::Null;
|
||||||
} else {
|
match data {
|
||||||
write!(f, "{}", self.main)
|
CborValue::Map(ref map) => {
|
||||||
|
for (key, val) in map {
|
||||||
|
if let CborValue::Text(key_str) = key {
|
||||||
|
if key_str == &path_el {
|
||||||
|
sub_data = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
impl MizeId {
|
val => {
|
||||||
pub fn main(main: u64) -> MizeId {
|
return Err(MizeError::new()
|
||||||
MizeId { main, path: None }
|
.msg(format!("Failed to get path '{:?}' from ItemData, the data at '{}' is not a map", path, path_el))
|
||||||
|
.msg(format!("{:?} is: {:?}", path_el, val)));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
path_iter.next();
|
||||||
|
item_data_get_path(sub_data, path_iter.collect())
|
||||||
}
|
}
|
||||||
pub fn join(self, segment: &str) -> MizeId {
|
|
||||||
let mut new = self.clone();
|
fn item_data_set_path(data: &mut CborValue, path: Vec<String>, new_data: &CborValue) -> MizeResult<()> {
|
||||||
match new.path {
|
trace!("[ {} ] item_data_set_path", "CALL".yellow());
|
||||||
|
trace!("[ {} ] data: {}", "ARG".yellow(), data.clone().into_item_data());
|
||||||
|
trace!("[ {} ] path: {:?}", "ARG".yellow(), path);
|
||||||
|
trace!("[ {} ] new_data: {}", "ARG".yellow(), new_data.clone().into_item_data());
|
||||||
|
|
||||||
|
let mut path_iter = path.clone().into_iter();
|
||||||
|
let path_el = match path_iter.nth(0) {
|
||||||
|
Some(val) => val,
|
||||||
None => {
|
None => {
|
||||||
new.path = Some(vec![segment.to_owned()]);
|
// our base case
|
||||||
}
|
*data = new_data.to_owned();
|
||||||
Some(ref mut val) => {
|
return Ok(());
|
||||||
val.push(segment.to_owned());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
impl ItemCbor {
|
|
||||||
fn value_as_file(&self) -> MizeResult<File> {
|
|
||||||
/* sadly does not work like that
|
|
||||||
let cbor_c = self.inner.get("v").ok_or(MizeError::new()
|
|
||||||
.msg(format!("The ItemCbor ({}) does not have a \"c\" field ... so can't get it as a file", self.id()?)))?;
|
|
||||||
match cbor_c {
|
|
||||||
Cbor::Bytes(val) => {
|
|
||||||
return Ok(Cursor::new(val.clone()).into());
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
return Err(MizeError::new().msg(format!("The value fo item ({}) is not of type Cbor::Bytes", self.id()?)));
|
|
||||||
},
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return File::open(self.value_as_path()?).mize_result_msg("Could not open file");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn value_as_path(&self) -> MizeResult<PathBuf> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/* an old way of getting the id this
|
|
||||||
fn id(self) -> MizeResult<MizeId> {
|
|
||||||
let cbor_item = self.inner.get("item".to_owned()).ok_or(MizeError::new()
|
|
||||||
.msg("ItemCbor had no path: \"item\""))?;
|
|
||||||
|
|
||||||
let cbor_id = match cbor_item {
|
|
||||||
Cbor::Map(map) => {
|
|
||||||
map.get("id").ok_or(MizeError::new().msg("ItemCbor had no path \"item/id\""))
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
return Err(MizeError::new().msg("ItemCbor path \"item\" was not of type Cbor::Map"));
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
match data {
|
||||||
let id = match cbor_id {
|
CborValue::Map(ref mut map) => {
|
||||||
Cbor::Unsigned(val) => val.into_u64(),
|
for (key, val) in map {
|
||||||
_ => {
|
if let CborValue::Text(key_str) = key {
|
||||||
return Err(MizeError::new().msg("ItemCbor path \"item/id\" was not of type Cbor::Unsigned"));
|
if key_str == &path_el {
|
||||||
|
path_iter.next();
|
||||||
|
return item_data_set_path(val, path_iter.collect(), new_data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
CborValue::Null => {
|
||||||
|
let map_vec = vec![(CborValue::Text(path_el), CborValue::Null)];
|
||||||
|
*data = CborValue::Map(map_vec);
|
||||||
|
return item_data_set_path(data, path, new_data);
|
||||||
|
},
|
||||||
|
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!("{:?} is: {:?}", path_el, val)));
|
||||||
},
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
return Err(MizeError::new().msg("unreachable"));
|
||||||
|
}
|
||||||
|
|
||||||
return Ok(MizeId { inner: id });
|
fn item_data_merge(first: &mut ItemData, other: ItemData){
|
||||||
|
match first.0 {
|
||||||
|
_ => {
|
||||||
|
*first = other;
|
||||||
|
},
|
||||||
|
CborValue::Map(ref mut map) => {
|
||||||
|
match other.0 {
|
||||||
|
_ => {
|
||||||
|
*first = other;
|
||||||
}
|
}
|
||||||
// */
|
CborValue::Map(mut other_map) => {
|
||||||
|
let mut to_add = Vec::new();
|
||||||
fn id(&self) -> MizeResult<MizeId> {
|
for (other_key, other_val) in other_map.clone() {
|
||||||
Ok(self.id.clone())
|
let mut key_found_in_old = false;
|
||||||
|
for (key, mut val) in map.clone() {
|
||||||
|
if key == other_key {
|
||||||
|
val = other_val.clone();
|
||||||
|
key_found_in_old = true;
|
||||||
}
|
}
|
||||||
fn as_cbor(&self) -> MizeResult<ItemCbor> {
|
|
||||||
Ok(self.clone())
|
|
||||||
}
|
}
|
||||||
fn write_to_path(&self, path: PathBuf) -> MizeResult<()> {
|
if key_found_in_old == false {
|
||||||
todo!()
|
to_add.push((other_key.clone(), other_val.clone()));
|
||||||
//let cbor_content =
|
}
|
||||||
//std::fs::write(path.join(format!("{}", self.id)), );
|
}
|
||||||
|
other_map.extend(to_add);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ItemFolder {
|
trait IntoPath {
|
||||||
fn value_as_file(&self) -> MizeResult<File> {
|
fn into_path(self) -> Vec<String>;
|
||||||
let file = File::open(self.path.join("v"))
|
|
||||||
.mize_result_msg(format!("Could not open the value file of item ({})", self.id()?));
|
|
||||||
return file;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn value_as_path(&self) -> MizeResult<PathBuf> {
|
pub trait IntoItemData {
|
||||||
return Ok(self.path.clone());
|
fn into_item_data(self) -> ItemData;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn id(&self) -> MizeResult<MizeId> {
|
impl IntoPath for &str {
|
||||||
Ok(self.id.clone())
|
fn into_path(self) -> Vec<String> {
|
||||||
}
|
self.to_owned().split("/").map(|v| v.to_owned()).collect()
|
||||||
|
|
||||||
fn as_cbor(&self) -> MizeResult<ItemCbor> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_to_path(&self, path: PathBuf) -> MizeResult<()> {
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ItemRef {
|
impl IntoPath for &[&str] {
|
||||||
fn value_as_file(&self) -> MizeResult<File> {
|
fn into_path(self) -> Vec<String> {
|
||||||
todo!()
|
self.into_iter().map(|v| (*v).to_owned()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn value_as_path(&self) -> MizeResult<PathBuf> {
|
|
||||||
todo!()
|
|
||||||
}
|
}
|
||||||
|
impl IntoPath for Vec<String> {
|
||||||
fn id(&self) -> MizeResult<MizeId> {
|
fn into_path(self) -> Vec<String> {
|
||||||
return Ok(self.id.clone());
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_cbor(&self) -> MizeResult<ItemCbor> {
|
|
||||||
todo!()
|
|
||||||
}
|
}
|
||||||
|
impl IntoPath for Vec<&str> {
|
||||||
async fn write_to_path(&self, path: PathBuf) -> MizeResult<()> {
|
fn into_path(self) -> Vec<String> {
|
||||||
let store = self.store.lock().await;
|
self.into_iter().map(|v| v.to_owned()).collect()
|
||||||
for (key, value) in self.map.iter() {
|
|
||||||
// TODO right here!!!!
|
|
||||||
}
|
|
||||||
todo!()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Item {
|
impl IntoItemData for &str {
|
||||||
pub fn value_as_file(&self) -> MizeResult<File> {
|
fn into_item_data(self) -> ItemData {
|
||||||
match self {
|
ItemData::parse(self)
|
||||||
Item::Cbor(val) => val.value_as_file(),
|
}
|
||||||
Item::Ref(val) => val.value_as_file(),
|
}
|
||||||
Item::Folder(val) => val.value_as_file(),
|
impl IntoItemData for CborValue {
|
||||||
|
fn into_item_data(self) -> ItemData {
|
||||||
|
ItemData ( self )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl IntoItemData for ItemData {
|
||||||
|
fn into_item_data(self) -> ItemData {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl IntoItemData for i128 {
|
||||||
|
fn into_item_data(self) -> ItemData {
|
||||||
|
ItemData(self.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn value_as_path(&self) -> MizeResult<PathBuf> {
|
impl fmt::Display for ItemData {
|
||||||
match self {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
Item::Cbor(val) => val.value_as_path(),
|
write!(f, "\nItemData: ");
|
||||||
Item::Ref(val) => val.value_as_path(),
|
let display_writer = DisplayWriter (f);
|
||||||
Item::Folder(val) => val.value_as_path(),
|
self.0.serialize(&mut serde_json::Serializer::pretty(display_writer))
|
||||||
|
.map_err(|serde_err| std::fmt::Error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn id(&self) -> MizeResult<MizeId> {
|
// thanks to: https://stackoverflow.com/a/61768916
|
||||||
match self {
|
struct DisplayWriter<'a, 'b>(&'a mut fmt::Formatter<'b>);
|
||||||
Item::Cbor(val) => val.id(),
|
|
||||||
Item::Ref(val) => val.id(),
|
impl<'a, 'b> io::Write for DisplayWriter<'a, 'b> {
|
||||||
Item::Folder(val) => val.id(),
|
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!() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_cbor(&self) -> MizeResult<ItemCbor> {
|
|
||||||
match self {
|
|
||||||
Item::Cbor(val) => val.as_cbor(),
|
|
||||||
Item::Ref(val) => val.as_cbor(),
|
|
||||||
Item::Folder(val) => val.as_cbor(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write_to_path(&self, path: PathBuf) -> MizeResult<()> {
|
|
||||||
match self {
|
|
||||||
Item::Cbor(val) => val.write_to_path(path),
|
|
||||||
Item::Ref(val) => val.write_to_path(path),
|
|
||||||
Item::Folder(val) => val.write_to_path(path),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn load_json(json_str: &str) -> MizeResult<Item> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ pub type MemStoreId = u64;
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct MemStoreInner {
|
struct MemStoreInner {
|
||||||
map: HashMap<u64, CborValue>,
|
map: HashMap<u64, ItemData>,
|
||||||
next_id: u64,
|
next_id: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +60,13 @@ impl Store for MemStore {
|
|||||||
id_iter.next();
|
id_iter.next();
|
||||||
let id_without_first = id_iter.collect();
|
let id_without_first = id_iter.collect();
|
||||||
|
|
||||||
Ok(get_raw_from_cbor(cbor_val, id_without_first)?.to_owned())
|
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()?;
|
||||||
|
inner.map.get(&id_to_u64(id.clone())?)
|
||||||
|
.ok_or(MizeError::new().msg(format!("Item wich id '{}' has not data stored in this MemStore", id.clone()))).cloned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +89,6 @@ fn get_raw_from_cbor<'a>(value: &'a CborValue, path: Vec<&String>) -> MizeResult
|
|||||||
CborValue::Text(string) => Ok(string.as_bytes()),
|
CborValue::Text(string) => Ok(string.as_bytes()),
|
||||||
CborValue::Map(map) => {
|
CborValue::Map(map) => {
|
||||||
let mut inner_val: &CborValue = &CborValue::Null;
|
let mut inner_val: &CborValue = &CborValue::Null;
|
||||||
trace!("map: {:?}", map);
|
|
||||||
for (key, val) in map.into_iter() {
|
for (key, val) in map.into_iter() {
|
||||||
let first_path_string = *path.iter().nth(0)
|
let first_path_string = *path.iter().nth(0)
|
||||||
.ok_or(MizeError::new()
|
.ok_or(MizeError::new()
|
||||||
|
|||||||
@@ -5,12 +5,13 @@ use home::home_dir;
|
|||||||
|
|
||||||
use mize::error::{IntoMizeResult, MizeError, MizeResult, MizeResultTrait};
|
use mize::error::{IntoMizeResult, MizeError, MizeResult, MizeResultTrait};
|
||||||
use mize::instance::Instance;
|
use mize::instance::Instance;
|
||||||
|
use mize::platform::os::config_from_cli_args;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub fn get(sub_matches: &ArgMatches) -> MizeResult<()> {
|
pub fn get(sub_matches: &ArgMatches) -> MizeResult<()> {
|
||||||
|
|
||||||
let instance = Instance::new()?;
|
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"))?;
|
.ok_or(MizeError::new().msg("No id Argument specified"))?;
|
||||||
|
|||||||
@@ -13,9 +13,8 @@ use mize::instance::Instance;
|
|||||||
pub fn run(sub_matches: &ArgMatches) -> MizeResult<()> {
|
pub fn run(sub_matches: &ArgMatches) -> MizeResult<()> {
|
||||||
|
|
||||||
// TODO NEXT!!!
|
// TODO NEXT!!!
|
||||||
// - add --system arg
|
|
||||||
// - add --user arg
|
|
||||||
// - --config arg
|
// - --config arg
|
||||||
|
// - --folder
|
||||||
// - to set a location, where there will be a /store and a /sock
|
// - to set a location, where there will be a /store and a /sock
|
||||||
// - listen for connections on that sock
|
// - listen for connections on that sock
|
||||||
// - msg handeling
|
// - msg handeling
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ use std::path::PathBuf;
|
|||||||
use clap::{ArgAction, ArgMatches};
|
use clap::{ArgAction, ArgMatches};
|
||||||
use clap::{Arg, crate_version, Command};
|
use clap::{Arg, crate_version, Command};
|
||||||
|
|
||||||
use mize::error::MizeError;
|
use mize::error::{MizeError, MizeResult};
|
||||||
|
use mize::item::ItemData;
|
||||||
use tokio::sync::{Mutex, mpsc};
|
use tokio::sync::{Mutex, mpsc};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use log::Level;
|
use log::Level;
|
||||||
@@ -258,12 +259,9 @@ fn level_from_env(var_name: &str, log_level: LevelFilter) -> (Option<log::LevelF
|
|||||||
return (None, log_messages);
|
return (None, log_messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn cli_matches() -> clap::ArgMatches {
|
fn cli_matches() -> clap::ArgMatches {
|
||||||
|
|
||||||
let folder_arg = Arg::new("folder")
|
|
||||||
.short('f')
|
|
||||||
.long("folder")
|
|
||||||
.help("The folder the Instance stores all it's data and the socket for connections");
|
|
||||||
|
|
||||||
let main = Command::new(APPNAME)
|
let main = Command::new(APPNAME)
|
||||||
.version(crate_version!())
|
.version(crate_version!())
|
||||||
@@ -273,18 +271,37 @@ fn cli_matches() -> clap::ArgMatches {
|
|||||||
.long("verbose")
|
.long("verbose")
|
||||||
.short('v')
|
.short('v')
|
||||||
.action(ArgAction::Count)
|
.action(ArgAction::Count)
|
||||||
|
.global(true)
|
||||||
)
|
)
|
||||||
.arg(Arg::new("log-level")
|
.arg(Arg::new("log-level")
|
||||||
.long("log-level")
|
.long("log-level")
|
||||||
.value_name("LOGLEVEL")
|
.value_name("LOGLEVEL")
|
||||||
.help("set the log-level to one of OFF, ERROR, WARN, INFO, DEBUG, TRACE")
|
.help("set the log-level to one of OFF, ERROR, WARN, INFO, DEBUG, TRACE")
|
||||||
|
.global(true)
|
||||||
)
|
)
|
||||||
.arg(Arg::new("silent")
|
.arg(Arg::new("silent")
|
||||||
.long("silent")
|
.long("silent")
|
||||||
.action(ArgAction::SetTrue)
|
.action(ArgAction::SetTrue)
|
||||||
.help("set the log-level to OFF")
|
.help("set the log-level to OFF")
|
||||||
|
.global(true)
|
||||||
|
)
|
||||||
|
.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)
|
||||||
|
)
|
||||||
|
.arg(Arg::new("config")
|
||||||
|
.short('c')
|
||||||
|
.long("config")
|
||||||
|
.help("overwrite config options")
|
||||||
|
.global(true)
|
||||||
|
)
|
||||||
|
.arg(Arg::new("config-file")
|
||||||
|
.long("config-file")
|
||||||
|
.help("specify a config file")
|
||||||
|
.global(true)
|
||||||
)
|
)
|
||||||
.arg(&folder_arg)
|
|
||||||
.subcommand(
|
.subcommand(
|
||||||
Command::new("run")
|
Command::new("run")
|
||||||
.aliases(["r"])
|
.aliases(["r"])
|
||||||
@@ -300,25 +317,21 @@ fn cli_matches() -> clap::ArgMatches {
|
|||||||
.subcommand(
|
.subcommand(
|
||||||
Command::new("get")
|
Command::new("get")
|
||||||
.aliases(["g"])
|
.aliases(["g"])
|
||||||
.arg(&folder_arg)
|
|
||||||
.arg(Arg::new("id").help("The id or path to get"))
|
.arg(Arg::new("id").help("The id or path to get"))
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
Command::new("set")
|
Command::new("set")
|
||||||
.aliases(["s"])
|
.aliases(["s"])
|
||||||
.arg(&folder_arg)
|
|
||||||
.arg(Arg::new("id").help("The id or path to set"))
|
.arg(Arg::new("id").help("The id or path to set"))
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
Command::new("show")
|
Command::new("show")
|
||||||
.aliases(["so"])
|
.aliases(["so"])
|
||||||
.arg(&folder_arg)
|
|
||||||
.arg(Arg::new("id").help("The id or path to sub to and show"))
|
.arg(Arg::new("id").help("The id or path to sub to and show"))
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
Command::new("call")
|
Command::new("call")
|
||||||
.aliases(["c"])
|
.aliases(["c"])
|
||||||
.arg(&folder_arg)
|
|
||||||
)
|
)
|
||||||
.arg_required_else_help(true);
|
.arg_required_else_help(true);
|
||||||
|
|
||||||
|
|||||||
@@ -1,35 +1,110 @@
|
|||||||
use ciborium::Value as CborValue;
|
use ciborium::Value as CborValue;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
use std::env::VarError;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use log::{debug, error, warn, trace};
|
||||||
|
use clap::ArgMatches;
|
||||||
|
|
||||||
use crate::id::MizeId;
|
use crate::id::MizeId;
|
||||||
use crate::instance::store::Store;
|
use crate::instance::store::Store;
|
||||||
use crate::instance::Instance;
|
use crate::instance::Instance;
|
||||||
use crate::error::{IntoMizeResult, MizeError, MizeResult};
|
use crate::error::{IntoMizeResult, MizeError, MizeResult};
|
||||||
|
use crate::item::{ItemData, IntoItemData};
|
||||||
|
|
||||||
|
|
||||||
pub fn os_instance_init<S: Store>(instance: &mut Instance<S>) -> MizeResult<()> {
|
pub fn os_instance_init<S: Store>(instance: &mut Instance<S>) -> MizeResult<()> {
|
||||||
// this is the code, that runs to initialize an Instance on a system with an os present.
|
// this is the code, that runs to initialize an Instance on a system with an os present.
|
||||||
|
|
||||||
|
let mut config = ItemData::new();
|
||||||
|
|
||||||
////// load MIZE_CONFIG_FILE as the instance, which is item 0
|
////// load MIZE_CONFIG_FILE as the instance, which is item 0
|
||||||
let config_file_path = std::env::var("MIZE_CONFIG_FILE")
|
match std::env::var("MIZE_CONFIG_FILE") {
|
||||||
.mize_result_msg("Could not get the MIZE_CONFIG_FILE Environment Variable")?;
|
Ok(config_file_path) => {
|
||||||
|
config.merge(config_from_file(config_file_path)?);
|
||||||
let toml_string = fs::read_to_string(&config_file_path)
|
debug!("env var MIZE_CONFIG_FILE present");
|
||||||
.mize_result_msg(format!("Could not read file {} as mize config", &config_file_path))?;
|
trace!("config after MIZE_CONFIG_FILE env var: {}", config);
|
||||||
|
}
|
||||||
let toml_deserializer = toml::Deserializer::new(&toml_string.as_str());
|
Err(var_err) => match var_err {
|
||||||
|
VarError::NotPresent => {
|
||||||
let config = CborValue::deserialize(toml_deserializer)
|
debug!("env var MIZE_CONFIG_FILE NOT present");
|
||||||
.mize_result_msg(format!("Could not deserialize the content of MIZE_CONFIG_FILE at {}", &config_file_path))?;
|
},
|
||||||
|
VarError::NotUnicode(_) => {
|
||||||
instance.set("0", config)?;
|
warn!("env var MIZE_CONFIG_FILE is not Unicode, so not reading it")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
////// load config from MIZE_CONFIG env var
|
////// load config from MIZE_CONFIG env var
|
||||||
//TODO
|
match std::env::var("MIZE_CONFIG") {
|
||||||
|
Ok(config_string) => {
|
||||||
|
config.merge(config_from_string(config_string)?);
|
||||||
|
debug!("env var MIZE_CONFIG present");
|
||||||
|
trace!("config after MIZE_CONFIG env var: {}", 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")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
instance.set("0", config)?;
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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") {
|
||||||
|
config.merge(config_from_file(config_file_path.to_string())?);
|
||||||
|
trace!("config after --config-file arg: {}", config);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(config_string) = matches.get_one::<String>("config") {
|
||||||
|
config.merge(config_from_string(config_string.to_string())?);
|
||||||
|
trace!("config after --config arg: {}", config);
|
||||||
|
}
|
||||||
|
|
||||||
|
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))?;
|
||||||
|
|
||||||
|
let toml_deserializer = toml::Deserializer::new(&toml_string.as_str());
|
||||||
|
|
||||||
|
let config = CborValue::deserialize(toml_deserializer)
|
||||||
|
.mize_result_msg(format!("Could not deserialize the content of MIZE_CONFIG_FILE at {}", &file_path))?;
|
||||||
|
|
||||||
|
return Ok(config.into_item_data());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn config_from_string(config_string: String) -> MizeResult<ItemData> {
|
||||||
|
|
||||||
|
let mut config = ItemData::new();
|
||||||
|
|
||||||
|
for option in config_string.split(";") {
|
||||||
|
let path = option.split("=").nth(0)
|
||||||
|
.ok_or(MizeError::new().msg(format!("Failed to parse Option: option '{}' has an empty path (thing beforee =)", 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)))?;
|
||||||
|
let mut path_vec = vec!["config"];
|
||||||
|
path_vec.extend(path.split("."));
|
||||||
|
|
||||||
|
config.set_path(path_vec, ItemData::parse(value))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user