simulator_api/
subscribe_config.rs1use serde::{Deserialize, Serialize};
10use serde_json::Value;
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
15#[serde(rename_all = "lowercase")]
16pub enum Compression {
17 Zstd,
18}
19
20#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
22pub struct SubscribeConfig {
23 #[serde(
26 rename = "replayFromSlot",
27 default,
28 skip_serializing_if = "Option::is_none"
29 )]
30 pub replay_from_slot: Option<i64>,
31 #[serde(default, skip_serializing_if = "Option::is_none")]
34 pub compression: Option<Compression>,
35}
36
37impl SubscribeConfig {
38 pub fn from_value(config: Option<&Value>) -> Self {
42 config
43 .cloned()
44 .and_then(|v| serde_json::from_value(v).ok())
45 .unwrap_or_default()
46 }
47
48 pub fn apply_to(&self, params: &mut Value) {
52 let Some(config) = params.get_mut(1).and_then(Value::as_object_mut) else {
53 return;
54 };
55 if let Ok(Value::Object(fields)) = serde_json::to_value(self) {
56 config.extend(fields);
57 }
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64
65 #[test]
66 fn parses_set_options_and_ignores_per_kind_fields() {
67 let cfg = SubscribeConfig::from_value(Some(&serde_json::json!({
68 "commitment": "confirmed",
69 "replayFromSlot": 42,
70 "compression": "zstd",
71 })));
72 assert_eq!(cfg.replay_from_slot, Some(42));
73 assert_eq!(cfg.compression, Some(Compression::Zstd));
74 }
75
76 #[test]
77 fn absent_or_malformed_options_default_off() {
78 assert_eq!(
79 SubscribeConfig::from_value(None),
80 SubscribeConfig::default()
81 );
82 let cfg =
83 SubscribeConfig::from_value(Some(&serde_json::json!({ "commitment": "confirmed" })));
84 assert_eq!(cfg, SubscribeConfig::default());
85 let cfg = SubscribeConfig::from_value(Some(&serde_json::json!({ "compression": "gzip" })));
87 assert_eq!(cfg.compression, None);
88 }
89
90 #[test]
91 fn apply_to_merges_into_config_without_clobbering() {
92 let mut params =
93 serde_json::json!([{ "mentions": ["prog"] }, { "commitment": "confirmed" }]);
94 SubscribeConfig {
95 replay_from_slot: Some(7),
96 compression: Some(Compression::Zstd),
97 }
98 .apply_to(&mut params);
99 assert_eq!(params[1]["commitment"], "confirmed");
100 assert_eq!(params[1]["replayFromSlot"], 7);
101 assert_eq!(params[1]["compression"], "zstd");
102 }
103
104 #[test]
105 fn apply_to_omits_unset_options() {
106 let mut params = serde_json::json!([{ "mentions": ["prog"] }, {}]);
107 SubscribeConfig::default().apply_to(&mut params);
108 assert_eq!(params[1].as_object().unwrap().len(), 0);
109 }
110}