better stuff :D

This commit is contained in:
Cadey Ratio 2020-07-31 13:38:33 -04:00
parent 9e217953b9
commit 687bece5be
5 changed files with 53 additions and 5 deletions

View File

@ -1,5 +1,12 @@
# Changelog # 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 ## 0.4.1
Oops Oops

View File

@ -35,7 +35,7 @@ struct Options {
key: PathBuf, key: PathBuf,
/// static path /// static path
#[structopt(short = "s", long, env = "STATIC_PATH")] #[structopt(short = "s", long, env = "STATIC_PATH", default_value = "./static")]
static_path: PathBuf, static_path: PathBuf,
/// server hostname /// server hostname
@ -121,13 +121,13 @@ async fn input(req: Request) -> Result<Response, Error> {
match req.url.query() { match req.url.query() {
None => Ok(Response::input("test")), None => Ok(Response::input("test")),
Some(q) => Ok({ Some(q) => Ok({
use maj::gemini::Node::*; use maj::gemini::Node::{self, *};
let result = vec![ let result = vec![
Heading { Heading {
level: 1, level: 1,
body: "Input test".to_string(), body: "Input test".to_string(),
}, },
Text("".to_string()), Node::blank(),
Text("You gave me:".to_string()), Text("You gave me:".to_string()),
Preformatted(format!("{}", percent_decode_str(q).decode_utf8()?)), Preformatted(format!("{}", percent_decode_str(q).decode_utf8()?)),
]; ];
@ -137,6 +137,21 @@ async fn input(req: Request) -> Result<Response, Error> {
} }
} }
async fn user(name: String) -> Result<Response, Error> {
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] #[async_trait::async_trait]
impl MajHandler for Handler { impl MajHandler for Handler {
async fn handle(&self, req: Request) -> Result<Response, Error> { async fn handle(&self, req: Request) -> Result<Response, Error> {
@ -156,9 +171,9 @@ impl MajHandler for Handler {
(/"cert") => need_cert(req).await; (/"cert") => need_cert(req).await;
(/"input") => input(req).await; (/"input") => input(req).await;
(/"majc") => majc().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
} }
} }

3
site/static/foo.gmi Normal file
View File

@ -0,0 +1,3 @@
# foo
Hahaha static serving works

View File

@ -156,6 +156,12 @@ pub enum Node {
Quote(String), Quote(String),
} }
impl Node {
pub fn blank() -> Node {
Node::Text("".to_string())
}
}
pub fn parse(doc: &str) -> Vec<Node> { pub fn parse(doc: &str) -> Vec<Node> {
let mut result: Vec<Node> = vec![]; let mut result: Vec<Node> = vec![];
let mut collect_preformatted: bool = false; let mut collect_preformatted: bool = false;

View File

@ -1,5 +1,6 @@
use crate::{gemini, StatusCode}; use crate::{gemini, StatusCode};
use num::FromPrimitive; use num::FromPrimitive;
use std::fmt;
use std::io::{self, prelude::*, ErrorKind}; use std::io::{self, prelude::*, ErrorKind};
/// A Gemini response as specified in [the spec](https://gemini.circumlunar.space/docs/specification.html). /// 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<u8>, pub body: Vec<u8>,
} }
#[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 { impl Response {
pub fn with_body(meta: String, body: Vec<u8>) -> Response { pub fn with_body(meta: String, body: Vec<u8>) -> Response {
Response { Response {