resource mechanism
This commit is contained in:
parent
11543af683
commit
56cf9061f0
|
@ -37,6 +37,15 @@ dependencies = [
|
|||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "android-tzdata"
|
||||
version = "0.1.1"
|
||||
|
@ -375,6 +384,7 @@ dependencies = [
|
|||
"num",
|
||||
"rand",
|
||||
"redis",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
|
@ -941,7 +951,7 @@ version = "0.17.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ec3b11d443640ec35165ee8f6f0559f1c6f41878d70330fe9187012b5935f02"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"aho-corasick 0.7.20",
|
||||
"bumpalo",
|
||||
"hashbrown 0.13.2",
|
||||
"lazy_static",
|
||||
|
@ -1078,6 +1088,35 @@ dependencies = [
|
|||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
|
||||
dependencies = [
|
||||
"aho-corasick 1.1.2",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
|
||||
dependencies = [
|
||||
"aho-corasick 1.1.2",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
||||
|
||||
[[package]]
|
||||
name = "rfc7239"
|
||||
version = "0.1.0"
|
||||
|
|
|
@ -19,6 +19,7 @@ log = "0.4.20"
|
|||
num = { version = "0.4.1", features = ["serde"] }
|
||||
rand = "0.8.5"
|
||||
redis = { version = "0.23.3", features = ["tokio", "tokio-comp"] }
|
||||
regex = "1.10.2"
|
||||
serde = { version = "1.0.188", features = ["derive"] }
|
||||
serde_json = "1.0.107"
|
||||
sha2 = "0.10.8"
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
pub mod types;
|
||||
pub mod resource;
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
pub mod types;
|
|
@ -0,0 +1,80 @@
|
|||
use regex::Regex;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use std::{error::Error, fs, collections::HashMap, path::Path};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ResourceCollection(HashMap<String, Resource>);
|
||||
|
||||
impl ResourceCollection {
|
||||
pub fn validate(self: &Self) -> Result<(), String> {
|
||||
for (name, resource) in self.0.iter() {
|
||||
resource.validate(Some(name.clone()))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn init(self: &mut Self) -> Result<(), String> {
|
||||
for (name, resource) in self.0.iter_mut() {
|
||||
resource.init(Some(name.clone()))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Resource {
|
||||
pub path: String,
|
||||
pub mime: String,
|
||||
cached_data: Option<Vec<u8>>
|
||||
}
|
||||
|
||||
impl Resource {
|
||||
|
||||
pub fn init(self: &mut Self, name: Option<String>) -> Result<(), String> {
|
||||
if self.cached_data.is_none() {
|
||||
self.read_to_cache().map_err(|x|
|
||||
if let Some(name) = name {
|
||||
format!("Error while initalizing resource {name}: {:?}", x)
|
||||
} else {
|
||||
format!("Error while initalizing unknown resource: {:?}", x)
|
||||
}
|
||||
)?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn validate(self: &Self, name: Option<String>) -> Result<(), String> {
|
||||
// dont catch this panic
|
||||
let re = Regex::new(r"^[a-z][a-z0-9_]*(\.[a-z0-9_]+)+[0-9a-z_]$").unwrap();
|
||||
|
||||
if let Some(name) = name.clone() {
|
||||
if ! re.is_match(name.as_str()) {
|
||||
return Err(format!("Invalid resource name: {name}"));
|
||||
}
|
||||
}
|
||||
|
||||
let path = Path::new(&self.path);
|
||||
if ! path.is_file() {
|
||||
if let Some(name) = name {
|
||||
return Err(format!("Resource {name} is not a file!"));
|
||||
} else {
|
||||
return Err(format!("A resource with path {} is not a file!", self.path));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_to_cache(self: &mut Self) -> Result<(), Box<dyn Error>> {
|
||||
let data = fs::read(self.path.clone())?;
|
||||
self.cached_data = Some(data);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get(self: &mut Self) -> Result<Vec<u8>, Box<dyn Error>> {
|
||||
if let Some(cached) = self.cached_data.clone() {
|
||||
Ok(cached)
|
||||
} else {
|
||||
Ok(fs::read(self.path.clone())?)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,6 +3,8 @@ use std::{error::Error, fs, path::Path};
|
|||
|
||||
use crate::env::Env;
|
||||
|
||||
use super::resource;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct FilesPolicy {
|
||||
/// Whether the uploads are enabled
|
||||
|
@ -167,7 +169,8 @@ impl APISettings {
|
|||
pub struct Config {
|
||||
pub files: FilesPolicy,
|
||||
pub brand: Branding,
|
||||
pub api: APISettings
|
||||
pub api: APISettings,
|
||||
pub resources: Option<resource::types::ResourceCollection>
|
||||
}
|
||||
|
||||
impl Config {
|
||||
|
@ -176,14 +179,26 @@ impl Config {
|
|||
self.files.validate()?;
|
||||
self.brand.validate()?;
|
||||
self.api .validate()?;
|
||||
if let Some(resources) = self.resources.clone() {
|
||||
resources.validate()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn init(self: &mut Self) -> Result<(), String> {
|
||||
if let Some(ref mut resources) = self.resources {
|
||||
resources.init()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn load(env: Env) -> Result<Config, Box<dyn Error>> {
|
||||
let raw = fs::read_to_string(env.confpath.clone())?;
|
||||
let conf: Config = toml::from_str(&raw)?;
|
||||
let mut conf: Config = toml::from_str(&raw)?;
|
||||
conf.validate()?;
|
||||
conf.init()?;
|
||||
|
||||
Ok(conf)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue