mirror of
https://github.com/Astatin3/unshell.git
synced 2026-06-09 06:47:59 -06:00
Add tree thing
This commit is contained in:
@@ -53,6 +53,9 @@ pub async fn start_api(address: &str, server: Server) {
|
||||
router = route_get!(router, "/api/keys/{*path}", Server::all_tree_keys_api);
|
||||
router = route_get!(router, "/api/values/{*path}", Server::all_tree_values_api);
|
||||
|
||||
router = route_get!(router, "/api/interface/", Server::get_tree2_root);
|
||||
router = route_get!(router, "/api/interface/{*path}", Server::get_tree2);
|
||||
|
||||
// router = route_get_log(router);
|
||||
|
||||
axum::serve(listener, router.with_state(server))
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::config::ConfigStructField;
|
||||
|
||||
#[derive(Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub enum Interface {
|
||||
Sub(HashMap<String, InterfaceWrapper>),
|
||||
Struct {
|
||||
fields: HashMap<String, ConfigStructField>,
|
||||
value: HashMap<String, Value>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub struct InterfaceWrapper {
|
||||
pub name: String,
|
||||
pub interface: Interface,
|
||||
}
|
||||
|
||||
impl InterfaceWrapper {
|
||||
pub fn get_path(&self, elements: &Vec<&str>, depth: usize) -> Result<InterfaceWrapper, String> {
|
||||
if depth == elements.len() {
|
||||
return Ok(self.clone());
|
||||
}
|
||||
|
||||
let element = elements[depth];
|
||||
|
||||
match &self.interface {
|
||||
Interface::Sub(interface_wrappers) => {
|
||||
if let Some(interface) = interface_wrappers.get(element) {
|
||||
interface.get_path(elements, depth)
|
||||
} else {
|
||||
Err("Invalid Path".into())
|
||||
}
|
||||
}
|
||||
|
||||
_ => Err("Invalid Path".into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_test_interface() -> InterfaceWrapper {
|
||||
InterfaceWrapper {
|
||||
name: "Root Interface".into(),
|
||||
interface: Interface::Sub(HashMap::new()),
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
mod blob;
|
||||
// pub mod interface;
|
||||
|
||||
pub use blob::Blob;
|
||||
// pub use interface::InterfaceWrapper;
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
@@ -37,7 +39,7 @@ struct BuildConfig {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||
enum ConfigStructField {
|
||||
pub enum ConfigStructField {
|
||||
Header(String),
|
||||
Text(String),
|
||||
String {
|
||||
|
||||
@@ -5,6 +5,7 @@ mod config;
|
||||
pub mod logger;
|
||||
mod modules;
|
||||
mod server;
|
||||
|
||||
pub use api::app::start_api;
|
||||
|
||||
pub use server::Server;
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
use std::{error::Error, path::PathBuf};
|
||||
|
||||
use crate::server::tree2::Tree2;
|
||||
|
||||
mod blobs;
|
||||
mod database;
|
||||
mod manager;
|
||||
mod tree2;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Server {
|
||||
pub component_configs: Vec<crate::config::ComponentState>,
|
||||
// pub interface: InterfaceWrapper,
|
||||
// pub manager: Arc<Mutex<Manager>>,
|
||||
pub db: sled::Db,
|
||||
pub tree: Tree2,
|
||||
}
|
||||
|
||||
impl Server {
|
||||
@@ -23,6 +27,8 @@ impl Server {
|
||||
component_configs,
|
||||
// manager: Manager::start(&SERVER_CONFIG, Vec::new()),
|
||||
db: sled::open(database)?,
|
||||
tree: Tree2::default(),
|
||||
// interface: get_test_interface(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use axum::{
|
||||
Extension, Json,
|
||||
extract::{Path, State},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use unshell_lib::debug;
|
||||
|
||||
use crate::{Server, api::CurrentUser};
|
||||
|
||||
#[derive(Clone)]
|
||||
enum Tree2Branch {
|
||||
File(String),
|
||||
Folder(String, HashMap<String, Tree2Branch>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
enum Tree2Repr {
|
||||
File(String),
|
||||
Folder(Vec<String>),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Tree2 {
|
||||
root: Tree2Branch,
|
||||
}
|
||||
|
||||
impl Tree2Branch {
|
||||
pub fn get_path(&self, elements: &Vec<&str>, depth: usize) -> Result<&Tree2Branch, String> {
|
||||
if depth == elements.len() {
|
||||
return Ok(self);
|
||||
}
|
||||
|
||||
let element = elements[depth];
|
||||
|
||||
if let Tree2Branch::Folder(_, hash_map) = self {
|
||||
if let Some(branch) = hash_map.get(element) {
|
||||
branch.get_path(elements, depth + 1)
|
||||
} else {
|
||||
Err("Invalid Path".into())
|
||||
}
|
||||
} else {
|
||||
return Err("This is a folder, not a file".into());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_repr(&self) -> Tree2Repr {
|
||||
match self {
|
||||
Tree2Branch::File(name) => Tree2Repr::File(name.clone()),
|
||||
Tree2Branch::Folder(_, hash_map) => {
|
||||
Tree2Repr::Folder(hash_map.keys().cloned().collect::<Vec<String>>())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Tree2 {
|
||||
fn get(&self, path: &str) -> Result<Tree2Repr, String> {
|
||||
let elements = if path.is_empty() {
|
||||
Vec::new()
|
||||
} else {
|
||||
path.split("/").collect::<Vec<&str>>()
|
||||
};
|
||||
|
||||
// let elements = path.split("/").collect::<Vec<&str>>();
|
||||
|
||||
let branch = self.root.get_path(&elements, 0)?;
|
||||
Ok(branch.to_repr())
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Tree2 {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
root: Tree2Branch::Folder(
|
||||
"ROOT".into(),
|
||||
HashMap::from([
|
||||
("File A".into(), Tree2Branch::File("A".into())),
|
||||
("File B".into(), Tree2Branch::File("B".into())),
|
||||
(
|
||||
"Folder C".into(),
|
||||
Tree2Branch::Folder(
|
||||
"A".into(),
|
||||
HashMap::from([
|
||||
("File A".into(), Tree2Branch::File("A".into())),
|
||||
("File B".into(), Tree2Branch::File("B".into())),
|
||||
]),
|
||||
),
|
||||
),
|
||||
]),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Server {
|
||||
pub async fn get_tree2(
|
||||
State(server): State<Server>,
|
||||
Path(path): Path<String>,
|
||||
Extension(_): Extension<CurrentUser>,
|
||||
) -> Json<Value> {
|
||||
debug!("GET /api/interface/{}", path);
|
||||
|
||||
let result = (|| -> Result<_, String> {
|
||||
let interface = server.tree.get(&path)?;
|
||||
|
||||
Ok(interface)
|
||||
})();
|
||||
|
||||
Json(serde_json::to_value(result).unwrap())
|
||||
}
|
||||
pub async fn get_tree2_root(
|
||||
State(server): State<Server>,
|
||||
Extension(extension): Extension<CurrentUser>,
|
||||
) -> Json<Value> {
|
||||
Self::get_tree2(State(server), Path("".into()), Extension(extension)).await
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user