From d7ec07cd0d713fc308e1004663b0053db8f00a0f Mon Sep 17 00:00:00 2001 From: Jeidnx Date: Mon, 2 Dec 2024 17:29:57 +0100 Subject: [PATCH] Implement a serializer for user preferences (#336) --- Cargo.lock | 13 +++++++++++ Cargo.toml | 1 + src/utils.rs | 49 ++++++++++++++++++++++++++++++++++++++--- templates/settings.html | 12 ++++++++-- 4 files changed, 70 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 057234fd..819d4bc6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1384,6 +1384,7 @@ dependencies = [ "serde", "serde_json", "serde_json_path", + "serde_urlencoded", "serde_yaml", "tegen", "time", @@ -1797,6 +1798,18 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "serde_yaml" version = "0.9.34+deprecated" diff --git a/Cargo.toml b/Cargo.toml index 616d8e9d..a1d3ec01 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,6 +50,7 @@ async-recursion = "1.1.1" common-words-all = { version = "0.0.2", default-features = false, features = ["english", "one"] } hyper-rustls = { version = "0.24.2", features = [ "http2" ] } tegen = "0.1.4" +serde_urlencoded = "0.7.1" [dev-dependencies] diff --git a/src/utils.rs b/src/utils.rs index 1edb5288..c15dceab 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -13,7 +13,7 @@ use once_cell::sync::Lazy; use regex::Regex; use rinja::Template; use rust_embed::RustEmbed; -use serde::Serialize; +use serde::{Serialize, Serializer}; use serde_json::Value; use serde_json_path::{JsonPath, JsonPathExt}; use std::collections::{HashMap, HashSet}; @@ -601,8 +601,9 @@ pub struct Params { pub before: Option, } -#[derive(Default)] +#[derive(Default, Serialize)] pub struct Preferences { + #[serde(skip)] pub available_themes: Vec, pub theme: String, pub front_page: String, @@ -620,12 +621,21 @@ pub struct Preferences { pub disable_visit_reddit_confirmation: String, pub comment_sort: String, pub post_sort: String, + #[serde(serialize_with = "serialize_vec_with_plus")] pub subscriptions: Vec, + #[serde(serialize_with = "serialize_vec_with_plus")] pub filters: Vec, pub hide_awards: String, pub hide_score: String, } +fn serialize_vec_with_plus(vec: &Vec, serializer: S) -> Result +where + S: Serializer, +{ + serializer.serialize_str(&vec.join("+")) +} + #[derive(RustEmbed)] #[folder = "static/themes/"] #[include = "*.css"] @@ -665,6 +675,10 @@ impl Preferences { hide_score: setting(req, "hide_score"), } } + + pub fn to_urlencoded(&self) -> Result { + serde_urlencoded::to_string(self).map_err(|e| e.to_string()) + } } /// Gets a `HashSet` of filters from the cookie in the given `Request`. @@ -1277,7 +1291,7 @@ pub fn get_post_url(post: &Post) -> String { #[cfg(test)] mod tests { - use super::{format_num, format_url, rewrite_urls}; + use super::{format_num, format_url, rewrite_urls, Preferences}; #[test] fn format_num_works() { @@ -1344,6 +1358,35 @@ mod tests { assert_eq!(format_url("nsfw"), ""); assert_eq!(format_url("spoiler"), ""); } + #[test] + fn serialize_prefs() { + let prefs = Preferences { + available_themes: vec![], + theme: "laserwave".to_owned(), + front_page: "default".to_owned(), + layout: "compact".to_owned(), + wide: "on".to_owned(), + blur_spoiler: "on".to_owned(), + show_nsfw: "off".to_owned(), + blur_nsfw: "on".to_owned(), + hide_hls_notification: "off".to_owned(), + video_quality: "best".to_owned(), + hide_sidebar_and_summary: "off".to_owned(), + use_hls: "on".to_owned(), + autoplay_videos: "on".to_owned(), + fixed_navbar: "on".to_owned(), + disable_visit_reddit_confirmation: "on".to_owned(), + comment_sort: "confidence".to_owned(), + post_sort: "top".to_owned(), + subscriptions: vec!["memes".to_owned(), "mildlyinteresting".to_owned()], + filters: vec![], + hide_awards: "off".to_owned(), + hide_score: "off".to_owned(), + }; + let urlencoded = serde_urlencoded::to_string(prefs).expect("Failed to serialize Prefs"); + + assert_eq!(urlencoded, "theme=laserwave&front_page=default&layout=compact&wide=on&blur_spoiler=on&show_nsfw=off&blur_nsfw=on&hide_hls_notification=off&video_quality=best&hide_sidebar_and_summary=off&use_hls=on&autoplay_videos=on&fixed_navbar=on&disable_visit_reddit_confirmation=on&comment_sort=confidence&post_sort=top&subscriptions=memes%2Bmildlyinteresting&filters=&hide_awards=off&hide_score=off") + } } #[test] diff --git a/templates/settings.html b/templates/settings.html index a7d66153..fef91cf3 100644 --- a/templates/settings.html +++ b/templates/settings.html @@ -161,8 +161,16 @@ {% endif %}
-

Note: settings and subscriptions are saved in browser cookies. Clearing your cookies will reset them.


-

You can restore your current settings and subscriptions after clearing your cookies using this link.

+

Note: settings and subscriptions are saved in browser cookies. Clearing your cookies will reset them.

+
+ {% match prefs.to_urlencoded() %} + {% when Ok with (encoded_prefs) %} +

You can restore your current settings and subscriptions after clearing your cookies using this link.

+ {% when Err with (err) %} +

There was an error creating your restore link: {{ err }}

+

Please report this issue

+ {% endmatch %}