Implementing traits for accepting actual gemention requests

This commit is contained in:
projectmoon 2024-03-29 20:37:19 +01:00
parent 4a6379b9fa
commit d34ca875ab
8 changed files with 67 additions and 1 deletions

1
Cargo.lock generated
View File

@ -189,6 +189,7 @@ name = "gemention"
version = "0.1.0"
dependencies = [
"anyhow",
"async-trait",
"fluffer",
"germ",
"thiserror",

View File

@ -7,6 +7,7 @@ edition = "2021"
[dependencies]
anyhow = "1.0.81"
async-trait = "0.1.79"
fluffer = "4"
germ = "0.4"
thiserror = "1.0.58"

View File

@ -5,6 +5,7 @@ use fluffer::Client;
// - Make Gemini request to see if target page supports gemention.
// - If so, store mention in DB.
pub(crate) async fn receive_mention(client: Client) -> String {
// TODO change to return MentionResponse or something like that.
let titan = match client.titan {
Some(ref titan) => titan,
_ => return "".to_string(),

View File

@ -1,3 +1,5 @@
use std::str::Utf8Error;
use thiserror::Error;
#[derive(Error, Debug)]
@ -8,6 +10,9 @@ pub(crate) enum GementionError {
#[error("url parsing error: {0}")]
UrlParsingError(#[from] url::ParseError),
#[error("value was not utf8: {0}")]
Utf8Error(#[from] Utf8Error),
#[error("generic error: {0}")]
UnclassifiedError(#[from] anyhow::Error),
}

56
src/models/mentions.rs Normal file
View File

@ -0,0 +1,56 @@
use async_trait::async_trait;
use fluffer::GemBytes;
use std::fmt::Display;
use crate::error::GementionError;
pub(crate) enum MentionType {
Reply,
Like,
}
pub(crate) struct Mention {
mention_type: MentionType,
user: String,
content: Option<String>,
}
// This is for converting an incoming Titan request into a mention. It
// is very flexible: If the incoming value matches a specific format,
// it'll accurately convert the stringi nto a proper mention.
// Otherwise, it just assumes comment. An error is returned only if
// input is not utf8.
impl TryFrom<Vec<u8>> for Mention {
type Error = GementionError;
fn try_from(content: Vec<u8>) -> Result<Self, Self::Error> {
let content = std::str::from_utf8(&content)?;
Ok(Mention {
mention_type: MentionType::Reply,
user: "".to_string(),
content: None,
})
}
}
impl Display for MentionType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Reply => write!(f, "Reply"),
Self::Like => write!(f, "Like"),
}
}
}
#[async_trait]
impl GemBytes for Mention {
async fn gem_bytes(self) -> Vec<u8> {
// TODO change output based on mention type:
// Reply/comment = current format.
// Like = "<user> liked this"
let headline = format!("## {} from {}", self.mention_type, self.user);
let content = self.content.unwrap_or(String::from("[no content]"));
format!("20 text/gemini\r\n{}\n\n{}", headline, content).into_bytes()
}
}

2
src/models/mod.rs Normal file
View File

@ -0,0 +1,2 @@
pub(crate) mod verification;
pub(crate) mod mentions;

View File

@ -4,7 +4,7 @@ use germ::request::request as germ_request;
use url::Url;
use crate::error::GementionError;
use crate::models::*;
use crate::models::verification::*;
const OUR_ENDPOINT: &'static str = "titan://localhost/receive/";