From 7ddb7eddec3b928947b52f715aaf4821a818ebee Mon Sep 17 00:00:00 2001 From: Vika Date: Thu, 7 Jul 2022 00:34:43 +0300 Subject: format using rustfmt --- kittybox-rs/src/frontend/mod.rs | 4 +- kittybox-rs/src/frontend/onboarding.rs | 99 +++++++++++----------- kittybox-rs/src/indieauth.rs | 9 +- kittybox-rs/src/main.rs | 10 ++- kittybox-rs/src/media/mod.rs | 10 +-- kittybox-rs/src/media/storage/file.rs | 14 ++- kittybox-rs/src/media/storage/mod.rs | 13 ++- kittybox-rs/src/metrics.rs | 2 +- kittybox-rs/src/micropub/mod.rs | 145 ++++++++++++++++++-------------- kittybox-rs/templates/src/lib.rs | 116 +++++++++++-------------- kittybox-rs/templates/src/onboarding.rs | 6 +- kittybox-rs/templates/src/templates.rs | 2 +- 12 files changed, 228 insertions(+), 202 deletions(-) (limited to 'kittybox-rs') diff --git a/kittybox-rs/src/frontend/mod.rs b/kittybox-rs/src/frontend/mod.rs index 51db2e1..bc9925f 100644 --- a/kittybox-rs/src/frontend/mod.rs +++ b/kittybox-rs/src/frontend/mod.rs @@ -12,9 +12,7 @@ use tracing::{debug, error}; //pub mod login; pub mod onboarding; -use kittybox_templates::{ - Entry, ErrorPage, Feed, MainPage, Template, VCard, POSTS_PER_PAGE, -}; +use kittybox_templates::{Entry, ErrorPage, Feed, MainPage, Template, VCard, POSTS_PER_PAGE}; pub use kittybox_util::IndiewebEndpoints; diff --git a/kittybox-rs/src/frontend/onboarding.rs b/kittybox-rs/src/frontend/onboarding.rs index 18def1d..9027201 100644 --- a/kittybox-rs/src/frontend/onboarding.rs +++ b/kittybox-rs/src/frontend/onboarding.rs @@ -1,25 +1,28 @@ -use kittybox_templates::{ErrorPage, Template, OnboardingPage}; -use crate::database::{Storage, Settings}; +use crate::database::{Settings, Storage}; use axum::{ - Json, - extract::{Host, Extension}, + extract::{Extension, Host}, http::StatusCode, response::{Html, IntoResponse}, + Json, }; +use kittybox_templates::{ErrorPage, OnboardingPage, Template}; use serde::Deserialize; use tracing::{debug, error}; use super::FrontendError; pub async fn get() -> Html { - Html(Template { - title: "Kittybox - Onboarding", - blog_name: "Kittybox", - feeds: vec![], - endpoints: None, - user: None, - content: OnboardingPage {}.to_string() - }.to_string()) + Html( + Template { + title: "Kittybox - Onboarding", + blog_name: "Kittybox", + feeds: vec![], + endpoints: None, + user: None, + content: OnboardingPage {}.to_string(), + } + .to_string(), + ) } #[derive(Deserialize, Debug)] @@ -45,21 +48,21 @@ impl OnboardingData { #[tracing::instrument(skip(db, http))] async fn onboard( - db: D, user_uid: url::Url, data: OnboardingData, http: reqwest::Client + db: D, + user_uid: url::Url, + data: OnboardingData, + http: reqwest::Client, ) -> Result<(), FrontendError> { // Create a user to pass to the backend // At this point the site belongs to nobody, so it is safe to do - let user = crate::indieauth::User::new( - user_uid.as_str(), - "https://kittybox.fireburn.ru/", - "create" - ); + let user = + crate::indieauth::User::new(user_uid.as_str(), "https://kittybox.fireburn.ru/", "create"); if data.user["type"][0] != "h-card" || data.first_post["type"][0] != "h-entry" { return Err(FrontendError::with_code( StatusCode::BAD_REQUEST, - "user and first_post should be an h-card and an h-entry" - )) + "user and first_post should be an h-card and an h-entry", + )); } db.set_setting(Settings::SiteName, user.me.as_str(), &data.blog_name) @@ -71,7 +74,9 @@ async fn onboard( hcard["properties"]["uid"] = serde_json::json!([&user_uid]); crate::micropub::normalize_mf2(hcard, &user) }; - db.put_post(&hcard, user_uid.as_str()).await.map_err(FrontendError::from)?; + db.put_post(&hcard, user_uid.as_str()) + .await + .map_err(FrontendError::from)?; debug!("Creating feeds..."); for feed in data.feeds { @@ -87,16 +92,18 @@ async fn onboard( &user, ); - db.put_post(&feed, user_uid.as_str()).await.map_err(FrontendError::from)?; + db.put_post(&feed, user_uid.as_str()) + .await + .map_err(FrontendError::from)?; } let (uid, post) = crate::micropub::normalize_mf2(data.first_post, &user); - crate::micropub::_post(user, uid, post, db, http).await.map_err(|e| { - FrontendError { + crate::micropub::_post(user, uid, post, db, http) + .await + .map_err(|e| FrontendError { msg: "Error while posting the first post".to_string(), source: Some(Box::new(e)), - code: StatusCode::INTERNAL_SERVER_ERROR - } - })?; + code: StatusCode::INTERNAL_SERVER_ERROR, + })?; Ok(()) } @@ -105,36 +112,34 @@ pub async fn post( Extension(db): Extension, Host(host): Host, Json(data): Json, - Extension(http): Extension + Extension(http): Extension, ) -> axum::response::Response { let user_uid = format!("https://{}/", host.as_str()); if db.post_exists(&user_uid).await.unwrap() { - IntoResponse::into_response(( - StatusCode::FOUND, - [("Location", "/")] - )) + IntoResponse::into_response((StatusCode::FOUND, [("Location", "/")])) } else { match onboard(db, user_uid.parse().unwrap(), data, http).await { - Ok(()) => IntoResponse::into_response(( - StatusCode::FOUND, - [("Location", "/")] - )), + Ok(()) => IntoResponse::into_response((StatusCode::FOUND, [("Location", "/")])), Err(err) => { error!("Onboarding error: {}", err); IntoResponse::into_response(( err.code(), - Html(Template { - title: "Kittybox - Onboarding", - blog_name: "Kittybox", - feeds: vec![], - endpoints: None, - user: None, - content: ErrorPage { - code: err.code(), - msg: Some(err.msg().to_string()), - }.to_string(), - }.to_string()) + Html( + Template { + title: "Kittybox - Onboarding", + blog_name: "Kittybox", + feeds: vec![], + endpoints: None, + user: None, + content: ErrorPage { + code: err.code(), + msg: Some(err.msg().to_string()), + } + .to_string(), + } + .to_string(), + ), )) } } diff --git a/kittybox-rs/src/indieauth.rs b/kittybox-rs/src/indieauth.rs index 63de859..103f514 100644 --- a/kittybox-rs/src/indieauth.rs +++ b/kittybox-rs/src/indieauth.rs @@ -151,7 +151,10 @@ where { type Rejection = IndieAuthError; - #[cfg_attr(all(debug_assertions, not(test)), allow(unreachable_code, unused_variables))] + #[cfg_attr( + all(debug_assertions, not(test)), + allow(unreachable_code, unused_variables) + )] async fn from_request(req: &mut RequestParts) -> Result { // Return a fake user if we're running a debug build // I don't wanna bother with authentication @@ -159,7 +162,7 @@ where return Ok(User::new( "http://localhost:8080/", "https://quill.p3k.io/", - "create update delete media" + "create update delete media", )); let TypedHeader(Authorization(token)) = @@ -232,7 +235,7 @@ mod tests { use super::User; use axum::{ extract::FromRequest, - http::{Method, Request} + http::{Method, Request}, }; use httpmock::prelude::*; diff --git a/kittybox-rs/src/main.rs b/kittybox-rs/src/main.rs index ef051ba..ece31df 100644 --- a/kittybox-rs/src/main.rs +++ b/kittybox-rs/src/main.rs @@ -197,15 +197,17 @@ async fn main() { .route( "/.kittybox/onboarding", axum::routing::get(kittybox::frontend::onboarding::get) - .post(kittybox::frontend::onboarding::post::) + .post(kittybox::frontend::onboarding::post::), ) .route( "/.kittybox/micropub", axum::routing::get(kittybox::micropub::query::) .post(kittybox::micropub::post::) - .layer(tower_http::cors::CorsLayer::new() - .allow_methods([axum::http::Method::GET, axum::http::Method::POST]) - .allow_origin(tower_http::cors::Any)), + .layer( + tower_http::cors::CorsLayer::new() + .allow_methods([axum::http::Method::GET, axum::http::Method::POST]) + .allow_origin(tower_http::cors::Any), + ), ) .route( "/.kittybox/micropub/client", diff --git a/kittybox-rs/src/media/mod.rs b/kittybox-rs/src/media/mod.rs index d18cf34..0d26f92 100644 --- a/kittybox-rs/src/media/mod.rs +++ b/kittybox-rs/src/media/mod.rs @@ -1,9 +1,9 @@ -use bytes::buf::Buf; -use futures_util::StreamExt; use axum::{ - extract::{Host, Extension, Multipart}, - response::{Response, IntoResponse, Json} + extract::{Extension, Host, Multipart}, + response::{IntoResponse, Json, Response}, }; +use bytes::buf::Buf; +use futures_util::StreamExt; pub mod storage; use storage::{MediaStore, MediaStoreError}; @@ -36,7 +36,7 @@ use storage::{MediaStore, MediaStoreError}; pub async fn upload( Host(host): Host, upload: Multipart, - Extension(db): Extension + Extension(db): Extension, ) -> Response { todo!() } diff --git a/kittybox-rs/src/media/storage/file.rs b/kittybox-rs/src/media/storage/file.rs index 8c0ddf0..ea1f010 100644 --- a/kittybox-rs/src/media/storage/file.rs +++ b/kittybox-rs/src/media/storage/file.rs @@ -22,16 +22,22 @@ impl From for MediaStoreError { #[async_trait] impl MediaStore for FileStore { async fn write_streaming( - &self, domain: url::Host, filename: &str, - content: axum::extract::multipart::Field<'_> + &self, + domain: url::Host, + filename: &str, + content: axum::extract::multipart::Field<'_>, ) -> Result<()> { todo!() } - async fn read_streaming(&self, domain: url::Host, filename: &str) -> Result>> { + async fn read_streaming( + &self, + domain: url::Host, + filename: &str, + ) -> Result>> { todo!() } - + async fn write(&self, domain: url::Host, filename: &str, content: &[u8]) -> Result<()> { let path = self.base.join(format!("{}/{}", domain, filename)); diff --git a/kittybox-rs/src/media/storage/mod.rs b/kittybox-rs/src/media/storage/mod.rs index e9b01f9..ba880ab 100644 --- a/kittybox-rs/src/media/storage/mod.rs +++ b/kittybox-rs/src/media/storage/mod.rs @@ -45,9 +45,18 @@ pub type Result = std::result::Result; #[async_trait] pub trait MediaStore: 'static + Send + Sync + Clone { - async fn write_streaming(&self, domain: url::Host, filename: &str, content: axum::extract::multipart::Field<'_>) -> Result<()>; + async fn write_streaming( + &self, + domain: url::Host, + filename: &str, + content: axum::extract::multipart::Field<'_>, + ) -> Result<()>; async fn write(&self, domain: url::Host, filename: &str, content: &[u8]) -> Result<()>; - async fn read_streaming(&self, domain: url::Host, filename: &str) -> Result>>; + async fn read_streaming( + &self, + domain: url::Host, + filename: &str, + ) -> Result>>; async fn read(&self, domain: url::Host, filename: &str) -> Result>; async fn delete(&self, domain: url::Host, filename: &str) -> Result<()>; } diff --git a/kittybox-rs/src/metrics.rs b/kittybox-rs/src/metrics.rs index 48f5d9b..e13fcb9 100644 --- a/kittybox-rs/src/metrics.rs +++ b/kittybox-rs/src/metrics.rs @@ -1,8 +1,8 @@ #![allow(unused_imports, dead_code)] use async_trait::async_trait; use lazy_static::lazy_static; -use std::time::{Duration, Instant}; use prometheus::Encoder; +use std::time::{Duration, Instant}; // TODO: Vendor in the Metrics struct from warp_prometheus and rework the path matching algorithm diff --git a/kittybox-rs/src/micropub/mod.rs b/kittybox-rs/src/micropub/mod.rs index d7be785..d8a84e6 100644 --- a/kittybox-rs/src/micropub/mod.rs +++ b/kittybox-rs/src/micropub/mod.rs @@ -1,15 +1,15 @@ use crate::database::{MicropubChannel, Storage, StorageError}; use crate::indieauth::User; use crate::micropub::util::form_to_mf2_json; -use axum::TypedHeader; use axum::extract::{BodyStream, Query}; use axum::headers::ContentType; use axum::response::{IntoResponse, Response}; +use axum::TypedHeader; use axum::{http::StatusCode, Extension}; -use tracing::{error, info, warn, debug}; use serde::{Deserialize, Serialize}; use serde_json::json; use std::fmt::Display; +use tracing::{debug, error, info, warn}; #[derive(Serialize, Deserialize, Debug, PartialEq)] #[serde(rename_all = "kebab-case")] @@ -91,7 +91,7 @@ impl axum::response::IntoResponse for MicropubError { fn into_response(self) -> axum::response::Response { axum::response::IntoResponse::into_response(( StatusCode::from(&self), - axum::response::Json(self) + axum::response::Json(self), )) } } @@ -374,11 +374,8 @@ pub(crate) async fn _post( } } - let reply = IntoResponse::into_response(( - StatusCode::ACCEPTED, - [("Location", uid.as_str())], - () - )); + let reply = + IntoResponse::into_response((StatusCode::ACCEPTED, [("Location", uid.as_str())], ())); tokio::task::spawn(background_processing(db, mf2, http)); @@ -486,11 +483,14 @@ async fn post_action( enum PostBody { Action(MicropubAction), - MF2(serde_json::Value) + MF2(serde_json::Value), } #[tracing::instrument] -async fn dispatch_body(mut body: BodyStream, content_type: ContentType) -> Result { +async fn dispatch_body( + mut body: BodyStream, + content_type: ContentType, +) -> Result { let body: Vec = { debug!("Buffering body..."); use tokio_stream::StreamExt; @@ -538,7 +538,7 @@ async fn dispatch_body(mut body: BodyStream, content_type: ContentType) -> Resul } else { Err(MicropubError::new( ErrorType::UnsupportedMediaType, - "This Content-Type is not recognized. Try application/json instead?" + "This Content-Type is not recognized. Try application/json instead?", )) } } @@ -549,28 +549,28 @@ pub async fn post( Extension(http): Extension, user: User, body: BodyStream, - TypedHeader(content_type): TypedHeader + TypedHeader(content_type): TypedHeader, ) -> axum::response::Response { match dispatch_body(body, content_type).await { Ok(PostBody::Action(action)) => match post_action(action, db, user).await { Ok(()) => Response::default(), - Err(err) => err.into_response() + Err(err) => err.into_response(), }, Ok(PostBody::MF2(mf2)) => { let (uid, mf2) = normalize_mf2(mf2, &user); match _post(user, uid, mf2, db, http).await { Ok(response) => response, - Err(err) => err.into_response() + Err(err) => err.into_response(), } - }, - Err(err) => err.into_response() + } + Err(err) => err.into_response(), } } pub async fn query( Extension(db): Extension, Query(query): Query, - user: User + user: User, ) -> axum::response::Response { let host = axum::http::Uri::try_from(user.me.as_str()) .unwrap() @@ -582,10 +582,13 @@ pub async fn query( QueryType::Config => { let channels: Vec = match db.get_channels(host.as_str()).await { Ok(chans) => chans, - Err(err) => return MicropubError::new( - ErrorType::InternalServerError, - &format!("Error fetching channels: {}", err) - ).into_response(), + Err(err) => { + return MicropubError::new( + ErrorType::InternalServerError, + &format!("Error fetching channels: {}", err), + ) + .into_response() + } }; axum::response::Json(json!({ @@ -598,50 +601,59 @@ pub async fn query( "channels": channels, "_kittybox_authority": host.as_str(), "syndicate-to": [] - })).into_response() - }, + })) + .into_response() + } QueryType::Source => { match query.url { Some(url) => { - if axum::http::Uri::try_from(&url).unwrap().authority().unwrap() != &host { + if axum::http::Uri::try_from(&url) + .unwrap() + .authority() + .unwrap() + != &host + { return MicropubError::new( ErrorType::NotAuthorized, - "You are requesting a post from a website that doesn't belong to you." - ).into_response() + "You are requesting a post from a website that doesn't belong to you.", + ) + .into_response(); } match db.get_post(&url).await { Ok(some) => match some { Some(post) => axum::response::Json(&post).into_response(), None => MicropubError::new( ErrorType::NotFound, - "The specified MF2 object was not found in database." - ).into_response() + "The specified MF2 object was not found in database.", + ) + .into_response(), }, Err(err) => MicropubError::new( ErrorType::InternalServerError, - &format!("Backend error: {}", err) - ).into_response() + &format!("Backend error: {}", err), + ) + .into_response(), } - }, + } None => { // Here, one should probably attempt to query at least the main feed and collect posts // Using a pre-made query function can't be done because it does unneeded filtering // Don't implement for now, this is optional MicropubError::new( ErrorType::InvalidRequest, - "Querying for post list is not implemented yet." - ).into_response() + "Querying for post list is not implemented yet.", + ) + .into_response() } } - }, - QueryType::Channel => { - match db.get_channels(host.as_str()).await { - Ok(chans) => axum::response::Json(json!({"channels": chans})).into_response(), - Err(err) => MicropubError::new( - ErrorType::InternalServerError, - &format!("Error fetching channels: {}", err) - ).into_response() - } + } + QueryType::Channel => match db.get_channels(host.as_str()).await { + Ok(chans) => axum::response::Json(json!({ "channels": chans })).into_response(), + Err(err) => MicropubError::new( + ErrorType::InternalServerError, + &format!("Error fetching channels: {}", err), + ) + .into_response(), }, QueryType::SyndicateTo => { axum::response::Json(json!({ "syndicate-to": [] })).into_response() @@ -725,16 +737,16 @@ mod tests { let user = crate::indieauth::User::new( "https://localhost:8080/", "https://kittybox.fireburn.ru/", - "profile" + "profile", ); let (uid, mf2) = super::normalize_mf2(post, &user); - - let err = super::_post( - user, uid, mf2, db.clone(), reqwest::Client::new() - ).await.unwrap_err(); + + let err = super::_post(user, uid, mf2, db.clone(), reqwest::Client::new()) + .await + .unwrap_err(); assert_eq!(err.error, super::ErrorType::InvalidScope); - + let hashmap = db.mapping.read().await; assert!(hashmap.is_empty()); } @@ -754,21 +766,20 @@ mod tests { let user = crate::indieauth::User::new( "https://aaronparecki.com/", "https://kittybox.fireburn.ru/", - "create update media" + "create update media", ); let (uid, mf2) = super::normalize_mf2(post, &user); - - let err = super::_post( - user, uid, mf2, db.clone(), reqwest::Client::new() - ).await.unwrap_err(); + + let err = super::_post(user, uid, mf2, db.clone(), reqwest::Client::new()) + .await + .unwrap_err(); assert_eq!(err.error, super::ErrorType::Forbidden); - + let hashmap = db.mapping.read().await; assert!(hashmap.is_empty()); } - #[tokio::test] async fn test_post_mf2() { let db = crate::database::MemoryStorage::new(); @@ -782,31 +793,37 @@ mod tests { let user = crate::indieauth::User::new( "https://localhost:8080/", "https://kittybox.fireburn.ru/", - "create" + "create", ); let (uid, mf2) = super::normalize_mf2(post, &user); - let res = super::_post( - user, uid, mf2, db.clone(), reqwest::Client::new() - ).await.unwrap(); + let res = super::_post(user, uid, mf2, db.clone(), reqwest::Client::new()) + .await + .unwrap(); assert!(res.headers().contains_key("Location")); let location = res.headers().get("Location").unwrap(); assert!(db.post_exists(location.to_str().unwrap()).await.unwrap()); - assert!(db.post_exists("https://localhost:8080/feeds/main").await.unwrap()); + assert!(db + .post_exists("https://localhost:8080/feeds/main") + .await + .unwrap()); } #[tokio::test] async fn test_query_foreign_url() { let mut res = super::query( axum::Extension(crate::database::MemoryStorage::new()), - axum::extract::Query(super::MicropubQuery::source("https://aaronparecki.com/feeds/main")), + axum::extract::Query(super::MicropubQuery::source( + "https://aaronparecki.com/feeds/main", + )), crate::indieauth::User::new( "https://fireburn.ru/", "https://quill.p3k.io/", - "create update media" - ) - ).await; + "create update media", + ), + ) + .await; assert_eq!(res.status(), 401); let body = res.body_mut().data().await.unwrap().unwrap(); diff --git a/kittybox-rs/templates/src/lib.rs b/kittybox-rs/templates/src/lib.rs index 39f1075..8e9abba 100644 --- a/kittybox-rs/templates/src/lib.rs +++ b/kittybox-rs/templates/src/lib.rs @@ -1,5 +1,5 @@ mod templates; -pub use templates::{ErrorPage, MainPage, Template, POSTS_PER_PAGE, Entry, VCard, Feed}; +pub use templates::{Entry, ErrorPage, Feed, MainPage, Template, VCard, POSTS_PER_PAGE}; mod onboarding; pub use onboarding::OnboardingPage; mod login; @@ -7,12 +7,12 @@ pub use login::LoginPage; #[cfg(test)] mod tests { + use faker_rand::en_us::internet::Domain; use faker_rand::lorem::Word; - use serde_json::json; use microformats::types::{Document, Item, PropertyValue, Url}; + use serde_json::json; use std::cell::RefCell; use std::rc::Rc; - use faker_rand::en_us::internet::Domain; enum PostType { Note, @@ -20,7 +20,7 @@ mod tests { ReplyTo(serde_json::Value), ReplyToLink(String), LikeOf(serde_json::Value), - LikeOfLink(String) + LikeOfLink(String), } fn gen_hcard(domain: &str) -> serde_json::Value { @@ -36,7 +36,7 @@ mod tests { } }) } - + fn gen_random_post(domain: &str, kind: PostType) -> serde_json::Value { use faker_rand::lorem::{Paragraph, Sentence}; @@ -46,13 +46,14 @@ mod tests { "value": content.to_string() }) } - + let uid = format!( "https://{domain}/posts/{}-{}-{}", - rand::random::(), rand::random::(), rand::random::() + rand::random::(), + rand::random::(), + rand::random::() ); - let dt = chrono::offset::Local::now() - .to_rfc3339_opts(chrono::SecondsFormat::Secs, true); + let dt = chrono::offset::Local::now().to_rfc3339_opts(chrono::SecondsFormat::Secs, true); match kind { PostType::Note => { @@ -99,7 +100,7 @@ mod tests { }] } }) - }, + } PostType::ReplyToLink(link) => { let content = rand::random::(); @@ -113,7 +114,7 @@ mod tests { "in-reply-to": [link] } }) - }, + } PostType::LikeOf(ctx) => { json!({ "type": ["h-entry"], @@ -127,7 +128,7 @@ mod tests { }] } }) - }, + } PostType::LikeOfLink(link) => { json!({ "type": ["h-entry"], @@ -142,20 +143,15 @@ mod tests { } } - fn check_dt_published( - mf2: &serde_json::Value, - item: &Rc> - ) { + fn check_dt_published(mf2: &serde_json::Value, item: &Rc>) { use microformats::types::temporal::Value as TemporalValue; let _item = item.borrow(); let props = _item.properties.borrow(); assert!(props.contains_key("published")); - if let Some(PropertyValue::Temporal( - TemporalValue::Timestamp(item) - )) = props.get("published") - .and_then(|v| v.first()) + if let Some(PropertyValue::Temporal(TemporalValue::Timestamp(item))) = + props.get("published").and_then(|v| v.first()) { use chrono::{DateTime, FixedOffset, NaiveDateTime}; @@ -171,8 +167,9 @@ mod tests { let dt = DateTime::::from_utc(ndt, offset); let expected: DateTime = chrono::DateTime::parse_from_rfc3339( - mf2["properties"]["published"][0].as_str().unwrap() - ).unwrap(); + mf2["properties"]["published"][0].as_str().unwrap(), + ) + .unwrap(); assert_eq!(dt, expected); } else { @@ -180,17 +177,12 @@ mod tests { } } - fn check_e_content( - mf2: &serde_json::Value, - item: &Rc> - ) { + fn check_e_content(mf2: &serde_json::Value, item: &Rc>) { let _item = item.borrow(); let props = _item.properties.borrow(); assert!(props.contains_key("content")); - if let Some(PropertyValue::Fragment(content)) = - props.get("content") - .and_then(|v| v.first()) + if let Some(PropertyValue::Fragment(content)) = props.get("content").and_then(|v| v.first()) { assert_eq!( content.html, @@ -199,7 +191,6 @@ mod tests { } else { unreachable!() } - } #[test] @@ -207,16 +198,12 @@ mod tests { fn test_note() { test_logger::ensure_env_logger_initialized(); - let mf2 = gen_random_post( - &rand::random::().to_string(), - PostType::Note - ); + let mf2 = gen_random_post(&rand::random::().to_string(), PostType::Note); - let html = crate::templates::Entry { - post: &mf2 - }.to_string(); + let html = crate::templates::Entry { post: &mf2 }.to_string(); - let url: Url = mf2.pointer("/properties/uid/0") + let url: Url = mf2 + .pointer("/properties/uid/0") .and_then(|i| i.as_str()) .and_then(|u| u.parse().ok()) .unwrap(); @@ -230,13 +217,13 @@ mod tests { check_dt_published(&mf2, &item); assert!(props.contains_key("uid")); assert!(props.contains_key("url")); - assert!(props.get("url") - .unwrap() - .iter() - .any(|i| i == props.get("uid").and_then(|v| v.first()).unwrap())); + assert!(props + .get("url") + .unwrap() + .iter() + .any(|i| i == props.get("uid").and_then(|v| v.first()).unwrap())); // XXX: fails because of https://gitlab.com/maxburon/microformats-parser/-/issues/7 assert!(!props.contains_key("name")); - } else { unreachable!() } @@ -246,14 +233,10 @@ mod tests { fn test_article() { test_logger::ensure_env_logger_initialized(); - let mf2 = gen_random_post( - &rand::random::().to_string(), - PostType::Article - ); - let html = crate::templates::Entry { - post: &mf2 - }.to_string(); - let url: Url = mf2.pointer("/properties/uid/0") + let mf2 = gen_random_post(&rand::random::().to_string(), PostType::Article); + let html = crate::templates::Entry { post: &mf2 }.to_string(); + let url: Url = mf2 + .pointer("/properties/uid/0") .and_then(|i| i.as_str()) .and_then(|u| u.parse().ok()) .unwrap(); @@ -267,10 +250,11 @@ mod tests { check_dt_published(&mf2, &item); assert!(props.contains_key("uid")); assert!(props.contains_key("url")); - assert!(props.get("url") - .unwrap() - .iter() - .any(|i| i == props.get("uid").and_then(|v| v.first()).unwrap())); + assert!(props + .get("url") + .unwrap() + .iter() + .any(|i| i == props.get("uid").and_then(|v| v.first()).unwrap())); assert!(props.contains_key("name")); if let Some(PropertyValue::Plain(name)) = props.get("name").and_then(|v| v.first()) { assert_eq!( @@ -294,7 +278,7 @@ mod tests { for likeof in [ PostType::LikeOf(gen_random_post( &rand::random::().to_string(), - PostType::Note + PostType::Note, )), PostType::LikeOfLink(format!( "https://{}/posts/{}-{}-{}", @@ -302,19 +286,15 @@ mod tests { &rand::random::(), &rand::random::(), &rand::random::(), - )) + )), ] { - let mf2 = gen_random_post( - &rand::random::().to_string(), - likeof - ); - let url: Url = mf2.pointer("/properties/uid/0") + let mf2 = gen_random_post(&rand::random::().to_string(), likeof); + let url: Url = mf2 + .pointer("/properties/uid/0") .and_then(|i| i.as_str()) .and_then(|u| u.parse().ok()) .unwrap(); - let html = crate::templates::Entry { - post: &mf2 - }.to_string(); + let html = crate::templates::Entry { post: &mf2 }.to_string(); let parsed: Document = microformats::from_html(&html, url.clone()).unwrap(); if let Some(item) = parsed.items.get(0) { @@ -329,7 +309,9 @@ mod tests { url, &mf2.pointer("/properties/like-of/0") .and_then(|i| i.as_str()) - .or_else(|| mf2.pointer("/properties/like-of/0/properties/uid/0").and_then(|i| i.as_str())) + .or_else(|| mf2 + .pointer("/properties/like-of/0/properties/uid/0") + .and_then(|i| i.as_str())) .and_then(|u| u.parse::().ok()) .unwrap() ); @@ -337,7 +319,7 @@ mod tests { Some(PropertyValue::Item(_cite)) => { todo!() } - other => panic!("Unexpected value in like-of: {:?}", other) + other => panic!("Unexpected value in like-of: {:?}", other), } } else { unreachable!() diff --git a/kittybox-rs/templates/src/onboarding.rs b/kittybox-rs/templates/src/onboarding.rs index 5a9f226..e2f07df 100644 --- a/kittybox-rs/templates/src/onboarding.rs +++ b/kittybox-rs/templates/src/onboarding.rs @@ -29,7 +29,11 @@ markup::define! { @markup::raw("") } hr; - p { "In other words: " b { "please enable JavaScript for this page to work properly." } small { "sorry T__T" } } + p { + "In other words: " + b { "please enable JavaScript for this page to work properly." } + small { "sorry T__T" } + } } ul #progressbar[style="display: none"] { li #intro { "Introduction" } diff --git a/kittybox-rs/templates/src/templates.rs b/kittybox-rs/templates/src/templates.rs index b084fbd..0b1db28 100644 --- a/kittybox-rs/templates/src/templates.rs +++ b/kittybox-rs/templates/src/templates.rs @@ -1,6 +1,6 @@ -use kittybox_util::{MicropubChannel, IndiewebEndpoints}; use ellipse::Ellipse; use http::StatusCode; +use kittybox_util::{IndiewebEndpoints, MicropubChannel}; use log::error; pub static POSTS_PER_PAGE: usize = 20; -- cgit 1.4.1