Browse Source

1. migrated code to form.rs
2. made get_parsed_values as private fn.
3. handled multi-valued data while parsing

Bunny Bites 1 năm trước cách đây
mục cha
commit
d54ec57192
2 tập tin đã thay đổi với 53 bổ sung25 xóa
  1. 53 2
      packages/html/src/events/form.rs
  2. 0 23
      packages/rink/src/hooks.rs

+ 53 - 2
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<FormData>;
 
+#[derive(Serialize, Deserialize)]
+enum ValueType {
+    Text(String),
+    VecText(Vec<String>),
+}
+
 /* 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<std::sync::Arc<dyn FileEngine>>,
 }
 
+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<HashMap<String, ValueType>> {
+        if self.values.is_empty() {
+            return None;
+        }
+
+        let raw_values = self.values.clone();
+
+        let mut parsed_values: HashMap<String, ValueType> = 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<T>(&self) -> Result<T, serde_json::Error>
+    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);
     };

+ 0 - 23
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<HashMap<String, String>> {
-        if (self.values.is_empty()) {
-            return None;
-        }
-
-        let raw_values = self.values.clone();
-
-        let mut parsed_values: HashMap<String, String> = 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)]