From b333b8600deb7553b001d35edbd990887cf6d5f5 Mon Sep 17 00:00:00 2001 From: teor Date: Tue, 24 Dec 2024 12:14:55 +1000 Subject: [PATCH] Accept a string or int in the gateway HTTP server --- .../src/commands/http/server.rs | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/crates/subspace-gateway/src/commands/http/server.rs b/crates/subspace-gateway/src/commands/http/server.rs index d222509e63..1c4b534059 100644 --- a/crates/subspace-gateway/src/commands/http/server.rs +++ b/crates/subspace-gateway/src/commands/http/server.rs @@ -2,6 +2,7 @@ use actix_web::{web, App, HttpResponse, HttpServer, Responder}; use serde::{Deserialize, Deserializer, Serialize}; +use serde_json::Value; use std::default::Default; use std::sync::Arc; use subspace_core_primitives::hashes::{blake3_hash, Blake3Hash}; @@ -28,17 +29,33 @@ struct ObjectMapping { hash: Blake3Hash, piece_index: PieceIndex, piece_offset: u32, - #[serde(deserialize_with = "string_to_u32")] + // TODO: when the HTTP server starts sending integers, remove this custom function + #[serde(deserialize_with = "string_or_int_to_u32")] block_number: BlockNumber, } -/// Utility function to deserialize a JSON string into a u32. -fn string_to_u32<'de, D>(deserializer: D) -> Result +/// Utility function to deserialize a JSON string or integer into a u32. +fn string_or_int_to_u32<'de, D>(deserializer: D) -> Result where D: Deserializer<'de>, { - let s: String = Deserialize::deserialize(deserializer)?; - s.parse::().map_err(serde::de::Error::custom) + let v: serde_json::Value = Deserialize::deserialize(deserializer)?; + + match v { + Value::String(s) => s.parse::().map_err(serde::de::Error::custom), + Value::Number(n) => { + if let Some(n) = n.as_u64() { + if n <= u32::MAX as u64 { + return Ok(n as u32); + } + } + + Err(serde::de::Error::custom("block_number is not a u32")) + } + _ => Err(serde::de::Error::custom( + "block_number is not a Number or String", + )), + } } /// Requests an object mapping with `hash` from the indexer service.