From 9ed7cb215840ab9d445ba5e4c26885bea4bdc820 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Wed, 25 Sep 2024 03:09:36 +0100 Subject: [PATCH] Fix response parsing for () --- src/client/response.rs | 12 ++++++++++-- src/server/params.rs | 5 +++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/client/response.rs b/src/client/response.rs index dedc8b1..cfc3427 100644 --- a/src/client/response.rs +++ b/src/client/response.rs @@ -3,7 +3,9 @@ use crate::client::ResponseTransaction; use crate::response::ValueResponse; use crate::{ASCOMError, ASCOMErrorCode, ASCOMResult}; use mime::Mime; +use serde::de::value::UnitDeserializer; use serde::de::DeserializeOwned; +use std::any::TypeId; pub(crate) trait Response: Sized { fn prepare_reqwest(request: reqwest::RequestBuilder) -> reqwest::RequestBuilder { @@ -30,7 +32,7 @@ impl ResponseTransaction { } } -impl Response for ASCOMResult { +impl Response for ASCOMResult { fn from_reqwest(mime_type: Mime, bytes: &[u8]) -> eyre::Result> { let transaction = ResponseTransaction::from_reqwest(mime_type, bytes)?; let ascom_error = serde_json::from_slice::(bytes)?; @@ -38,7 +40,13 @@ impl Response for ASCOMResult { Ok(ResponseWithTransaction { transaction, response: match ascom_error.code { - ASCOMErrorCode::OK => Ok(serde_json::from_slice::>(bytes)?.value), + ASCOMErrorCode::OK => Ok(if TypeId::of::() == TypeId::of::<()>() { + // Specialization: avoid failure when trying to parse `()` from JSON object with no `Value`. + T::deserialize(UnitDeserializer::new()) + } else { + serde_json::from_slice::>(bytes) + .map(|value_response| value_response.value) + }?), _ => Err(ascom_error), }, }) diff --git a/src/server/params.rs b/src/server/params.rs index 3e6b62e..c37d4c9 100644 --- a/src/server/params.rs +++ b/src/server/params.rs @@ -7,6 +7,7 @@ use http::{Method, StatusCode}; use indexmap::IndexMap; use serde::de::{DeserializeOwned, IntoDeserializer}; use serde::Deserialize; +use std::any::TypeId; use std::fmt::Debug; use std::hash::Hash; @@ -39,11 +40,11 @@ where .swap_remove(name.as_ref()) .map(|mut value| { // Specialization: optimized path to avoid cloning the string. - if std::any::TypeId::of::() == std::any::TypeId::of::() { + if TypeId::of::() == TypeId::of::() { return T::deserialize(value.into_deserializer()); } // Specialization: booleans in ASCOM must be case-insensitive. - if std::any::TypeId::of::() == std::any::TypeId::of::() { + if TypeId::of::() == TypeId::of::() { value.make_ascii_lowercase(); } serde_plain::from_str(&value)