From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id 2F2671FF190 for ; 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 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox Datacenter Manager development discussion Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pdm-devel-bounces@lists.proxmox.com Sender: "pdm-devel" 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 --- 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( + 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 = 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