Files
khadhroony-bot3/kb-onchain-transport/src/standard_methods.rs
2026-07-26 16:32:14 +02:00

672 lines
28 KiB
Rust

// file: kb-onchain-transport/src/standard_methods.rs
// version: 4
//! Canonical inventory of standard Solana HTTP and WebSocket JSON-RPC methods.
/// Strongest implementation contract exposed for one standard RPC method.
#[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Serialize)]
#[serde(rename_all = "snake_case")]
pub enum StandardRpcContract {
/// The crate exposes a dedicated request/result adapter in addition to raw JSON transport.
TypedAdapter,
/// The method is explicitly registered and callable through validated raw JSON transport.
RawJson,
}
impl crate::StandardRpcContract {
/// Returns the stable matrix code for this contract.
pub const fn code(self) -> &'static str {
return match self {
Self::TypedAdapter => "typed_adapter",
Self::RawJson => "raw_json",
};
}
}
/// Local category used to group standard Solana HTTP methods.
#[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Serialize)]
#[serde(rename_all = "snake_case")]
pub enum StandardHttpCategory {
/// Account state and account ownership reads.
Accounts,
/// SPL Token account and mint reads.
Tokens,
/// Transaction, signature, fee, simulation and submission methods.
Transactions,
/// Block, ledger and performance methods.
Blocks,
/// Cluster, node, epoch, slot and validator methods.
Cluster,
/// Inflation, supply and stake-economics methods.
Economics,
}
impl crate::StandardHttpCategory {
/// Returns the stable matrix code for this category.
pub const fn code(self) -> &'static str {
return match self {
Self::Accounts => "accounts",
Self::Tokens => "tokens",
Self::Transactions => "transactions",
Self::Blocks => "blocks",
Self::Cluster => "cluster",
Self::Economics => "economics",
};
}
}
/// One standard Solana HTTP JSON-RPC method specification.
#[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct StandardHttpMethodSpec {
/// Exact JSON-RPC method name.
pub method: &'static str,
/// Local inventory category.
pub category: crate::StandardHttpCategory,
/// Strongest contract currently exposed by `kb-onchain-transport`.
pub contract: crate::StandardRpcContract,
}
impl crate::StandardHttpMethodSpec {
/// Returns the local HTTP routing class for this method.
pub fn method_class(&self) -> crate::HttpMethodClass {
return match self.method {
"requestAirdrop" | "sendTransaction" => crate::HttpMethodClass::SendTransaction,
"getBlock"
| "getBlocks"
| "getBlocksWithLimit"
| "getProgramAccounts"
| "getSignaturesForAddress"
| "getTransaction"
| "simulateTransaction" => crate::HttpMethodClass::HeavyRead,
_ => crate::HttpMethodClass::GeneralRpc,
};
}
}
/// Every standard Solana HTTP JSON-RPC method documented by the canonical RPC reference.
pub const STANDARD_HTTP_METHODS: [crate::StandardHttpMethodSpec; 52] = [
crate::StandardHttpMethodSpec {
method: "getAccountInfo",
category: crate::StandardHttpCategory::Accounts,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getBalance",
category: crate::StandardHttpCategory::Accounts,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getLargestAccounts",
category: crate::StandardHttpCategory::Accounts,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getMinimumBalanceForRentExemption",
category: crate::StandardHttpCategory::Accounts,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getMultipleAccounts",
category: crate::StandardHttpCategory::Accounts,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getProgramAccounts",
category: crate::StandardHttpCategory::Accounts,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getTokenAccountBalance",
category: crate::StandardHttpCategory::Tokens,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getTokenAccountsByDelegate",
category: crate::StandardHttpCategory::Tokens,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getTokenAccountsByOwner",
category: crate::StandardHttpCategory::Tokens,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getTokenLargestAccounts",
category: crate::StandardHttpCategory::Tokens,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getTokenSupply",
category: crate::StandardHttpCategory::Tokens,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getFeeForMessage",
category: crate::StandardHttpCategory::Transactions,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getLatestBlockhash",
category: crate::StandardHttpCategory::Transactions,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getRecentPrioritizationFees",
category: crate::StandardHttpCategory::Transactions,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getSignaturesForAddress",
category: crate::StandardHttpCategory::Transactions,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getSignatureStatuses",
category: crate::StandardHttpCategory::Transactions,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getTransaction",
category: crate::StandardHttpCategory::Transactions,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getTransactionCount",
category: crate::StandardHttpCategory::Transactions,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "isBlockhashValid",
category: crate::StandardHttpCategory::Transactions,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "requestAirdrop",
category: crate::StandardHttpCategory::Transactions,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "sendTransaction",
category: crate::StandardHttpCategory::Transactions,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "simulateTransaction",
category: crate::StandardHttpCategory::Transactions,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getBlock",
category: crate::StandardHttpCategory::Blocks,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getBlockCommitment",
category: crate::StandardHttpCategory::Blocks,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getBlockHeight",
category: crate::StandardHttpCategory::Blocks,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getBlockProduction",
category: crate::StandardHttpCategory::Blocks,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getBlocks",
category: crate::StandardHttpCategory::Blocks,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getBlocksWithLimit",
category: crate::StandardHttpCategory::Blocks,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getBlockTime",
category: crate::StandardHttpCategory::Blocks,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getFirstAvailableBlock",
category: crate::StandardHttpCategory::Blocks,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getRecentPerformanceSamples",
category: crate::StandardHttpCategory::Blocks,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "minimumLedgerSlot",
category: crate::StandardHttpCategory::Blocks,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getClusterNodes",
category: crate::StandardHttpCategory::Cluster,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getEpochInfo",
category: crate::StandardHttpCategory::Cluster,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getEpochSchedule",
category: crate::StandardHttpCategory::Cluster,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getGenesisHash",
category: crate::StandardHttpCategory::Cluster,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getHealth",
category: crate::StandardHttpCategory::Cluster,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getHighestSnapshotSlot",
category: crate::StandardHttpCategory::Cluster,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getIdentity",
category: crate::StandardHttpCategory::Cluster,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getLeaderSchedule",
category: crate::StandardHttpCategory::Cluster,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getMaxRetransmitSlot",
category: crate::StandardHttpCategory::Cluster,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getMaxShredInsertSlot",
category: crate::StandardHttpCategory::Cluster,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getSlot",
category: crate::StandardHttpCategory::Cluster,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getSlotLeader",
category: crate::StandardHttpCategory::Cluster,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getSlotLeaders",
category: crate::StandardHttpCategory::Cluster,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getVersion",
category: crate::StandardHttpCategory::Cluster,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getVoteAccounts",
category: crate::StandardHttpCategory::Cluster,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getInflationGovernor",
category: crate::StandardHttpCategory::Economics,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getInflationRate",
category: crate::StandardHttpCategory::Economics,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getInflationReward",
category: crate::StandardHttpCategory::Economics,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getStakeMinimumDelegation",
category: crate::StandardHttpCategory::Economics,
contract: crate::StandardRpcContract::TypedAdapter,
},
crate::StandardHttpMethodSpec {
method: "getSupply",
category: crate::StandardHttpCategory::Economics,
contract: crate::StandardRpcContract::TypedAdapter,
},
];
/// Returns the canonical specification for one exact standard HTTP method name.
pub fn standard_http_method(
method: &str,
) -> std::option::Option<&'static crate::StandardHttpMethodSpec> {
return crate::STANDARD_HTTP_METHODS.iter().find(|entry| return entry.method == method);
}
/// Stability of one standard Solana WebSocket subscription surface.
#[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Serialize)]
#[serde(rename_all = "snake_case")]
pub enum StandardWsStability {
/// Stable standard PubSub method.
Stable,
/// Method documented as unstable and potentially gated by validator flags.
Unstable,
}
impl crate::StandardWsStability {
/// Returns the stable matrix code for this stability class.
pub const fn code(self) -> &'static str {
return match self {
Self::Stable => "stable",
Self::Unstable => "unstable",
};
}
}
/// One standard Solana WebSocket subscribe/unsubscribe pair.
#[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct StandardWsSubscriptionSpec {
/// Exact subscribe method name.
pub subscribe_method: &'static str,
/// Exact unsubscribe method name.
pub unsubscribe_method: &'static str,
/// Exact notification method name emitted by the server.
pub notification_method: &'static str,
/// Stability declared by the canonical Solana RPC documentation.
pub stability: crate::StandardWsStability,
/// Strongest typed request contract exposed by `kb-onchain-transport`.
pub request_contract: crate::StandardRpcContract,
/// Strongest typed notification contract exposed by `kb-onchain-transport`.
pub notification_contract: crate::StandardRpcContract,
/// Whether the pair is supported by the reusable persistent session runtime.
pub persistent_runtime: bool,
}
/// Every standard Solana WebSocket subscription pair documented by the canonical RPC reference.
pub const STANDARD_WS_SUBSCRIPTIONS: [crate::StandardWsSubscriptionSpec; 9] = [
crate::StandardWsSubscriptionSpec {
subscribe_method: "accountSubscribe",
unsubscribe_method: "accountUnsubscribe",
notification_method: "accountNotification",
stability: crate::StandardWsStability::Stable,
request_contract: crate::StandardRpcContract::TypedAdapter,
notification_contract: crate::StandardRpcContract::TypedAdapter,
persistent_runtime: true,
},
crate::StandardWsSubscriptionSpec {
subscribe_method: "blockSubscribe",
unsubscribe_method: "blockUnsubscribe",
notification_method: "blockNotification",
stability: crate::StandardWsStability::Unstable,
request_contract: crate::StandardRpcContract::TypedAdapter,
notification_contract: crate::StandardRpcContract::TypedAdapter,
persistent_runtime: true,
},
crate::StandardWsSubscriptionSpec {
subscribe_method: "logsSubscribe",
unsubscribe_method: "logsUnsubscribe",
notification_method: "logsNotification",
stability: crate::StandardWsStability::Stable,
request_contract: crate::StandardRpcContract::TypedAdapter,
notification_contract: crate::StandardRpcContract::TypedAdapter,
persistent_runtime: true,
},
crate::StandardWsSubscriptionSpec {
subscribe_method: "programSubscribe",
unsubscribe_method: "programUnsubscribe",
notification_method: "programNotification",
stability: crate::StandardWsStability::Stable,
request_contract: crate::StandardRpcContract::TypedAdapter,
notification_contract: crate::StandardRpcContract::TypedAdapter,
persistent_runtime: true,
},
crate::StandardWsSubscriptionSpec {
subscribe_method: "rootSubscribe",
unsubscribe_method: "rootUnsubscribe",
notification_method: "rootNotification",
stability: crate::StandardWsStability::Stable,
request_contract: crate::StandardRpcContract::TypedAdapter,
notification_contract: crate::StandardRpcContract::TypedAdapter,
persistent_runtime: true,
},
crate::StandardWsSubscriptionSpec {
subscribe_method: "signatureSubscribe",
unsubscribe_method: "signatureUnsubscribe",
notification_method: "signatureNotification",
stability: crate::StandardWsStability::Stable,
request_contract: crate::StandardRpcContract::TypedAdapter,
notification_contract: crate::StandardRpcContract::TypedAdapter,
persistent_runtime: true,
},
crate::StandardWsSubscriptionSpec {
subscribe_method: "slotSubscribe",
unsubscribe_method: "slotUnsubscribe",
notification_method: "slotNotification",
stability: crate::StandardWsStability::Stable,
request_contract: crate::StandardRpcContract::TypedAdapter,
notification_contract: crate::StandardRpcContract::TypedAdapter,
persistent_runtime: true,
},
crate::StandardWsSubscriptionSpec {
subscribe_method: "slotsUpdatesSubscribe",
unsubscribe_method: "slotsUpdatesUnsubscribe",
notification_method: "slotsUpdatesNotification",
stability: crate::StandardWsStability::Unstable,
request_contract: crate::StandardRpcContract::TypedAdapter,
notification_contract: crate::StandardRpcContract::TypedAdapter,
persistent_runtime: true,
},
crate::StandardWsSubscriptionSpec {
subscribe_method: "voteSubscribe",
unsubscribe_method: "voteUnsubscribe",
notification_method: "voteNotification",
stability: crate::StandardWsStability::Unstable,
request_contract: crate::StandardRpcContract::TypedAdapter,
notification_contract: crate::StandardRpcContract::TypedAdapter,
persistent_runtime: true,
},
];
/// Returns the canonical subscription specification matching a subscribe or unsubscribe method.
pub fn standard_ws_subscription(
method: &str,
) -> std::option::Option<&'static crate::StandardWsSubscriptionSpec> {
return crate::STANDARD_WS_SUBSCRIPTIONS.iter().find(|entry| {
return entry.subscribe_method == method || entry.unsubscribe_method == method;
});
}
#[cfg(test)]
mod tests {
#[test]
fn standard_http_inventory_is_exact_unique_and_classified() {
assert_eq!(crate::STANDARD_HTTP_METHODS.len(), 52);
let mut names = std::collections::BTreeSet::new();
let mut typed_count = 0_usize;
for method in &crate::STANDARD_HTTP_METHODS {
assert!(names.insert(method.method));
if method.contract == crate::StandardRpcContract::TypedAdapter {
typed_count = typed_count.saturating_add(1);
}
assert_eq!(
crate::standard_http_method(method.method),
std::option::Option::Some(method)
);
}
assert_eq!(typed_count, 52);
}
#[test]
fn configurable_request_registry_covers_the_former_thirty_eight_raw_methods() {
fn method<Request: crate::StandardHttpRequest>() -> &'static str {
return <Request as crate::StandardHttpRequest>::METHOD;
}
let methods = [
method::<crate::GetLargestAccountsRequest>(),
method::<crate::GetMultipleAccountsRequest>(),
method::<crate::GetProgramAccountsRequest>(),
method::<crate::GetTokenAccountBalanceRequest>(),
method::<crate::GetTokenAccountsByDelegateRequest>(),
method::<crate::GetTokenAccountsByOwnerRequest>(),
method::<crate::GetTokenLargestAccountsRequest>(),
method::<crate::GetTokenSupplyRequest>(),
method::<crate::GetRecentPrioritizationFeesRequest>(),
method::<crate::GetTransactionCountRequest>(),
method::<crate::IsBlockhashValidRequest>(),
method::<crate::GetBlockRequest>(),
method::<crate::GetBlockCommitmentRequest>(),
method::<crate::GetBlockProductionRequest>(),
method::<crate::GetBlocksRequest>(),
method::<crate::GetBlocksWithLimitRequest>(),
method::<crate::GetBlockTimeRequest>(),
method::<crate::GetFirstAvailableBlockRequest>(),
method::<crate::GetRecentPerformanceSamplesRequest>(),
method::<crate::MinimumLedgerSlotRequest>(),
method::<crate::GetClusterNodesRequest>(),
method::<crate::GetEpochScheduleRequest>(),
method::<crate::GetHealthRequest>(),
method::<crate::GetHighestSnapshotSlotRequest>(),
method::<crate::GetIdentityRequest>(),
method::<crate::GetLeaderScheduleRequest>(),
method::<crate::GetMaxRetransmitSlotRequest>(),
method::<crate::GetMaxShredInsertSlotRequest>(),
method::<crate::GetSlotRequest>(),
method::<crate::GetSlotLeaderRequest>(),
method::<crate::GetSlotLeadersRequest>(),
method::<crate::GetVersionRequest>(),
method::<crate::GetVoteAccountsRequest>(),
method::<crate::GetInflationGovernorRequest>(),
method::<crate::GetInflationRateRequest>(),
method::<crate::GetInflationRewardRequest>(),
method::<crate::GetStakeMinimumDelegationRequest>(),
method::<crate::GetSupplyRequest>(),
];
assert_eq!(methods.len(), 38);
let mut unique = std::collections::BTreeSet::new();
for method_name in methods {
assert!(unique.insert(method_name));
let specification = match crate::standard_http_method(method_name) {
std::option::Option::Some(specification) => specification,
std::option::Option::None => panic!("typed method absent from registry"),
};
assert_eq!(specification.contract, crate::StandardRpcContract::TypedAdapter);
}
}
#[test]
fn standard_ws_inventory_contains_nine_pairs_and_eighteen_unique_methods() {
assert_eq!(crate::STANDARD_WS_SUBSCRIPTIONS.len(), 9);
let mut names = std::collections::BTreeSet::new();
let mut unstable_count = 0_usize;
for subscription in &crate::STANDARD_WS_SUBSCRIPTIONS {
assert!(names.insert(subscription.subscribe_method));
assert!(names.insert(subscription.unsubscribe_method));
if subscription.stability == crate::StandardWsStability::Unstable {
unstable_count = unstable_count.saturating_add(1);
}
assert_eq!(subscription.request_contract, crate::StandardRpcContract::TypedAdapter);
assert_eq!(
subscription.notification_contract,
crate::StandardRpcContract::TypedAdapter
);
assert!(subscription.persistent_runtime);
assert_eq!(
crate::standard_ws_subscription(subscription.subscribe_method),
std::option::Option::Some(subscription)
);
assert_eq!(
crate::standard_ws_subscription(subscription.unsubscribe_method),
std::option::Option::Some(subscription)
);
}
assert_eq!(names.len(), 18);
assert_eq!(unstable_count, 3);
}
#[test]
fn standard_rpc_matrix_matches_compiled_inventory() {
let raw =
include_str!("../../test-fixtures/contract-matrices/SOLANA_STANDARD_RPC_MATRIX.json");
let parsed = match serde_json::from_str::<serde_json::Value>(raw) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("rpc matrix parsing failed: {error}"),
};
let http_methods = match parsed.get("http_methods").and_then(serde_json::Value::as_array) {
std::option::Option::Some(value) => value,
std::option::Option::None => panic!("rpc matrix http_methods missing"),
};
let ws_subscriptions =
match parsed.get("ws_subscriptions").and_then(serde_json::Value::as_array) {
std::option::Option::Some(value) => value,
std::option::Option::None => panic!("rpc matrix ws_subscriptions missing"),
};
assert_eq!(http_methods.len(), crate::STANDARD_HTTP_METHODS.len());
assert_eq!(ws_subscriptions.len(), crate::STANDARD_WS_SUBSCRIPTIONS.len());
for method in &crate::STANDARD_HTTP_METHODS {
let matrix_entry = http_methods.iter().find(|entry| {
return entry.get("method").and_then(serde_json::Value::as_str)
== std::option::Option::Some(method.method);
});
let matrix_entry = match matrix_entry {
std::option::Option::Some(value) => value,
std::option::Option::None => panic!("rpc matrix HTTP method missing"),
};
assert_eq!(
matrix_entry.get("category").and_then(serde_json::Value::as_str),
std::option::Option::Some(method.category.code())
);
assert_eq!(
matrix_entry.get("contract").and_then(serde_json::Value::as_str),
std::option::Option::Some(method.contract.code())
);
}
for subscription in &crate::STANDARD_WS_SUBSCRIPTIONS {
let matrix_entry = ws_subscriptions.iter().find(|entry| {
return entry.get("subscribe_method").and_then(serde_json::Value::as_str)
== std::option::Option::Some(subscription.subscribe_method);
});
let matrix_entry = match matrix_entry {
std::option::Option::Some(value) => value,
std::option::Option::None => panic!("rpc matrix WS subscription missing"),
};
assert_eq!(
matrix_entry.get("unsubscribe_method").and_then(serde_json::Value::as_str),
std::option::Option::Some(subscription.unsubscribe_method)
);
assert_eq!(
matrix_entry.get("notification_method").and_then(serde_json::Value::as_str),
std::option::Option::Some(subscription.notification_method)
);
assert_eq!(
matrix_entry.get("stability").and_then(serde_json::Value::as_str),
std::option::Option::Some(subscription.stability.code())
);
assert_eq!(
matrix_entry.get("request_contract").and_then(serde_json::Value::as_str),
std::option::Option::Some(subscription.request_contract.code())
);
assert_eq!(
matrix_entry.get("notification_contract").and_then(serde_json::Value::as_str),
std::option::Option::Some(subscription.notification_contract.code())
);
assert_eq!(
matrix_entry.get("persistent_runtime").and_then(serde_json::Value::as_bool),
std::option::Option::Some(subscription.persistent_runtime)
);
}
}
}