From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <pdm-devel-bounces@lists.proxmox.com>
Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68])
	by lore.proxmox.com (Postfix) with ESMTPS id 2F2671FF190
	for <inbox@lore.proxmox.com>; Fri, 10 Jan 2025 11:22:02 +0100 (CET)
Received: from firstgate.proxmox.com (localhost [127.0.0.1])
	by firstgate.proxmox.com (Proxmox) with ESMTP id 5C41129070;
	Fri, 10 Jan 2025 11:21:46 +0100 (CET)
From: Dominik Csapak <d.csapak@proxmox.com>
To: pdm-devel@lists.proxmox.com
Date: Fri, 10 Jan 2025 11:21:37 +0100
Message-Id: <20250110102142.1212874-2-d.csapak@proxmox.com>
X-Mailer: git-send-email 2.39.5
In-Reply-To: <20250110102142.1212874-1-d.csapak@proxmox.com>
References: <20250110102142.1212874-1-d.csapak@proxmox.com>
MIME-Version: 1.0
X-SPAM-LEVEL: Spam detection results:  0
 AWL 0.015 Adjusted score from AWL reputation of From: address
 BAYES_00                 -1.9 Bayes spam probability is 0 to 1%
 DMARC_MISSING             0.1 Missing DMARC policy
 KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment
 RCVD_IN_VALIDITY_CERTIFIED_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to
 Validity was blocked. See
 https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more
 information.
 RCVD_IN_VALIDITY_RPBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to
 Validity was blocked. See
 https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more
 information.
 RCVD_IN_VALIDITY_SAFE_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to
 Validity was blocked. See
 https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more
 information.
 SPF_HELO_NONE           0.001 SPF: HELO does not publish an SPF Record
 SPF_PASS               -0.001 SPF: sender matches SPF record
Subject: [pdm-devel] [PATCH yew-comp 1/1] form: add helpers for property
 strings
X-BeenThere: pdm-devel@lists.proxmox.com
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: Proxmox Datacenter Manager development discussion
 <pdm-devel.lists.proxmox.com>
List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pdm-devel>, 
 <mailto:pdm-devel-request@lists.proxmox.com?subject=unsubscribe>
List-Archive: <http://lists.proxmox.com/pipermail/pdm-devel/>
List-Post: <mailto:pdm-devel@lists.proxmox.com>
List-Help: <mailto:pdm-devel-request@lists.proxmox.com?subject=help>
List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel>, 
 <mailto:pdm-devel-request@lists.proxmox.com?subject=subscribe>
Reply-To: Proxmox Datacenter Manager development discussion
 <pdm-devel@lists.proxmox.com>
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Errors-To: pdm-devel-bounces@lists.proxmox.com
Sender: "pdm-devel" <pdm-devel-bounces@lists.proxmox.com>

when handling property strings in edit windows/input panels, we want to
have a consistent and easy way to handle them.

This introduces two helpers for parsing the property string into
separate parts (`flatten_property_string`) and one to generate the
property string again from parts (`property_string_from_parts`)

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 src/form/mod.rs | 73 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/lib.rs      |  2 ++
 2 files changed, 75 insertions(+)
 create mode 100644 src/form/mod.rs

diff --git a/src/form/mod.rs b/src/form/mod.rs
new file mode 100644
index 0000000..9661c28
--- /dev/null
+++ b/src/form/mod.rs
@@ -0,0 +1,73 @@
+use serde::{de::DeserializeOwned, Serialize};
+use serde_json::{json, Value};
+
+use proxmox_schema::{ApiType, ObjectSchemaType, Schema};
+
+#[inline]
+fn format_property(name: &str, part: &str) -> String {
+    format!("_{name}_{part}")
+}
+
+/// Convert a property string to separate properties
+///
+/// This is useful for use in an [`crate::EditWindow`] when editing parts of a property string.
+/// Takes the `name` property from `data`, parses it a s property string, and sets it back to
+/// `data` as `_{name}_{key}` so this should be used as a field. If it's not desired
+/// to expose a property to the UI, simply add a hidden field to the form.
+pub fn flatten_property_string(data: &mut Value, name: &str, schema: &'static Schema) {
+    if let Some(prop_str) = data[name].as_str() {
+        if let Ok(Value::Object(map)) = schema.parse_property_string(&prop_str) {
+            for (part, v) in map {
+                data[format_property(name, &part)] = v;
+            }
+        }
+    }
+}
+
+/// Uses an [`proxmox_schema::ObjectSchema`] to generate a property string from separate properties.
+///
+/// This is useful for use in an [`crate::EditWindow`] when editing parts of a property string.
+/// Takes the single properties from `data` and adds it as a property string as `name`.
+pub fn property_string_from_parts<T: ApiType + Serialize + DeserializeOwned>(
+    data: &mut Value,
+    name: &str,
+    skip_empty_values: bool,
+) {
+    let props = match T::API_SCHEMA {
+        Schema::Object(object_schema) => object_schema.properties(),
+        _ => return, // not supported
+    };
+
+    if let Value::Object(map) = data {
+        let mut value = json!({});
+
+        let mut has_parts = false;
+        for (part, _, _) in props {
+            if let Some(v) = map.remove(&format_property(name, part)) {
+                has_parts = true;
+                let is_empty = match &v {
+                    Value::String(s) => s.is_empty(),
+                    _ => false,
+                };
+                if !(skip_empty_values && is_empty) {
+                    value[part] = v;
+                }
+            }
+        }
+
+        if !has_parts {
+            return;
+        }
+
+        let parsed: Option<T> = serde_json::from_value(value).ok();
+
+        if let Some(parsed) = parsed {
+            match proxmox_schema::property_string::print(&parsed) {
+                Ok(prop_string) => data[name] = prop_string.into(),
+                Err(err) => log::error!("error during property string print for {name}: {err}"),
+            }
+        } else {
+            data[name] = "".into();
+        }
+    }
+}
diff --git a/src/lib.rs b/src/lib.rs
index a4d68c4..091cb72 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -45,6 +45,8 @@ pub use confirm_button::{ConfirmButton, ProxmoxConfirmButton};
 mod data_view_window;
 pub use data_view_window::{DataViewWindow, ProxmoxDataViewWindow};
 
+pub mod form;
+
 pub mod gauge;
 pub use gauge::{Gauge, ProxmoxGauge};
 
-- 
2.39.5



_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel