#![allow(mutable_transmutes)] use maud::{html, Markup, PreEscaped, DOCTYPE}; use regex::Regex; use std::mem::{take, transmute}; use worker::*; pub mod solar; use crate::solar::{dow, solar}; async fn text(r: &mut Response) -> Result { match r.body() { ResponseBody::Body(bytes) => unsafe { let bytes: &mut Vec = transmute(bytes); Ok(String::from_utf8_unchecked(take(bytes))) }, ResponseBody::Empty => Ok(String::new()), ResponseBody::Stream(_) => unsafe { let bytes = r.bytes().await?; Ok(String::from_utf8_unchecked(bytes)) }, } } #[event(fetch)] async fn fetch(req: Request, env: Env, _ctx: Context) -> Result { // wont let me use closures let re = |r: Request, _| Response::redirect(r.url()?.join("shitpit")?); let hm = |r: Request, _| Response::redirect(r.url()?.join("/")?); Router::new() .get("/journal", re) .get("/diary", re) .get("/index.html", hm) .get_async("/shitpit", |req, ctx| async move { let u = req.url()?; let a = ctx.env.assets("ASSETS")?; let mut a = a.fetch(u.join("_/diary")?, None).await?; let a = text(&mut a).await?; let re = Regex::new( r"(0[1-9]|[1-9]|1[0-2])\/(0[1-9]|[1-9]|1\d|2\d|3[01])\/(\d{2})$", ).unwrap(); bone("shitpit", "look in the sky! it's a bird! it's a plane! no it's superego!", html! { p { "The numbering system for people (#1, #2, ...) is arbitrary and " "the numbers do not denote interpersonal proximity." } p { "The Chinese characters next to Western dates (mm/dd/yy format) are " "traditional Chinese " a href="https://en.wikipedia.org/wiki/Sexagenary_cycle" { "Sexagenary cycle" } " dates." } pre { @for x in a.split('\n').map(|l| { let l = l.trim(); re.captures(l) .map_or_else(|| html! { (PreEscaped(l)) "\n" }, |c| { let (m, d, y) = (c.get(1), c.get(2), c.get(3)); let f = |x: Option| x.unwrap().as_str().parse().unwrap(); let (y, m, d): (usize, usize, usize) = (f(y) + 2000, f(m), f(d)); let s = solar(y, m, d); let (dowc, dowl) = dow(y, m, d); let (y, m, d, t) = (s.year, s.month, s.day, s.term); let href = l.replace('/', "_"); html! { (PreEscaped("")) a name=(href) { } a class="sec" href={"#" (href)} { (format!("{l} {dowl}. {y}年 {m}月 {d}日 ({dowc})")) @if let Some((t, _)) = t { " " (t) } } (PreEscaped("
"))
                            }
                        })
                    }) {
                        (x)
                    }
                }
            })
        })
        .get("/", |_, _| {
            bone("home", "ataxia.moe: like i heard a transmission from Apollo 13", html! {
                p style="padding: 1vw" {
                    "No. Stop." br; br; "Check out "
                    a href="/shitpit" { "the shitpit" }
                    " in the meantime."
                }
            })
        })
        .get("/about", |_, _| {
            bone("about", "And they completely goddamn disrespected me! Little idiots! Idiots!!", html! {
                p style="padding: 1vw" {
                    "Ataxia is a nervous system dysfunction consisting of poor coördination of muscle movements such as gait abnormalities, slurring of speech, and eye movement issues."
                    br; br;
                    "Hosted on "
                    a href="https://developers.cloudflare.com/workers/" { "Cloudflare Workers" }
                    ". Source available "
                    a href="https://git.neetlo.li/ataxia/tree" { "here" }
                    "."
                }
            })
        })
        .or_else_any_method("/*catchall" /* wtf is this syntax? */ , |_, _| {
            Ok(bone("", "404 Not Found", html! {
                p style="padding: 1vw" { "what?" }
            })?.with_status(404))
        })
        .run(req, env)
        .await
}

fn header() -> Markup {
    let css = r"/* i dont know css im so fucking sorry ill fix it l8r */
pre {
  white-space: pre-wrap;
  white-space: -moz-pre-wrap;
  white-space: -pre-wrap;
  white-space: -o-pre-wrap;
  word-wrap: break-word;
  font-family: serif;
}
.remark {
  box-sizing: content-box;
  border-top: 0px solid #000;
  border-left: 0px solid #000;
  border-right: 0px solid #000;
  border-bottom: 1px solid #000;
  padding: 1vw;
  padding-top: 0;
}
.nav {
  border-bottom: 1px solid #000;
  padding: 1vw;
  padding-top: 0;
}
main {
  border: 1px #000 solid;
}
body {
  background-color: #eee;
}

@media only screen and (min-width: 800px) {

  p, a.sec, pre {
    padding: 0 4vw;
    /*align: center;
    display:flex;
    align-items: center;
    justify-content: center;*/
  }
}
pre {
  font-size: 14pt;
}
a, p { font-size: 14pt; }
a.splink { color: #005953; font-size: inherit; }
a.sec, a.menu, a.menuon {
  color: #005953;
  font-family: 'Iansui', serif;
  font-size: 1.5em;
}
a.sec:link, a.sec:visited, a.sec:active {
   text-decoration: none;
}
a.sec:hover, a.sec:focus {
   text-decoration: underline;
}
a.menu:link, a.menu:visited, a.menu:active {
   text-decoration: none;
}
a.menu:hover, a.menu:focus {
   text-decoration: underline;
}
@media (prefers-color-scheme: dark) {
  body {
    background-color: #222;
    color: #dcdccc;
  }
  .nav, .remark {
    border-bottom: 1px solid #dcdccc;
  }
  main {
    border: 1px #dcdccc solid;
  }
  a.splink, a.sec, a.menu, a.menuon { color: #51bd96; }
}
@font-face {
  font-family: 'Iansui';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/_/iansui.woff2) format('woff2');
  unicode-range: U+3000-303F,U+3105-312F,U+4E00-9FFF;
}
body {
  max-width: 960px;
  margin-left: auto;
  margin-right: auto;
}";
    html! {
        (DOCTYPE)
        style { (PreEscaped(css)) }
        (PreEscaped(r#""#))
    }
}

fn menu(nav: &str) -> Markup {
    html! {
        div class="nav" {
            @let mut navs = [
                ("home", "/"),
                ("shitpit", "/shitpit"),
                ("about", "/about"),
            ].iter().peekable();
            @while let Some(&n) = navs.next() {
                a class=(if n.0 == nav { "menuon" } else { "menu" }) href=(n.1) {
                    (n.0)
                }
                @if navs.peek().is_some() {
                    " / "
                }
            }
        }
    }
}

fn bone(wh: &str, rm: &str, b: Markup) -> Result {
    Response::from_html(
        (html! {
            (header())
            main id="content" {
                h2 class="remark" { (rm) }
                (menu(wh))
                (b)
            }
        })
        .into_string(),
    )
}