From 210d4fdb68521fec6528fb74bed5de12221a1f03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= Date: Tue, 21 Jun 2022 13:47:40 +0200 Subject: [PATCH] http: take over json_object_to_query --- proxmox-http/Cargo.toml | 4 +++- proxmox-http/src/uri.rs | 47 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/proxmox-http/Cargo.toml b/proxmox-http/Cargo.toml index 14048ab5..7c222102 100644 --- a/proxmox-http/Cargo.toml +++ b/proxmox-http/Cargo.toml @@ -18,8 +18,10 @@ futures = { version = "0.3", optional = true } http = { version = "0.2", optional = true } hyper = { version = "0.14", features = [ "full" ], optional = true } openssl = { version = "0.10", optional = true } +serde_json = { version = "1.0", optional = true } tokio = { version = "1.0", features = [], optional = true } tokio-openssl = { version = "0.6.1", optional = true } +url = { version = "2", optional = true } proxmox-sys = { path = "../proxmox-sys", optional = true, version = "0.3.0" } proxmox-io = { path = "../proxmox-io", optional = true, version = "1.0.0" } @@ -29,7 +31,7 @@ proxmox-lang = { path = "../proxmox-lang", optional = true, version = "1.1" } default = [] client = [ "futures", "http-helpers", "openssl" ] -http-helpers = [ "base64", "http", "hyper", "tokio/io-util", "tokio-openssl", "proxmox-sys" ] +http-helpers = [ "base64", "http", "hyper", "serde_json", "tokio/io-util", "tokio-openssl", "proxmox-sys", "url" ] websocket = [ "base64", "futures", diff --git a/proxmox-http/src/uri.rs b/proxmox-http/src/uri.rs index 0f05ec7e..ecea1bca 100644 --- a/proxmox-http/src/uri.rs +++ b/proxmox-http/src/uri.rs @@ -1,6 +1,10 @@ //! URI Related helpers, such as `build_authority` +use anyhow::bail; +use anyhow::format_err; +use anyhow::Error; use http::uri::{Authority, InvalidUri}; +use serde_json::Value; // Build an [`Authority`](http::uri::Authority) from a combination of `host` and `port`, ensuring that // IPv6 addresses are enclosed in brackets. @@ -15,3 +19,46 @@ pub fn build_authority(host: &str, port: u16) -> Result { }; Ok(authority) } + +pub fn json_object_to_query(data: Value) -> Result { + let mut query = url::form_urlencoded::Serializer::new(String::new()); + + let object = data.as_object().ok_or_else(|| { + format_err!("json_object_to_query: got wrong data type (expected object).") + })?; + + for (key, value) in object { + match value { + Value::Bool(b) => { + query.append_pair(key, &b.to_string()); + } + Value::Number(n) => { + query.append_pair(key, &n.to_string()); + } + Value::String(s) => { + query.append_pair(key, s); + } + Value::Array(arr) => { + for element in arr { + match element { + Value::Bool(b) => { + query.append_pair(key, &b.to_string()); + } + Value::Number(n) => { + query.append_pair(key, &n.to_string()); + } + Value::String(s) => { + query.append_pair(key, s); + } + _ => bail!( + "json_object_to_query: unable to handle complex array data types." + ), + } + } + } + _ => bail!("json_object_to_query: unable to handle complex data types."), + } + } + + Ok(query.finish()) +}