diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f8fdff..2bcc08d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 0.5.0 + +### ADDED + +- A few more helper methods for making text/gemini nodes and responses. + `majsite` now serves static files and tests input from the user. + ## 0.4.1 Oops diff --git a/site/src/main.rs b/site/src/main.rs index dc2d35b..6c96a79 100644 --- a/site/src/main.rs +++ b/site/src/main.rs @@ -35,7 +35,7 @@ struct Options { key: PathBuf, /// static path - #[structopt(short = "s", long, env = "STATIC_PATH")] + #[structopt(short = "s", long, env = "STATIC_PATH", default_value = "./static")] static_path: PathBuf, /// server hostname @@ -121,13 +121,13 @@ async fn input(req: Request) -> Result { match req.url.query() { None => Ok(Response::input("test")), Some(q) => Ok({ - use maj::gemini::Node::*; + use maj::gemini::Node::{self, *}; let result = vec![ Heading { level: 1, body: "Input test".to_string(), }, - Text("".to_string()), + Node::blank(), Text("You gave me:".to_string()), Preformatted(format!("{}", percent_decode_str(q).decode_utf8()?)), ]; @@ -137,6 +137,21 @@ async fn input(req: Request) -> Result { } } +async fn user(name: String) -> Result { + Ok(Response::render({ + use maj::gemini::Node::{self, *}; + + vec![ + Heading { + level: 1, + body: format!("{}'s user page", name), + }, + Node::blank(), + Text(format!("this is a test page for {}", name)), + ] + })) +} + #[async_trait::async_trait] impl MajHandler for Handler { async fn handle(&self, req: Request) -> Result { @@ -156,9 +171,9 @@ impl MajHandler for Handler { (/"cert") => need_cert(req).await; (/"input") => input(req).await; (/"majc") => majc().await; - (/"static"[/rest..]) => self.files.handle(req).await; + (/"~"/[name: String][/rest..]) => user(name).await; }); - Ok(Response::not_found()) + self.files.handle(req).await } } diff --git a/site/static/foo.gmi b/site/static/foo.gmi new file mode 100644 index 0000000..8525bdf --- /dev/null +++ b/site/static/foo.gmi @@ -0,0 +1,3 @@ +# foo + +Hahaha static serving works diff --git a/src/gemini.rs b/src/gemini.rs index 3be2b5e..0225862 100644 --- a/src/gemini.rs +++ b/src/gemini.rs @@ -156,6 +156,12 @@ pub enum Node { Quote(String), } +impl Node { + pub fn blank() -> Node { + Node::Text("".to_string()) + } +} + pub fn parse(doc: &str) -> Vec { let mut result: Vec = vec![]; let mut collect_preformatted: bool = false; diff --git a/src/response.rs b/src/response.rs index dbc6d29..779400b 100644 --- a/src/response.rs +++ b/src/response.rs @@ -1,5 +1,6 @@ use crate::{gemini, StatusCode}; use num::FromPrimitive; +use std::fmt; use std::io::{self, prelude::*, ErrorKind}; /// A Gemini response as specified in [the spec](https://gemini.circumlunar.space/docs/specification.html). @@ -10,6 +11,22 @@ pub struct Response { pub body: Vec, } +#[derive(thiserror::Error, Debug)] +pub struct ResponseStatusError { + status: StatusCode, + meta: String, +} + +impl fmt::Display for ResponseStatusError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "{:?} ({}): {}", + self.status, self.status as u8, self.meta + ) + } +} + impl Response { pub fn with_body(meta: String, body: Vec) -> Response { Response {