diff options
Diffstat (limited to 'src/resources')
| -rw-r--r-- | src/resources/languages.rs | 134 | ||||
| -rw-r--r-- | src/resources/mod.rs | 8 | ||||
| -rw-r--r-- | src/resources/scripts.rs | 76 | ||||
| -rw-r--r-- | src/resources/style.rs | 108 | ||||
| -rw-r--r-- | src/resources/templates.rs | 202 |
5 files changed, 264 insertions, 264 deletions
diff --git a/src/resources/languages.rs b/src/resources/languages.rs index 8ef7553..b01daf9 100644 --- a/src/resources/languages.rs +++ b/src/resources/languages.rs @@ -1,67 +1,67 @@ -use std::collections::HashMap; -use std::path::PathBuf; - -use actix_web::{get, web, HttpResponse, Scope}; -use exun::RawUnexpected; -use ini::{Ini, Properties}; -use raise::yeet; -use unic_langid::subtags::Language; - -#[derive(Debug, Clone, PartialEq)] -pub struct Translations { - languages: HashMap<Language, Properties>, -} - -pub fn initialize() -> Result<Translations, RawUnexpected> { - let mut translations = Translations { - languages: HashMap::new(), - }; - translations.refresh()?; - Ok(translations) -} - -impl Translations { - pub fn languages(&self) -> Box<[Language]> { - self.languages.keys().cloned().collect() - } - - pub fn get_message(&self, language: Language, key: &str) -> Option<String> { - Some(self.languages.get(&language)?.get(key)?.to_owned()) - } - - pub fn refresh(&mut self) -> Result<(), RawUnexpected> { - let mut languages = HashMap::with_capacity(1); - for entry in PathBuf::from("static/languages").read_dir()? { - let entry = entry?; - if entry.file_type()?.is_dir() { - continue; - } - - let path = entry.path(); - let path = path.to_string_lossy(); - let Some(language) = path.as_bytes().get(0..2) else { yeet!(RawUnexpected::msg(format!("{} not long enough to be a language name", path))) }; - let language = Language::from_bytes(language)?; - let messages = Ini::load_from_file(entry.path())?.general_section().clone(); - - languages.insert(language, messages); - } - - self.languages = languages; - Ok(()) - } -} - -#[get("")] -pub async fn all_languages(translations: web::Data<Translations>) -> HttpResponse { - HttpResponse::Ok().json( - translations - .languages() - .into_iter() - .map(|l| l.as_str()) - .collect::<Box<[&str]>>(), - ) -} - -pub fn languages() -> Scope { - web::scope("/languages").service(all_languages) -} +use std::collections::HashMap;
+use std::path::PathBuf;
+
+use actix_web::{get, web, HttpResponse, Scope};
+use exun::RawUnexpected;
+use ini::{Ini, Properties};
+use raise::yeet;
+use unic_langid::subtags::Language;
+
+#[derive(Debug, Clone, PartialEq)]
+pub struct Translations {
+ languages: HashMap<Language, Properties>,
+}
+
+pub fn initialize() -> Result<Translations, RawUnexpected> {
+ let mut translations = Translations {
+ languages: HashMap::new(),
+ };
+ translations.refresh()?;
+ Ok(translations)
+}
+
+impl Translations {
+ pub fn languages(&self) -> Box<[Language]> {
+ self.languages.keys().cloned().collect()
+ }
+
+ pub fn get_message(&self, language: Language, key: &str) -> Option<String> {
+ Some(self.languages.get(&language)?.get(key)?.to_owned())
+ }
+
+ pub fn refresh(&mut self) -> Result<(), RawUnexpected> {
+ let mut languages = HashMap::with_capacity(1);
+ for entry in PathBuf::from("static/languages").read_dir()? {
+ let entry = entry?;
+ if entry.file_type()?.is_dir() {
+ continue;
+ }
+
+ let path = entry.path();
+ let path = path.to_string_lossy();
+ let Some(language) = path.as_bytes().get(0..2) else { yeet!(RawUnexpected::msg(format!("{} not long enough to be a language name", path))) };
+ let language = Language::from_bytes(language)?;
+ let messages = Ini::load_from_file(entry.path())?.general_section().clone();
+
+ languages.insert(language, messages);
+ }
+
+ self.languages = languages;
+ Ok(())
+ }
+}
+
+#[get("")]
+pub async fn all_languages(translations: web::Data<Translations>) -> HttpResponse {
+ HttpResponse::Ok().json(
+ translations
+ .languages()
+ .into_iter()
+ .map(|l| l.as_str())
+ .collect::<Box<[&str]>>(),
+ )
+}
+
+pub fn languages() -> Scope {
+ web::scope("/languages").service(all_languages)
+}
diff --git a/src/resources/mod.rs b/src/resources/mod.rs index 9251d2c..d9f14ba 100644 --- a/src/resources/mod.rs +++ b/src/resources/mod.rs @@ -1,4 +1,4 @@ -pub mod languages; -pub mod scripts; -pub mod style; -pub mod templates; +pub mod languages;
+pub mod scripts;
+pub mod style;
+pub mod templates;
diff --git a/src/resources/scripts.rs b/src/resources/scripts.rs index 1b27859..66b9693 100644 --- a/src/resources/scripts.rs +++ b/src/resources/scripts.rs @@ -1,38 +1,38 @@ -use std::path::Path; - -use actix_web::{get, http::StatusCode, web, HttpResponse, ResponseError}; -use exun::{Expect, ResultErrorExt}; -use path_clean::clean; -use raise::yeet; -use serde::Serialize; -use thiserror::Error; - -#[derive(Debug, Clone, Error, Serialize)] -pub enum LoadScriptError { - #[error("The requested script does not exist")] - FileNotFound(Box<Path>), -} - -impl ResponseError for LoadScriptError { - fn status_code(&self) -> StatusCode { - match self { - Self::FileNotFound(..) => StatusCode::NOT_FOUND, - } - } -} - -fn load(script: &str) -> Result<String, Expect<LoadScriptError>> { - let path = clean(format!("static/scripts/{}.js", script)); - if !path.exists() { - yeet!(LoadScriptError::FileNotFound(path.into()).into()); - } - let js = std::fs::read_to_string(format!("static/scripts/{}.js", script)).unexpect()?; - Ok(js) -} - -#[get("/{script}.js")] -pub async fn get_js(script: web::Path<Box<str>>) -> Result<HttpResponse, LoadScriptError> { - let js = load(&script).map_err(|e| e.unwrap())?; - let response = HttpResponse::Ok().content_type("text/javascript").body(js); - Ok(response) -} +use std::path::Path;
+
+use actix_web::{get, http::StatusCode, web, HttpResponse, ResponseError};
+use exun::{Expect, ResultErrorExt};
+use path_clean::clean;
+use raise::yeet;
+use serde::Serialize;
+use thiserror::Error;
+
+#[derive(Debug, Clone, Error, Serialize)]
+pub enum LoadScriptError {
+ #[error("The requested script does not exist")]
+ FileNotFound(Box<Path>),
+}
+
+impl ResponseError for LoadScriptError {
+ fn status_code(&self) -> StatusCode {
+ match self {
+ Self::FileNotFound(..) => StatusCode::NOT_FOUND,
+ }
+ }
+}
+
+fn load(script: &str) -> Result<String, Expect<LoadScriptError>> {
+ let path = clean(format!("static/scripts/{}.js", script));
+ if !path.exists() {
+ yeet!(LoadScriptError::FileNotFound(path.into()).into());
+ }
+ let js = std::fs::read_to_string(format!("static/scripts/{}.js", script)).unexpect()?;
+ Ok(js)
+}
+
+#[get("/{script}.js")]
+pub async fn get_js(script: web::Path<Box<str>>) -> Result<HttpResponse, LoadScriptError> {
+ let js = load(&script).map_err(|e| e.unwrap())?;
+ let response = HttpResponse::Ok().content_type("text/javascript").body(js);
+ Ok(response)
+}
diff --git a/src/resources/style.rs b/src/resources/style.rs index 3ea56d2..8b21dc4 100644 --- a/src/resources/style.rs +++ b/src/resources/style.rs @@ -1,54 +1,54 @@ -use std::path::Path; - -use actix_web::{get, http::StatusCode, web, HttpResponse, ResponseError}; -use exun::{Expect, ResultErrorExt}; -use grass::OutputStyle; -use path_clean::clean; -use raise::yeet; -use serde::Serialize; -use thiserror::Error; - -fn output_style() -> OutputStyle { - if cfg!(debug_assertions) { - OutputStyle::Expanded - } else { - OutputStyle::Compressed - } -} - -fn options() -> grass::Options<'static> { - grass::Options::default() - .load_path("static/style") - .style(output_style()) -} - -#[derive(Debug, Clone, Error, Serialize)] -pub enum LoadStyleError { - #[error("The requested stylesheet was not found")] - FileNotFound(Box<Path>), -} - -impl ResponseError for LoadStyleError { - fn status_code(&self) -> StatusCode { - match self { - Self::FileNotFound(..) => StatusCode::NOT_FOUND, - } - } -} - -pub fn load(stylesheet: &str) -> Result<String, Expect<LoadStyleError>> { - let options = options(); - let path = clean(format!("static/style/{}.scss", stylesheet)); - if !path.exists() { - yeet!(LoadStyleError::FileNotFound(path.into()).into()); - } - let css = grass::from_path(format!("static/style/{}.scss", stylesheet), &options).unexpect()?; - Ok(css) -} - -#[get("/{stylesheet}.css")] -pub async fn get_css(stylesheet: web::Path<Box<str>>) -> Result<HttpResponse, LoadStyleError> { - let css = load(&stylesheet).map_err(|e| e.unwrap())?; - let response = HttpResponse::Ok().content_type("text/css").body(css); - Ok(response) -} +use std::path::Path;
+
+use actix_web::{get, http::StatusCode, web, HttpResponse, ResponseError};
+use exun::{Expect, ResultErrorExt};
+use grass::OutputStyle;
+use path_clean::clean;
+use raise::yeet;
+use serde::Serialize;
+use thiserror::Error;
+
+fn output_style() -> OutputStyle {
+ if cfg!(debug_assertions) {
+ OutputStyle::Expanded
+ } else {
+ OutputStyle::Compressed
+ }
+}
+
+fn options() -> grass::Options<'static> {
+ grass::Options::default()
+ .load_path("static/style")
+ .style(output_style())
+}
+
+#[derive(Debug, Clone, Error, Serialize)]
+pub enum LoadStyleError {
+ #[error("The requested stylesheet was not found")]
+ FileNotFound(Box<Path>),
+}
+
+impl ResponseError for LoadStyleError {
+ fn status_code(&self) -> StatusCode {
+ match self {
+ Self::FileNotFound(..) => StatusCode::NOT_FOUND,
+ }
+ }
+}
+
+pub fn load(stylesheet: &str) -> Result<String, Expect<LoadStyleError>> {
+ let options = options();
+ let path = clean(format!("static/style/{}.scss", stylesheet));
+ if !path.exists() {
+ yeet!(LoadStyleError::FileNotFound(path.into()).into());
+ }
+ let css = grass::from_path(format!("static/style/{}.scss", stylesheet), &options).unexpect()?;
+ Ok(css)
+}
+
+#[get("/{stylesheet}.css")]
+pub async fn get_css(stylesheet: web::Path<Box<str>>) -> Result<HttpResponse, LoadStyleError> {
+ let css = load(&stylesheet).map_err(|e| e.unwrap())?;
+ let response = HttpResponse::Ok().content_type("text/css").body(css);
+ Ok(response)
+}
diff --git a/src/resources/templates.rs b/src/resources/templates.rs index 9168fb9..baf2ee8 100644 --- a/src/resources/templates.rs +++ b/src/resources/templates.rs @@ -1,101 +1,101 @@ -use std::collections::HashMap; - -use exun::{RawUnexpected, ResultErrorExt}; -use raise::yeet; -use serde::Serialize; -use tera::{Function, Tera, Value}; -use unic_langid::subtags::Language; - -use crate::api::AuthorizationParameters; - -use super::languages; - -fn make_msg(language: Language, translations: languages::Translations) -> impl Function { - Box::new( - move |args: &HashMap<String, Value>| -> tera::Result<Value> { - let Some(key) = args.get("key") else { yeet!("No parameter 'key' provided".into()) }; - let Some(key) = key.as_str() else { yeet!(format!("{} is not a string", key).into()) }; - let Some(value) = translations.get_message(language, key) else { yeet!(format!("{} does not exist", key).into()) }; - Ok(Value::String(value)) - }, - ) -} - -fn extend_tera( - tera: &Tera, - language: Language, - translations: languages::Translations, -) -> Result<Tera, RawUnexpected> { - let mut new_tera = initialize()?; - new_tera.extend(tera)?; - new_tera.register_function("msg", make_msg(language, translations)); - Ok(new_tera) -} - -pub fn initialize() -> tera::Result<Tera> { - let tera = Tera::new("static/templates/*")?; - Ok(tera) -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)] -#[serde(rename_all = "camelCase")] -pub enum ErrorPage { - InvalidRequest, - ClientNotFound, - MissingRedirectUri, - InvalidRedirectUri, - InternalServerError, -} - -pub fn error_page( - tera: &Tera, - language: Language, - mut translations: languages::Translations, - error: ErrorPage, -) -> Result<String, RawUnexpected> { - translations.refresh()?; - let mut tera = extend_tera(tera, language, translations)?; - tera.full_reload()?; - - let error = serde_variant::to_variant_name(&error)?; - let header = format!("errorHeader_{error}"); - let message = format!("errorMessage_{error}"); - - let mut context = tera::Context::new(); - context.insert("lang", language.as_str()); - context.insert("errorHeader", &header); - context.insert("errormessage", &message); - - tera.render("error.html", &context).unexpect() -} - -pub fn login_page( - tera: &Tera, - params: &AuthorizationParameters, - language: Language, - mut translations: languages::Translations, -) -> Result<String, RawUnexpected> { - translations.refresh()?; - let mut tera = extend_tera(tera, language, translations)?; - tera.full_reload()?; - let mut context = tera::Context::new(); - context.insert("lang", language.as_str()); - context.insert("params", &serde_urlencoded::to_string(params)?); - tera.render("login.html", &context).unexpect() -} - -pub fn login_error_page( - tera: &Tera, - params: &AuthorizationParameters, - language: Language, - mut translations: languages::Translations, -) -> Result<String, RawUnexpected> { - translations.refresh()?; - let mut tera = extend_tera(tera, language, translations)?; - tera.full_reload()?; - let mut context = tera::Context::new(); - context.insert("lang", language.as_str()); - context.insert("params", &serde_urlencoded::to_string(params)?); - context.insert("errorMessage", "loginErrorMessage"); - tera.render("login.html", &context).unexpect() -} +use std::collections::HashMap;
+
+use exun::{RawUnexpected, ResultErrorExt};
+use raise::yeet;
+use serde::Serialize;
+use tera::{Function, Tera, Value};
+use unic_langid::subtags::Language;
+
+use crate::api::AuthorizationParameters;
+
+use super::languages;
+
+fn make_msg(language: Language, translations: languages::Translations) -> impl Function {
+ Box::new(
+ move |args: &HashMap<String, Value>| -> tera::Result<Value> {
+ let Some(key) = args.get("key") else { yeet!("No parameter 'key' provided".into()) };
+ let Some(key) = key.as_str() else { yeet!(format!("{} is not a string", key).into()) };
+ let Some(value) = translations.get_message(language, key) else { yeet!(format!("{} does not exist", key).into()) };
+ Ok(Value::String(value))
+ },
+ )
+}
+
+fn extend_tera(
+ tera: &Tera,
+ language: Language,
+ translations: languages::Translations,
+) -> Result<Tera, RawUnexpected> {
+ let mut new_tera = initialize()?;
+ new_tera.extend(tera)?;
+ new_tera.register_function("msg", make_msg(language, translations));
+ Ok(new_tera)
+}
+
+pub fn initialize() -> tera::Result<Tera> {
+ let tera = Tera::new("static/templates/*")?;
+ Ok(tera)
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub enum ErrorPage {
+ InvalidRequest,
+ ClientNotFound,
+ MissingRedirectUri,
+ InvalidRedirectUri,
+ InternalServerError,
+}
+
+pub fn error_page(
+ tera: &Tera,
+ language: Language,
+ mut translations: languages::Translations,
+ error: ErrorPage,
+) -> Result<String, RawUnexpected> {
+ translations.refresh()?;
+ let mut tera = extend_tera(tera, language, translations)?;
+ tera.full_reload()?;
+
+ let error = serde_variant::to_variant_name(&error)?;
+ let header = format!("errorHeader_{error}");
+ let message = format!("errorMessage_{error}");
+
+ let mut context = tera::Context::new();
+ context.insert("lang", language.as_str());
+ context.insert("errorHeader", &header);
+ context.insert("errormessage", &message);
+
+ tera.render("error.html", &context).unexpect()
+}
+
+pub fn login_page(
+ tera: &Tera,
+ params: &AuthorizationParameters,
+ language: Language,
+ mut translations: languages::Translations,
+) -> Result<String, RawUnexpected> {
+ translations.refresh()?;
+ let mut tera = extend_tera(tera, language, translations)?;
+ tera.full_reload()?;
+ let mut context = tera::Context::new();
+ context.insert("lang", language.as_str());
+ context.insert("params", &serde_urlencoded::to_string(params)?);
+ tera.render("login.html", &context).unexpect()
+}
+
+pub fn login_error_page(
+ tera: &Tera,
+ params: &AuthorizationParameters,
+ language: Language,
+ mut translations: languages::Translations,
+) -> Result<String, RawUnexpected> {
+ translations.refresh()?;
+ let mut tera = extend_tera(tera, language, translations)?;
+ tera.full_reload()?;
+ let mut context = tera::Context::new();
+ context.insert("lang", language.as_str());
+ context.insert("params", &serde_urlencoded::to_string(params)?);
+ context.insert("errorMessage", "loginErrorMessage");
+ tera.render("login.html", &context).unexpect()
+}
|
