diff --git a/index.html b/index.html
index 6c81801..0ae1879 100644
--- a/index.html
+++ b/index.html
@@ -45,6 +45,8 @@ span {
+
@@ -52,6 +54,8 @@ span {
+
@@ -106,6 +111,7 @@ span {
+
diff --git a/src/data.rs b/src/data.rs
index b9fc07f..f13c41f 100644
--- a/src/data.rs
+++ b/src/data.rs
@@ -32,7 +32,7 @@ impl Data {
status_updated: Mutex::new((Instant::now(), false)),
}
}
- pub fn status_sync(&self, dbg: bool) -> MutexGuard {
+ pub fn status_sync(&'_ self, dbg: bool) -> MutexGuard<'_, Status> {
let mut updated = self.status_updated.blocking_lock();
let now = Instant::now();
if (now - updated.0).as_secs_f32() > 3.0 || (dbg && !updated.1) {
@@ -47,7 +47,7 @@ impl Data {
self.status.blocking_lock()
}
}
- pub async fn status_async(&self, dbg: bool) -> MutexGuard {
+ pub async fn status_async(&'_ self, dbg: bool) -> MutexGuard<'_, Status> {
let mut updated = self.status_updated.lock().await;
let now = Instant::now();
if (now - updated.0).as_secs_f32() > 3.0 || (dbg && !updated.1) {
diff --git a/src/main.rs b/src/main.rs
index b058f53..92a692f 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -26,7 +26,7 @@ async fn index_dbg(data: &State) -> RawHtml {
async fn index_gen(data: &State, dbg: bool) -> RawHtml {
let status = data.status_async(dbg).await;
- return RawHtml(data.index.gen(&status, dbg, data.globals.clone()));
+ RawHtml(data.index.gen(&status, dbg, data.globals.clone()))
}
#[get("/int")]
diff --git a/src/status.rs b/src/status.rs
index 29d4a5f..2d321a6 100644
--- a/src/status.rs
+++ b/src/status.rs
@@ -2,8 +2,8 @@ use std::{collections::BTreeMap, os::unix::fs::PermissionsExt, path::Path, time:
use tokio::time::Instant;
-const SLASHINFO: &'static str = "/srv/tomatenmhark-slashinfo/";
-const REDIRECT: &'static str = "/srv/tomatenmhark-redirect/";
+const SLASHINFO: &str = "/srv/tomatenmhark-slashinfo/";
+const REDIRECT: &str = "/srv/tomatenmhark-redirect/";
pub struct Status(
pub BTreeMap, Option)>,
@@ -40,36 +40,31 @@ impl Status {
);
let mut rest = BTreeMap::new();
if let Ok(rd) = std::fs::read_dir(SLASHINFO) {
- for f in rd {
- if let Ok(f) = f {
- if let Some(id) = f.file_name().to_str() {
- if !map.contains_key(id) {
- let mut p = f.path();
- p.push("desc");
- if let Ok(desc) = std::fs::read_to_string(&p) {
- let info = Path::new(SLASHINFO).join(id).join("index.html");
- let info = info.starts_with(SLASHINFO)
- && info.try_exists().ok() == Some(true);
- let redirect = Path::new(REDIRECT).join(id);
- let redirect = redirect.starts_with(REDIRECT)
- && redirect.try_exists().ok() == Some(true);
- let desc = desc.trim();
- if let Some(i) = desc.find('\n') {
- rest.insert(
- id.to_owned(),
- (
- info,
- redirect,
- desc[0..i].trim().to_owned(),
- Some(desc[i + 1..].trim().to_owned()),
- ),
- );
- } else {
- rest.insert(
- id.to_owned(),
- (info, redirect, desc.to_owned(), None),
- );
- }
+ for f in rd.filter_map(Result::ok) {
+ if let Some(id) = f.file_name().to_str() {
+ if !map.contains_key(id) {
+ let mut p = f.path();
+ p.push("desc");
+ if let Ok(desc) = std::fs::read_to_string(&p) {
+ let info = Path::new(SLASHINFO).join(id).join("index.html");
+ let info =
+ info.starts_with(SLASHINFO) && info.try_exists().ok() == Some(true);
+ let redirect = Path::new(REDIRECT).join(id);
+ let redirect = redirect.starts_with(REDIRECT)
+ && redirect.try_exists().ok() == Some(true);
+ let desc = desc.trim();
+ if let Some(i) = desc.find('\n') {
+ rest.insert(
+ id.to_owned(),
+ (
+ info,
+ redirect,
+ desc[0..i].trim().to_owned(),
+ Some(desc[i + 1..].trim().to_owned()),
+ ),
+ );
+ } else {
+ rest.insert(id.to_owned(), (info, redirect, desc.to_owned(), None));
}
}
}
@@ -143,26 +138,25 @@ impl Status {
fn query_status_sync(mut func: impl FnMut(&str, bool, bool, &str, Option), dbg: bool) {
if let Ok(rd) = std::fs::read_dir("/tmp/") {
- for f in rd {
- if let Ok(f) = f {
- if let Some(name) = f.file_name().to_str() {
- if name.starts_with("tomatenmhark-status-") {
- let id = name["tomatenmhark-status-".len()..].trim();
- if !id.is_empty() {
- if let Ok(status) = std::fs::read_to_string(f.path())
- .as_ref()
- .map(|v| v.trim_end())
- {
- if !status.is_empty() {
- let info = Path::new(SLASHINFO).join(id).join("index.html");
- let info = info.starts_with(SLASHINFO)
- && info.try_exists().ok() == Some(true);
- let redirect = Path::new(REDIRECT).join(id);
- let redirect = redirect.starts_with(REDIRECT)
- && redirect.try_exists().ok() == Some(true);
- func(id, info, redirect, status, None);
- }
- }
+ for f in rd.filter_map(Result::ok) {
+ if let Some(name) = f.file_name().to_str() {
+ if let Some(id) = name
+ .strip_prefix("tomatenmhark-status-")
+ .map(|v| v.trim())
+ .filter(|v| !v.is_empty())
+ {
+ if let Ok(status) = std::fs::read_to_string(f.path())
+ .as_ref()
+ .map(|v| v.trim_end())
+ {
+ if !status.is_empty() {
+ let info = Path::new(SLASHINFO).join(id).join("index.html");
+ let info =
+ info.starts_with(SLASHINFO) && info.try_exists().ok() == Some(true);
+ let redirect = Path::new(REDIRECT).join(id);
+ let redirect = redirect.starts_with(REDIRECT)
+ && redirect.try_exists().ok() == Some(true);
+ func(id, info, redirect, status, None);
}
}
}
@@ -170,28 +164,26 @@ fn query_status_sync(mut func: impl FnMut(&str, bool, bool, &str, Option),
+ IfEq(usize, usize, Templates, Option),
+ IfLine(usize, usize, Templates, Option),
For(Vec, Templates),
}
@@ -94,8 +96,8 @@ pub struct TemplateInfo {
last_end_was_else: Option,
}
-const COMMENT_START: &'static str = "";
+const COMMENT_START: &str = "";
impl Template {
pub fn parse(
mut src: &str,
@@ -137,13 +139,14 @@ impl Templates {
if let Some(comment_end) = src.find(COMMENT_END) {
// extract comment content
- let comment_og = src[..comment_end].trim();
- *src = &src[comment_end + COMMENT_END.len()..].trim_start_matches('\r');
+ let comment_og = src[..comment_end].trim_start();
+ *src = src[comment_end + COMMENT_END.len()..].trim_start_matches('\r');
*src = src.strip_prefix('\n').unwrap_or(src);
// do template things
let comment = comment_og.to_lowercase();
let mut comment = comment.split(char::is_whitespace);
- match comment.next().unwrap_or("") {
+ let comment_match = comment.next().unwrap_or("");
+ match comment_match {
"//" | "#" => {}
"end" => {
break 'parsing;
@@ -170,7 +173,8 @@ impl Templates {
let var_name = comment
.next()
.ok_or(TemplateParseError::MissingVariable("set"))?;
- let value = comment_og[3..].trim_start()[var_name.len()..].trim_start();
+ let value = &comment_og[3..].trim_start()[var_name.len()..];
+ let value = value.strip_prefix(char::is_whitespace).unwrap_or(value);
out.push(TemplateType::Set(info.var(var_name), value.to_owned()));
}
"concat" => {
@@ -187,22 +191,55 @@ impl Templates {
),
));
}
- "if" => {
+ "if" | "ifeq" | "ifline" => {
let prev_lewe = info.last_end_was_else;
info.last_end_was_else = Some(false);
- out.push(TemplateType::If(
- info.var(
- comment
- .next()
- .ok_or(TemplateParseError::MissingVariable("if"))?,
- ),
+ let (t_if, t_else) = (
Templates::parse(src, info)?,
if info.last_end_was_else.is_some_and(|v| v) {
Some(Templates::parse(src, info)?)
} else {
None
},
- ));
+ );
+ out.push(match comment_match {
+ "if" => TemplateType::If(
+ info.var(
+ comment
+ .next()
+ .ok_or(TemplateParseError::MissingVariable("if"))?,
+ ),
+ t_if,
+ t_else,
+ ),
+ "ifeq" => TemplateType::IfEq(
+ info.var(
+ comment
+ .next()
+ .ok_or(TemplateParseError::MissingVariable("ifeq"))?,
+ ),
+ info.var(
+ comment
+ .next()
+ .ok_or(TemplateParseError::MissingVariable("ifeq"))?,
+ ),
+ t_if,
+ t_else,
+ ),
+ "ifline" => {
+ TemplateType::IfLine(
+ info.var(comment.next().ok_or(
+ TemplateParseError::MissingVariable("ifline"),
+ )?),
+ info.var(comment.next().ok_or(
+ TemplateParseError::MissingVariable("ifline"),
+ )?),
+ t_if,
+ t_else,
+ )
+ }
+ _ => unreachable!(),
+ });
info.last_end_was_else = prev_lewe;
}
"for" => {
@@ -256,7 +293,7 @@ pub enum TemplateParseError {
impl Display for TemplateParseError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
- Self::UnclosedComment => write!(f, "There is an unclosed comment. Make sure all ``"),
+ Self::UnclosedComment => write!(f, "There is an unclosed comment. Make sure all ``"),
Self::InvalidTemplateKeyword(kw) => write!(f, "Invalid keyword `{kw}` after `