diff options
author | Justin Wernick <j.wernick@eyeo.com> | 2021-06-23 15:16:40 +0200 |
---|---|---|
committer | Justin Wernick <j.wernick@eyeo.com> | 2021-06-23 15:16:40 +0200 |
commit | 2bd9413b8dd8d5420251a7f327bd5b233c2aca61 (patch) | |
tree | 28dbcef801eb620a29df3f0606a2189378b4bae4 | |
parent | 970d02c30aac7b98114a872e9d86cb3e24237cce (diff) |
Add structform to support growing form rapidly
-rw-r--r-- | Cargo.lock | 20 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/form.rs | 5 | ||||
-rw-r--r-- | src/lib.rs | 98 |
4 files changed, 71 insertions, 53 deletions
@@ -436,6 +436,7 @@ version = "0.1.0" dependencies = [ "lazy_static", "seed", + "structform", "syntect", "wasm-bindgen-test", ] @@ -786,6 +787,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" [[package]] +name = "structform" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd2bc770711b46281f9e9c5a6cba74774a1b4d7b83236c33af98e9391afa4682" +dependencies = [ + "structform-derive", +] + +[[package]] +name = "structform-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2e0c933d0bb83ceb050eb952e7cc1145c889667d6cb50b1a1924d30737e5709" +dependencies = [ + "quote", + "syn", +] + +[[package]] name = "syn" version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -15,6 +15,7 @@ wasm-bindgen-test = "0.3.18" seed = "0.8.0" syntect = { version = "4.5", default-features = false, features = ["default-fancy"], optional = true} lazy_static = "1.4.0" +structform = "0.1.0" [profile.release] lto = true diff --git a/src/form.rs b/src/form.rs new file mode 100644 index 0000000..00b5a58 --- /dev/null +++ b/src/form.rs @@ -0,0 +1,5 @@ +use structform::{derive_form_input, impl_text_input_with_stringops, ParseAndFormat}; + +derive_form_input! {FormTextInput} + +impl_text_input_with_stringops!(FormTextInput, String); @@ -1,53 +1,52 @@ -// (Lines like the one below ignore selected Clippy rules -// - it's useful when you want to check your code with `cargo make verify` -// but some rules are too "annoying" or are not applicable for your case.) #![allow(clippy::wildcard_imports)] +use crate::form::*; use seed::{prelude::*, *}; +use structform::StructForm; mod facebook; +mod form; -// ------ ------ -// Init -// ------ ------ - -// `init` describes what should happen when your app started. fn init(_: Url, _: &mut impl Orders<Msg>) -> Model { - Model { - url: String::default(), - } + Model::default() } -// ------ ------ -// Model -// ------ ------ - -// `Model` describes our app state. +#[derive(Default)] struct Model { + form: ShareLinksOptionsForm, + links: Option<Vec<Node<Msg>>>, +} + +#[derive(Default, Debug)] +struct ShareLinksOptions { url: String, } -// ------ ------ -// Update -// ------ ------ +#[derive(Default, StructForm)] +#[structform(model = "ShareLinksOptions")] +struct ShareLinksOptionsForm { + url: FormTextInput<String>, +} -#[derive(Clone)] -// `Msg` describes the different events you can modify state with. pub enum Msg { - SetUrl(String), + Input(ShareLinksOptionsFormField, String), } -// `update` describes how to handle each `Msg`. fn update(msg: Msg, model: &mut Model, _: &mut impl Orders<Msg>) { match msg { - Msg::SetUrl(url) => model.url = url, + Msg::Input(field, val) => { + model.form.set_input(field, val); + let parsed = model.form.submit(); + match parsed { + Err(_e) => { + model.links = None; + } + Ok(options) => model.links = Some(vec![facebook::link(&options.url)]), + } + } } } -// ------ ------ -// View -// ------ ------ - #[cfg(feature = "highlighting")] fn codify(node: &Node<Msg>) -> Node<Msg> { use lazy_static::lazy_static; @@ -75,14 +74,11 @@ fn codify(node: &Node<Msg>) -> Node<Msg> { } #[cfg(not(feature = "highlighting"))] -fn codify(node: &Node<Msg>) -> Node<Msg> { - pre![code![node.to_string()]] +fn codify(links: &[Node<Msg>]) -> Node<Msg> { + pre![code![links.iter().map(|link| format!("{}\n", link))]] } -// `view` describes what to display. fn view(model: &Model) -> Node<Msg> { - let facebook_link = facebook::link(&model.url); - div![ header![ h1!["🧄 Garlic Social Sharing 🧄"], @@ -90,7 +86,7 @@ fn view(model: &Model) -> Node<Msg> { ], p!["Social media sites are notorious for tracking people around the web. They can do this because web content creators let them."], p!["The default social media sharing links often include JavaScript or hotlinked images that will notify the social media site whenever someone visits your page, allowing the social media site to track them around the web. On the other hand, those social media sharing links make it convenient for people to share your content with their friends."], - p!["There is a better option. This site generates links that you can put into your site that do not allow social media companies to track your audience around the web, but still makes it easy for them to share."], + p!["There is a better option. This site generates links that you can put into your site that do not allow social media companies to track your audience around the web, but still makes it easy for them to share. The links are pure HTML."], h2!["Tell Me About Your Site"], form![ label![ @@ -102,32 +98,28 @@ fn view(model: &Model) -> Node<Msg> { input![ id!["url"], attrs! { - At::Value => model.url + At::Value => model.form.url.input }, - input_ev(Ev::Input, Msg::SetUrl) + input_ev(Ev::Input, |val| Msg::Input(ShareLinksOptionsFormField::Url, val) ) ] ], - h2!["Here's Your Social Sharing Links"], - div![ - C!["results-code"], - p!["Copy this code into your site to add your sharing buttons"], - codify(&facebook_link) - ], - div![ - C!["results-demo"], - p!["This is what it will look like"], - facebook_link - ] + model.links.as_ref().map(|links| nodes![ + h2!["Here's Your Social Sharing Links"], + div![ + C!["results-code"], + p!["Copy this code into your site to add your sharing buttons"], + codify(&links) + ], + div![ + C!["results-demo"], + p!["This is what it will look like"], + links.iter().map(|link| nodes![link.clone(), Node::new_text("\n")]) + ] + ]) ] } -// ------ ------ -// Start -// ------ ------ - -// (This function is invoked by `init` function in `index.html`.) #[wasm_bindgen(start)] pub fn start() { - // Mount the `app` to the element with the `id` "app". App::start("app", init, update, view); } |