From d54ec57192b191cabb6f8ca138c369788fccaeb2 Mon Sep 17 00:00:00 2001 From: Bunny Bites Date: Sun, 5 Nov 2023 08:16:09 +0530 Subject: [PATCH] 1. migrated code to form.rs 2. made get_parsed_values as private fn. 3. handled multi-valued data while parsing --- packages/html/src/events/form.rs | 55 ++++++++++++++++++++++++++++++-- packages/rink/src/hooks.rs | 23 ------------- 2 files changed, 53 insertions(+), 25 deletions(-) diff --git a/packages/html/src/events/form.rs b/packages/html/src/events/form.rs index fab13482b..e3b35b098 100644 --- a/packages/html/src/events/form.rs +++ b/packages/html/src/events/form.rs @@ -1,9 +1,16 @@ use std::{any::Any, collections::HashMap, fmt::Debug}; use dioxus_core::Event; +use serde::{Deserialize, Serialize}; pub type FormEvent = Event; +#[derive(Serialize, Deserialize)] +enum ValueType { + Text(String), + VecText(Vec), +} + /* DOMEvent: Send + SyncTarget relatedTarget */ #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone)] @@ -23,6 +30,52 @@ pub struct FormData { pub files: Option>, } +impl FormData { + // ***** function to parse the 'values' to make it ready to use******* + // e.g - self.values = { username: ["rust"], password: ["dioxus"]} + // what we need it to be: { username: "rust", password: "dioxus"} + fn get_parsed_values(&self) -> Option> { + if self.values.is_empty() { + return None; + } + + let raw_values = self.values.clone(); + + let mut parsed_values: HashMap = HashMap::new(); + + for (fieldname, values) in raw_values.into_iter() { + /* + case 1 - multiple values, example { driving_types: ["manual", "automatic"] } + In this case we want to return the values as it is, NO point in making + driving_types: "manual, automatic" + + case 2 - single value, example { favourite_language: ["rust"] } + In this case we would want to deserialize the value as follows + favourite_language: "rust" + */ + if values.len() > 1 { + // handling multiple values - case 1 + parsed_values.insert(fieldname, ValueType::VecText(values.clone())); + } else { + // handle single value - case 2 + let prepared_value = values.into_iter().next()?; + parsed_values.insert(fieldname, ValueType::Text(prepared_value)); + } + } + + Some(parsed_values) + } + + pub fn parse_json(&self) -> Result + where + T: serde::de::DeserializeOwned, + { + let formatted = self.get_parsed_values(); + let as_string = serde_json::to_string(&formatted)?; + serde_json::from_str(&as_string) + } +} + #[cfg(feature = "serialize")] #[derive(serde::Serialize, serde::Deserialize)] struct SerializedFileEngine { @@ -60,8 +113,6 @@ fn deserialize_file_engine<'de, D>( where D: serde::Deserializer<'de>, { - use serde::Deserialize; - let Ok(file_engine) = SerializedFileEngine::deserialize(deserializer) else { return Ok(None); }; diff --git a/packages/rink/src/hooks.rs b/packages/rink/src/hooks.rs index a78194753..f8c4500d2 100644 --- a/packages/rink/src/hooks.rs +++ b/packages/rink/src/hooks.rs @@ -74,29 +74,6 @@ impl FormData { files: None, } } - - // ***** function to parse the 'values' to make it ready to use******* - // e.g - self.values = { username: ["rust"], password: ["dioxus"]} - // what we need it to be: { username: "rust", password: "dioxus"} - pub fn get_parsed_values(&self) -> Option> { - if (self.values.is_empty()) { - return None; - } - - let raw_values = self.values.clone(); - - let mut parsed_values: HashMap = HashMap::new(); - - for (fieldname, values) in raw_values.into_iter() { - // convert array of string value to string - // eg - ["rust", "javascript"] => "rust, javascript" - let prepared_value = values.join(", "); - - parsed_values.insert(fieldname, prepared_value); - } - - Some(parsed_values) - } } #[derive(Clone, Debug, PartialEq)]