summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Wernick <j.wernick@eyeo.com>2021-06-23 15:16:40 +0200
committerJustin Wernick <j.wernick@eyeo.com>2021-06-23 15:16:40 +0200
commit2bd9413b8dd8d5420251a7f327bd5b233c2aca61 (patch)
tree28dbcef801eb620a29df3f0606a2189378b4bae4
parent970d02c30aac7b98114a872e9d86cb3e24237cce (diff)
Add structform to support growing form rapidly
-rw-r--r--Cargo.lock20
-rw-r--r--Cargo.toml1
-rw-r--r--src/form.rs5
-rw-r--r--src/lib.rs98
4 files changed, 71 insertions, 53 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 453b965..31b0a67 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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"
diff --git a/Cargo.toml b/Cargo.toml
index 4e4db0d..995712a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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);
diff --git a/src/lib.rs b/src/lib.rs
index 9424c78..ccdb0d1 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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);
}