2020-08-02 02:42:44 +00:00
|
|
|
use dnd_dice_roller::{dice::Dice, error::DiceError};
|
|
|
|
use maj::{
|
|
|
|
gemini::Builder,
|
|
|
|
route, seg,
|
|
|
|
server::{Error, Handler as MajHandler, Request},
|
|
|
|
split, Response,
|
|
|
|
};
|
|
|
|
use percent_encoding::percent_decode_str;
|
|
|
|
use std::str::FromStr;
|
|
|
|
|
2020-08-05 20:03:42 +00:00
|
|
|
mod tarot;
|
|
|
|
|
2020-08-02 02:42:44 +00:00
|
|
|
pub struct Handler {
|
|
|
|
pub hostname: String,
|
|
|
|
pub files: maj::server::files::Handler,
|
2020-08-08 15:23:36 +00:00
|
|
|
pub cgi: maj::server::cgi::Handler,
|
2020-08-02 02:42:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
async fn dice(req: Request) -> Result<Response, Error> {
|
|
|
|
fn dice_roll<T: Into<String>>(roll: T) -> Result<String, DiceError> {
|
|
|
|
let mut dice = Dice::from_str(&roll.into())?;
|
|
|
|
|
|
|
|
if dice.number_of_dice_to_roll > 100 {
|
|
|
|
dice.number_of_dice_to_roll = 100;
|
|
|
|
}
|
|
|
|
|
|
|
|
if dice.sides > 100 {
|
|
|
|
dice.sides = 100
|
|
|
|
}
|
|
|
|
|
|
|
|
if dice.sides == 0 {
|
|
|
|
dice.sides = 6;
|
|
|
|
}
|
|
|
|
|
|
|
|
let res = dice.roll_dice();
|
|
|
|
let reply = format!(
|
|
|
|
"{}{} = {}\n",
|
|
|
|
res.dice_results,
|
|
|
|
match dice.modifier {
|
|
|
|
Some(amt) => format!(" + {}", amt),
|
|
|
|
None => "".into(),
|
|
|
|
},
|
|
|
|
res.final_result[0]
|
|
|
|
);
|
|
|
|
Ok(reply)
|
|
|
|
}
|
|
|
|
|
|
|
|
match req.url.query() {
|
|
|
|
None => Ok(Response::input(
|
|
|
|
"What do you want to roll? [n]dn[+n] [adv|dadv]",
|
|
|
|
)),
|
|
|
|
Some(q) => Ok({
|
|
|
|
let dice = percent_decode_str(q).decode_utf8()?;
|
|
|
|
let b = Builder::new()
|
|
|
|
.heading(1, "Dice Results")
|
|
|
|
.text("")
|
|
|
|
.text(format!("You rolled {} and you got:", dice))
|
|
|
|
.text("")
|
|
|
|
.preformatted(format!("{}", dice_roll(dice)?))
|
|
|
|
.text("")
|
|
|
|
.link("/dice", Some("Do another roll".to_string()));
|
|
|
|
|
|
|
|
Response::render(b.build())
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[async_trait::async_trait]
|
|
|
|
impl MajHandler for Handler {
|
|
|
|
async fn handle(&self, req: Request) -> Result<Response, Error> {
|
|
|
|
if req.url.has_host() && req.url.host_str().unwrap().to_string() != self.hostname {
|
|
|
|
return Ok(Response::no_proxy());
|
|
|
|
}
|
|
|
|
|
|
|
|
if req.url.path() == "" {
|
|
|
|
return Ok(Response::perm_redirect(format!(
|
|
|
|
"gemini://{}/",
|
|
|
|
self.hostname
|
|
|
|
)));
|
|
|
|
}
|
|
|
|
|
|
|
|
route!(req.url.path(), {
|
|
|
|
(/"dice") => dice(req).await;
|
2020-08-05 20:03:42 +00:00
|
|
|
(/"tools"/"character_gen") => tarot::character().await;
|
2020-08-08 15:23:36 +00:00
|
|
|
(/"cgi-bin"[/rest..]) => self.cgi.handle(req).await;
|
2020-08-02 02:42:44 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
self.files.handle(req).await
|
|
|
|
}
|
|
|
|
}
|