diff --git a/subxt/src/backend/unstable/rpc_methods.rs b/subxt/src/backend/unstable/rpc_methods.rs index fd2a1dcf9c..3da380c35c 100644 --- a/subxt/src/backend/unstable/rpc_methods.rs +++ b/subxt/src/backend/unstable/rpc_methods.rs @@ -11,7 +11,7 @@ use crate::config::BlockHash; use crate::{Config, Error}; use derivative::Derivative; use futures::{Stream, StreamExt}; -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Deserializer, Serialize}; use std::collections::{HashMap, VecDeque}; use std::task::Poll; @@ -378,8 +378,7 @@ pub enum FollowEvent { /// /// This is the first event generated by the `follow` subscription /// and is submitted only once. -#[derive(Debug, Clone, PartialEq, Eq, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct Initialized { /// The hashes of the last finalized blocks. pub finalized_block_hashes: Vec, @@ -392,6 +391,30 @@ pub struct Initialized { pub finalized_block_runtime: Option, } +impl<'de, Hash: Deserialize<'de>> Deserialize<'de> for Initialized { + fn deserialize>(deserializer: D) -> Result { + // Custom struct that can deserialize both `finalizedBlockHash` and `finalizedBlockHashes`. + #[derive(Debug, Clone, PartialEq, Eq, Deserialize)] + #[serde(rename_all = "camelCase")] + struct InitializedIR { + finalized_block_hashes: Option>, + finalized_block_hash: Option, + finalized_block_runtime: Option, + } + + let ir = InitializedIR::deserialize(deserializer)?; + let finalized_block_hashes = ir + .finalized_block_hashes + .or_else(|| ir.finalized_block_hash.map(|hash| vec![hash])) + .ok_or_else(|| serde::de::Error::custom("Missing finalized block hashes"))?; + + Ok(Initialized { + finalized_block_hashes, + finalized_block_runtime: ir.finalized_block_runtime, + }) + } +} + /// The runtime event generated if the `follow` subscription /// has set the `with_runtime` flag. #[derive(Debug, Clone, PartialEq, Eq, Deserialize)]