mirror of
https://github.com/Astatin3/unshell.git
synced 2026-06-08 22:38:01 -06:00
Move everything into workspace
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
// use bincode::{Decode, Encode};
|
||||
|
||||
/// Mostly temporary server message type
|
||||
// #[derive(Clone, Debug, Encode, Decode)]
|
||||
pub enum Announcement {
|
||||
TestAnnouncement(String),
|
||||
// GetRuntimes,
|
||||
// GetRuntimesAck(usize),
|
||||
|
||||
// StartRuntime(RuntimeConfig),
|
||||
// StartRuntimeAck(bool),
|
||||
}
|
||||
|
||||
// const BINCODE_CONFIG: bincode::config::Configuration = bincode::config::standard();
|
||||
|
||||
// impl Announcement {
|
||||
// pub fn encode(&self) -> Vec<u8> {
|
||||
// bincode::encode_to_vec(self, BINCODE_CONFIG).unwrap()
|
||||
// }
|
||||
|
||||
// pub fn decode(bytes: &[u8]) -> Option<Self> {
|
||||
// if let Ok((decoded, _)) = bincode::decode_from_slice(&bytes[..], BINCODE_CONFIG) {
|
||||
// Some(decoded)
|
||||
// } else {
|
||||
// None
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
@@ -0,0 +1,56 @@
|
||||
use serde_json::{Value, json};
|
||||
|
||||
use crate::{
|
||||
ModuleError, Result,
|
||||
config::{ConfigStructField, InterfaceData, InterfaceStruct, TreeMessage},
|
||||
warn,
|
||||
};
|
||||
|
||||
pub type ConfigStructKeys = Vec<ConfigStructField>;
|
||||
pub type ConfigStructValues = Vec<Value>;
|
||||
|
||||
pub struct Config {
|
||||
keys: ConfigStructKeys,
|
||||
values: ConfigStructValues,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn new(keys: ConfigStructKeys) -> Self {
|
||||
let values = keys
|
||||
.iter()
|
||||
.map(|key| match key {
|
||||
ConfigStructField::Header(_) => Value::Null,
|
||||
ConfigStructField::Text(_) => Value::Null,
|
||||
ConfigStructField::String { default, .. } => json!(default),
|
||||
ConfigStructField::Integer { default, .. } => json!(default),
|
||||
})
|
||||
.collect();
|
||||
|
||||
Self { keys, values }
|
||||
}
|
||||
|
||||
pub fn get(&mut self, message: TreeMessage) -> Result<TreeMessage> {
|
||||
match message {
|
||||
TreeMessage::State(InterfaceData::ConfigStruct(values)) => {
|
||||
self.values = values;
|
||||
Ok(TreeMessage::Success)
|
||||
}
|
||||
|
||||
// TreeMessage::RequestStruct => Ok(TreeMessage::Interface(
|
||||
// InterfaceStruct::ConfigStruct(self.keys.clone()),
|
||||
// )),
|
||||
TreeMessage::RequestState => Ok(TreeMessage::State(InterfaceData::ConfigStruct(
|
||||
self.values.clone(),
|
||||
))),
|
||||
TreeMessage::RequestStructAndValue => Ok(TreeMessage::InterfaceAndValue(
|
||||
InterfaceStruct::ConfigStruct(self.keys.clone()),
|
||||
InterfaceData::ConfigStruct(self.values.clone()),
|
||||
)),
|
||||
|
||||
_ => {
|
||||
warn!("Tree got invalid message");
|
||||
Err(ModuleError::Error("Invalid Request".into()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
use serde_json::{Value, json};
|
||||
|
||||
use crate::config::ConfigStructField;
|
||||
|
||||
pub type ConfigStructListKeys = Vec<ConfigStructField>;
|
||||
pub type ConfigStructListValues = Vec<Vec<Value>>;
|
||||
|
||||
pub struct ConfigStructList {
|
||||
keys: ConfigStructListKeys,
|
||||
values: ConfigStructListValues,
|
||||
}
|
||||
|
||||
impl ConfigStructList {
|
||||
pub fn new(keys: ConfigStructListKeys) -> Self {
|
||||
// let values = keys
|
||||
// .iter()
|
||||
// .map(|key| match key {
|
||||
// ConfigStructField::Header(_) => Value::Null,
|
||||
// ConfigStructField::Text(_) => Value::Null,
|
||||
// ConfigStructField::String { default, .. } => json!(default),
|
||||
// ConfigStructField::Integer { default, .. } => json!(default),
|
||||
// })
|
||||
// .collect();
|
||||
|
||||
Self {
|
||||
keys,
|
||||
values: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// impl Tree for ConfigStructList {}
|
||||
@@ -0,0 +1,41 @@
|
||||
pub mod config_struct;
|
||||
pub mod config_struct_list;
|
||||
mod tree;
|
||||
|
||||
pub use tree::{InterfaceData, InterfaceStruct, Tree, TreeMessage};
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RuntimeConfig {
|
||||
pub parent_component: String,
|
||||
pub name: String,
|
||||
pub config: HashMap<String, String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub enum ConfigStructField {
|
||||
Header(String),
|
||||
Text(String),
|
||||
String {
|
||||
// Default value of string edit in struct
|
||||
#[serde(default)]
|
||||
default: String,
|
||||
max_length: Option<usize>,
|
||||
// Display string edit as password
|
||||
#[serde(default)]
|
||||
protected: bool,
|
||||
},
|
||||
Integer {
|
||||
// Default value of integer in struct
|
||||
#[serde(default)]
|
||||
default: i32,
|
||||
min: Option<i32>,
|
||||
max: Option<i32>,
|
||||
},
|
||||
// Checkbox
|
||||
// Dropdown
|
||||
// Collapsing header
|
||||
// Slider
|
||||
// ...
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{ModuleError, Result, config::config_struct};
|
||||
|
||||
pub trait Tree {
|
||||
fn is_folder() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn get_children_string(&self) -> Vec<String> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn select_child(&mut self, child: &str, _message: TreeMessage) -> Result<TreeMessage>;
|
||||
|
||||
fn get_value(&self, _message: TreeMessage) -> TreeMessage {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn get_path(&mut self, elements: &mut Vec<&str>, message: TreeMessage) -> Result<TreeMessage> {
|
||||
if elements.is_empty() {
|
||||
return if Self::is_folder() {
|
||||
Ok(TreeMessage::Folder(self.get_children_string()))
|
||||
} else {
|
||||
Ok(self.get_value(message))
|
||||
};
|
||||
}
|
||||
|
||||
let child = elements.remove(0);
|
||||
|
||||
if Self::is_folder() {
|
||||
self.select_child(child, message)
|
||||
} else {
|
||||
Err(ModuleError::TreeMessageError(
|
||||
"This is a folder, not a file".into(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn get(&mut self, path: &str, message: TreeMessage) -> Result<TreeMessage> {
|
||||
let mut path = if path.is_empty() {
|
||||
Vec::new()
|
||||
} else {
|
||||
path.split("/").collect::<Vec<&str>>()
|
||||
};
|
||||
|
||||
self.get_path(&mut path, message)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub enum TreeMessage {
|
||||
RequestState,
|
||||
RequestStruct,
|
||||
RequestStructAndValue,
|
||||
|
||||
State(InterfaceData),
|
||||
// Interface(InterfaceStruct),
|
||||
InterfaceAndValue(InterfaceStruct, InterfaceData),
|
||||
|
||||
Success,
|
||||
Failure,
|
||||
|
||||
Folder(Vec<String>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub enum InterfaceStruct {
|
||||
ConfigStruct(config_struct::ConfigStructKeys),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub enum InterfaceData {
|
||||
ConfigStruct(config_struct::ConfigStructValues),
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
use std::fmt;
|
||||
|
||||
pub type Result<T> = std::result::Result<T, ModuleError>;
|
||||
|
||||
///Generic error type for module-related operations.
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum ModuleError {
|
||||
LibLoadingError(String),
|
||||
// LogError(log::SetLoggerError),
|
||||
LinkError(String),
|
||||
CryptError(String),
|
||||
DatabaseError(String),
|
||||
SerdeJsonError(String),
|
||||
|
||||
TreeMessageError(String),
|
||||
|
||||
Error(String),
|
||||
}
|
||||
|
||||
impl From<&str> for ModuleError {
|
||||
fn from(value: &str) -> Self {
|
||||
Self::Error(value.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<serde_json::Error> for ModuleError {
|
||||
fn from(value: serde_json::Error) -> Self {
|
||||
Self::SerdeJsonError(value.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Box<dyn std::error::Error>> for ModuleError {
|
||||
fn from(value: Box<dyn std::error::Error>) -> Self {
|
||||
ModuleError::Error(value.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for ModuleError {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
None
|
||||
}
|
||||
|
||||
fn description(&self) -> &str {
|
||||
"description() is deprecated; use Display"
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&dyn std::error::Error> {
|
||||
Some(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ModuleError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str(format!("{:?}", self).as_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ModuleError> for std::string::String {
|
||||
fn from(value: ModuleError) -> Self {
|
||||
value.to_string()
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
#![no_main]
|
||||
|
||||
pub mod config;
|
||||
mod error;
|
||||
pub mod logger;
|
||||
|
||||
mod announcement;
|
||||
|
||||
pub use error::{ModuleError, Result};
|
||||
|
||||
pub use announcement::Announcement;
|
||||
|
||||
// pub trait Component {
|
||||
// fn name(&self) -> &'static str;
|
||||
// // fn start_runtime(&self, manager: Arc<Mutex<Manager>>) -> Option<Box<dyn ModuleRuntime>>;
|
||||
|
||||
// fn get_interface(&self) -> Box<dyn Interface>;
|
||||
// fn clone_box(&self) -> Box<dyn Component>;
|
||||
// }
|
||||
|
||||
// impl Clone for Box<dyn Component> {
|
||||
// fn clone(&self) -> Box<dyn Component> {
|
||||
// self.clone_box()
|
||||
// }
|
||||
// }
|
||||
@@ -0,0 +1,148 @@
|
||||
#[cfg(feature = "log_debug")]
|
||||
#[macro_export]
|
||||
macro_rules! debug {
|
||||
($fmt:tt) => {{
|
||||
let log_result = unshell_obfuscate::format_obs!($fmt);
|
||||
|
||||
$crate::logger::add_record(
|
||||
$crate::logger::LogLevel::Debug,
|
||||
|
||||
#[cfg(feature = "log_debug")]
|
||||
Some(String::from(unshell_obfuscate::file_symbol!())),
|
||||
#[cfg(not(feature = "log_debug"))]
|
||||
None,
|
||||
|
||||
std::time::SystemTime::now(),
|
||||
log_result
|
||||
);
|
||||
}};
|
||||
($fmt:tt, $($arg:expr),*) => {{
|
||||
let log_result = unshell_obfuscate::format_obs!($fmt, $($arg),*);
|
||||
|
||||
$crate::logger::add_record(
|
||||
$crate::logger::LogLevel::Debug,
|
||||
|
||||
#[cfg(feature = "log_debug")]
|
||||
Some(String::from(unshell_obfuscate::file_symbol!())),
|
||||
#[cfg(not(feature = "log_debug"))]
|
||||
None,
|
||||
|
||||
std::time::SystemTime::now(),
|
||||
log_result
|
||||
);
|
||||
}};
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "log_debug"))]
|
||||
#[macro_export]
|
||||
macro_rules! debug {
|
||||
($fmt:tt) => {{
|
||||
let _ = $fmt;
|
||||
}};
|
||||
($fmt:tt, $($arg:expr),*) => {{
|
||||
let _ = $fmt;
|
||||
$(let _ = $arg;)*
|
||||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! info {
|
||||
($fmt:tt) => {{
|
||||
let log_result = unshell_obfuscate::format_obs!($fmt);
|
||||
|
||||
$crate::logger::add_record(
|
||||
$crate::logger::LogLevel::Info,
|
||||
|
||||
#[cfg(feature = "log_debug")]
|
||||
Some(String::from(unshell_obfuscate::file_symbol!())),
|
||||
#[cfg(not(feature = "log_debug"))]
|
||||
None,
|
||||
|
||||
std::time::SystemTime::now(),
|
||||
log_result
|
||||
);
|
||||
}};
|
||||
($fmt:tt, $($arg:expr),*) => {{
|
||||
let log_result = unshell_obfuscate::format_obs!($fmt, $($arg),*);
|
||||
|
||||
$crate::logger::add_record(
|
||||
$crate::logger::LogLevel::Info,
|
||||
|
||||
#[cfg(feature = "log_debug")]
|
||||
Some(String::from(unshell_obfuscate::file_symbol!())),
|
||||
#[cfg(not(feature = "log_debug"))]
|
||||
None,
|
||||
|
||||
std::time::SystemTime::now(),
|
||||
log_result
|
||||
);
|
||||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! warn {
|
||||
($fmt:tt) => {{
|
||||
let log_result = unshell_obfuscate::format_obs!($fmt);
|
||||
|
||||
$crate::logger::add_record(
|
||||
$crate::logger::LogLevel::Warn,
|
||||
|
||||
#[cfg(feature = "log_debug")]
|
||||
Some(String::from(unshell_obfuscate::file_symbol!())),
|
||||
#[cfg(not(feature = "log_debug"))]
|
||||
None,
|
||||
|
||||
std::time::SystemTime::now(),
|
||||
log_result
|
||||
);
|
||||
}};
|
||||
($fmt:tt, $($arg:expr),*) => {{
|
||||
let log_result = unshell_obfuscate::format_obs!($fmt, $($arg),*);
|
||||
|
||||
$crate::logger::add_record(
|
||||
$crate::logger::LogLevel::Warn,
|
||||
|
||||
#[cfg(feature = "log_debug")]
|
||||
Some(String::from(unshell_obfuscate::file_symbol!())),
|
||||
#[cfg(not(feature = "log_debug"))]
|
||||
None,
|
||||
|
||||
std::time::SystemTime::now(),
|
||||
log_result
|
||||
);
|
||||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! error {
|
||||
($fmt:tt) => {{
|
||||
let log_result = unshell_obfuscate::format_obs!($fmt);
|
||||
|
||||
$crate::logger::add_record(
|
||||
$crate::logger::LogLevel::Error,
|
||||
|
||||
#[cfg(feature = "log_debug")]
|
||||
Some(String::from(unshell_obfuscate::file_symbol!())),
|
||||
#[cfg(not(feature = "log_debug"))]
|
||||
None,
|
||||
|
||||
std::time::SystemTime::now(),
|
||||
log_result
|
||||
);
|
||||
}};
|
||||
($fmt:tt, $($arg:expr),*) => {{
|
||||
let log_result = unshell_obfuscate::format_obs!($fmt, $($arg),*);
|
||||
|
||||
$crate::logger::add_record(
|
||||
$crate::logger::LogLevel::Error,
|
||||
|
||||
#[cfg(feature = "log_debug")]
|
||||
Some(String::from(unshell_obfuscate::file_symbol!())),
|
||||
#[cfg(not(feature = "log_debug"))]
|
||||
None,
|
||||
|
||||
std::time::SystemTime::now(),
|
||||
log_result
|
||||
);
|
||||
}};
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
// Macros that are used that just drop the inside variables
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! debug {
|
||||
($fmt:tt) => {{
|
||||
let _ = $fmt;
|
||||
}};
|
||||
($fmt:tt, $($arg:expr),*) => {{
|
||||
let _ = $fmt;
|
||||
$(let _ = $arg;)*
|
||||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! info {
|
||||
($fmt:tt) => {{
|
||||
let _ = $fmt;
|
||||
}};
|
||||
($fmt:tt, $($arg:expr),*) => {{
|
||||
let _ = $fmt;
|
||||
$(let _ = $arg;)*
|
||||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! warn {
|
||||
($fmt:tt) => {{
|
||||
let _ = $fmt;
|
||||
}};
|
||||
($fmt:tt, $($arg:expr),*) => {{
|
||||
let _ = $fmt;
|
||||
$(let _ = $arg;)*
|
||||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! error {
|
||||
($fmt:tt) => {{
|
||||
let _ = $fmt;
|
||||
}};
|
||||
($fmt:tt, $($arg:expr),*) => {{
|
||||
let _ = $fmt;
|
||||
$(let _ = $arg;)*
|
||||
}};
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
// Choose if the macros are enabled based on the feature setting
|
||||
#[cfg(feature = "log")]
|
||||
pub mod macros;
|
||||
|
||||
#[cfg(not(feature = "log"))]
|
||||
pub mod macros_disabled;
|
||||
|
||||
mod pretty_logger;
|
||||
|
||||
use std::time::SystemTime;
|
||||
|
||||
pub use pretty_logger::PrettyLogger;
|
||||
|
||||
static mut LOGGER: &dyn Logger = &DefaultLogger;
|
||||
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum LogLevel {
|
||||
Debug,
|
||||
Info,
|
||||
Warn,
|
||||
Error,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub struct Record {
|
||||
log_level: LogLevel,
|
||||
location: Option<String>,
|
||||
// line: u32,
|
||||
time: SystemTime,
|
||||
message: String,
|
||||
}
|
||||
|
||||
pub trait Logger {
|
||||
fn log(&self, log: Record);
|
||||
}
|
||||
|
||||
struct DefaultLogger;
|
||||
|
||||
impl Logger for DefaultLogger {
|
||||
fn log(&self, _: Record) {}
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
pub fn set_logger_box(logger: Box<dyn Logger>) {
|
||||
#[cfg(feature = "log")]
|
||||
unsafe {
|
||||
LOGGER = Box::leak(logger);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_logger(logger: &'static dyn Logger) {
|
||||
unsafe {
|
||||
LOGGER = logger;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_record(
|
||||
log_level: LogLevel,
|
||||
location: Option<String>,
|
||||
time: SystemTime,
|
||||
message: String,
|
||||
) {
|
||||
logger().log(Record {
|
||||
log_level,
|
||||
location,
|
||||
time,
|
||||
message,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn logger() -> &'static dyn Logger {
|
||||
unsafe { LOGGER }
|
||||
}
|
||||
|
||||
#[allow(dead_code, improper_ctypes_definitions)]
|
||||
pub type SetupLogger = extern "C" fn(logger: &'static dyn Logger);
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
#[allow(improper_ctypes_definitions)]
|
||||
pub extern "C" fn setup_logger(logger: &'static dyn Logger) {
|
||||
set_logger(logger);
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
|
||||
use crate::logger::{LogLevel, Logger, Record};
|
||||
|
||||
pub struct PrettyLogger {
|
||||
output: Option<Box<dyn Fn(&Record)>>,
|
||||
}
|
||||
|
||||
// static TRACE_COLOR: &str = "\x1b[34m";
|
||||
static DEBUG_COLOR: &str = "\x1b[36m";
|
||||
static INFO_COLOR: &str = "\x1b[32m";
|
||||
static WARN_COLOR: &str = "\x1b[33m";
|
||||
static ERROR_COLOR: &str = "\x1b[31m";
|
||||
|
||||
static WHITE: &str = "\x1b[97m";
|
||||
static OFF_WHITE: &str = "\x1b[37m";
|
||||
static TIME_COLOR: &str = "\x1b[36m";
|
||||
static GREY: &str = "\x1b[90m";
|
||||
|
||||
impl Logger for PrettyLogger {
|
||||
fn log(&self, message: Record) {
|
||||
if let Some(ref func) = self.output {
|
||||
(*func)(&message)
|
||||
}
|
||||
|
||||
let log_level = match message.log_level {
|
||||
LogLevel::Debug => format!("{DEBUG_COLOR}DBUG"),
|
||||
LogLevel::Info => format!("{INFO_COLOR}INFO"),
|
||||
LogLevel::Warn => format!("{WARN_COLOR}WARN"),
|
||||
LogLevel::Error => format!("{ERROR_COLOR}ERR!"),
|
||||
};
|
||||
|
||||
let date: DateTime<Utc> = message.time.into();
|
||||
let date = date.to_rfc2822().to_string();
|
||||
|
||||
let location = message.location.unwrap_or("".to_string());
|
||||
|
||||
println!(
|
||||
"{OFF_WHITE}[{TIME_COLOR}{}{OFF_WHITE}] {} {WHITE}{} {GREY}{}{WHITE}",
|
||||
date, log_level, message.message, location
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
impl PrettyLogger {
|
||||
pub fn init() {
|
||||
crate::logger::set_logger_box(Box::new(PrettyLogger { output: None }));
|
||||
}
|
||||
|
||||
pub fn init_output<T>(output: T)
|
||||
where
|
||||
T: Fn(&Record) + 'static,
|
||||
{
|
||||
crate::logger::set_logger_box(Box::new(PrettyLogger {
|
||||
output: Some(Box::new(output)),
|
||||
}));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user