mirror of
https://git.proxmox.com/git/proxmox
synced 2025-08-04 15:40:27 +00:00
promxox-router: add SerializableReturn Trait
this will be useful as a generic return type for api calls which must implement Serialize. Signed-off-by: Dominik Csapak <d.csapak@proxmox.com> Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
27c8106d7b
commit
2c9272945e
@ -15,6 +15,7 @@ hyper = { version = "0.14", features = [ "full" ] }
|
|||||||
nix = "0.19.1"
|
nix = "0.19.1"
|
||||||
percent-encoding = "2.1"
|
percent-encoding = "2.1"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
serde = "1.0"
|
||||||
unicode-width ="0.1.8"
|
unicode-width ="0.1.8"
|
||||||
|
|
||||||
# cli:
|
# cli:
|
||||||
@ -24,6 +25,7 @@ libc = { version = "0.2", optional = true }
|
|||||||
|
|
||||||
proxmox-lang = { path = "../proxmox-lang", version = "1.1" }
|
proxmox-lang = { path = "../proxmox-lang", version = "1.1" }
|
||||||
proxmox-schema = { path = "../proxmox-schema", version = "1.1" }
|
proxmox-schema = { path = "../proxmox-schema", version = "1.1" }
|
||||||
|
proxmox-async = { path = "../proxmox-async", version = "0.4" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = [ "cli" ]
|
default = [ "cli" ]
|
||||||
|
@ -12,6 +12,7 @@ pub mod error;
|
|||||||
mod permission;
|
mod permission;
|
||||||
mod router;
|
mod router;
|
||||||
mod rpc_environment;
|
mod rpc_environment;
|
||||||
|
mod serializable_return;
|
||||||
|
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use error::HttpError;
|
pub use error::HttpError;
|
||||||
@ -19,6 +20,7 @@ pub use error::HttpError;
|
|||||||
pub use permission::*;
|
pub use permission::*;
|
||||||
pub use router::*;
|
pub use router::*;
|
||||||
pub use rpc_environment::{RpcEnvironment, RpcEnvironmentType};
|
pub use rpc_environment::{RpcEnvironment, RpcEnvironmentType};
|
||||||
|
pub use serializable_return::SerializableReturn;
|
||||||
|
|
||||||
// make list_subdirs_api_method! work without an explicit proxmox-schema dependency:
|
// make list_subdirs_api_method! work without an explicit proxmox-schema dependency:
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
62
proxmox-router/src/serializable_return.rs
Normal file
62
proxmox-router/src/serializable_return.rs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
use serde::Serializer;
|
||||||
|
use serde_json::Value;
|
||||||
|
|
||||||
|
/// This defines a *fixed* serializer (iow. also where/how to write out the data).
|
||||||
|
///
|
||||||
|
/// (Note that `serde::Serializer` is implemented for `__&mut__ serde_json::Serializer`.
|
||||||
|
type SenderSerializer<'a> = &'a mut serde_json::Serializer<
|
||||||
|
&'a mut std::io::BufWriter<proxmox_async::blocking::SenderWriter>,
|
||||||
|
>;
|
||||||
|
|
||||||
|
/// This is an object-safe trait which requires the ability to serialize into particular
|
||||||
|
/// Serializer instances.
|
||||||
|
pub trait SerializableReturn {
|
||||||
|
/// Serializes self into a [`proxmox_async::blocking::SenderWriter`] wrapped
|
||||||
|
/// into a [`std::io::BufWriter`]
|
||||||
|
///
|
||||||
|
/// If `value` is an Object/Map, serializes that first and puts the value of
|
||||||
|
/// `self` into the `data` property.
|
||||||
|
fn sender_serialize(
|
||||||
|
&self,
|
||||||
|
serializer: SenderSerializer,
|
||||||
|
value: Value,
|
||||||
|
) -> Result<
|
||||||
|
<SenderSerializer as serde::Serializer>::Ok,
|
||||||
|
<SenderSerializer as serde::Serializer>::Error,
|
||||||
|
>;
|
||||||
|
|
||||||
|
/// Returns a value again from self
|
||||||
|
fn to_value(&self) -> Result<Value, serde_json::error::Error>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> SerializableReturn for T
|
||||||
|
where
|
||||||
|
T: serde::Serialize,
|
||||||
|
{
|
||||||
|
fn sender_serialize(
|
||||||
|
&self,
|
||||||
|
serializer: SenderSerializer,
|
||||||
|
value: Value,
|
||||||
|
) -> Result<
|
||||||
|
<SenderSerializer as serde::Serializer>::Ok,
|
||||||
|
<SenderSerializer as serde::Serializer>::Error,
|
||||||
|
> {
|
||||||
|
use serde::ser::SerializeMap;
|
||||||
|
if let Some(original) = value.as_object() {
|
||||||
|
let mut map = serializer.serialize_map(None)?;
|
||||||
|
for (k, v) in original {
|
||||||
|
map.serialize_entry(k, v)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
map.serialize_key("data")?;
|
||||||
|
map.serialize_value(&self)?;
|
||||||
|
map.end()
|
||||||
|
} else {
|
||||||
|
self.serialize(serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_value(&self) -> Result<Value, serde_json::error::Error> {
|
||||||
|
serde_json::to_value(self)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user