Deserialize null into empty hashmap and add service meta fields

This commit is contained in:
Alex 2023-06-13 11:35:30 +02:00
parent 45e12c3bcd
commit 2f968a585d
2 changed files with 17 additions and 2 deletions

View file

@ -2,7 +2,7 @@
name = "df-consul" name = "df-consul"
description = "Deuxfleurs' async Rust bindings for (a subset of) the Consul HTTP API" description = "Deuxfleurs' async Rust bindings for (a subset of) the Consul HTTP API"
authors = [ "Alex Auvolat <alex@adnab.me>" ] authors = [ "Alex Auvolat <alex@adnab.me>" ]
version = "0.3.4" version = "0.3.5"
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"
repository = "https://git.deuxfleurs.fr/Deuxfleurs/df-consul" repository = "https://git.deuxfleurs.fr/Deuxfleurs/df-consul"

View file

@ -13,7 +13,7 @@ use futures::future::BoxFuture;
use futures::stream::futures_unordered::FuturesUnordered; use futures::stream::futures_unordered::FuturesUnordered;
use futures::{FutureExt, StreamExt, TryFutureExt}; use futures::{FutureExt, StreamExt, TryFutureExt};
use log::*; use log::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Deserializer, Serialize};
use tokio::select; use tokio::select;
use tokio::sync::watch; use tokio::sync::watch;
@ -26,6 +26,7 @@ use crate::{Consul, WithIndex};
pub struct Node { pub struct Node {
pub node: String, pub node: String,
pub address: String, pub address: String,
#[serde(default, deserialize_with = "deserialize_null_default")]
pub meta: HashMap<String, String>, pub meta: HashMap<String, String>,
} }
@ -37,6 +38,8 @@ pub struct Service {
pub address: String, pub address: String,
pub port: u16, pub port: u16,
pub tags: Vec<String>, pub tags: Vec<String>,
#[serde(default, deserialize_with = "deserialize_null_default")]
pub meta: HashMap<String, String>,
} }
/// Full node info, as specified in response to "retrieve map of services for a node" API call in /// Full node info, as specified in response to "retrieve map of services for a node" API call in
@ -45,6 +48,7 @@ pub struct Service {
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]
pub struct CatalogNode { pub struct CatalogNode {
pub node: Node, pub node: Node,
#[serde(default, deserialize_with = "deserialize_null_default")]
pub services: HashMap<String, Service>, pub services: HashMap<String, Service>,
} }
@ -59,11 +63,14 @@ pub type ServiceList = HashMap<String, Vec<String>>;
pub struct ServiceNode { pub struct ServiceNode {
pub node: String, pub node: String,
pub address: String, pub address: String,
#[serde(default, deserialize_with = "deserialize_null_default")]
pub node_meta: HashMap<String, String>, pub node_meta: HashMap<String, String>,
pub service_name: String, pub service_name: String,
pub service_tags: Vec<String>, pub service_tags: Vec<String>,
pub service_address: String, pub service_address: String,
pub service_port: u16, pub service_port: u16,
#[serde(default, deserialize_with = "deserialize_null_default")]
pub service_meta: HashMap<String, String>,
} }
/// Node serving a service with health info, /// Node serving a service with health info,
@ -273,3 +280,11 @@ fn retry_to_time(retries: usize, max_time: Duration) -> Duration {
Duration::from_secs_f64(2.0f64 * 1.5f64.powf(retries as f64)), Duration::from_secs_f64(2.0f64 * 1.5f64.powf(retries as f64)),
) )
} }
fn deserialize_null_default<'de, D, T>(deserializer: D) -> Result<T, D::Error>
where
T: Default + Deserialize<'de>,
D: Deserializer<'de>,
{
Option::deserialize(deserializer).map(Option::unwrap_or_default)
}