longbridge/signal/
context.rs1use std::sync::Arc;
2
3use longbridge_httpcli::{HttpClient, Json, Method};
4use serde::Deserialize;
5use tracing::{Subscriber, dispatcher, instrument::WithSubscriber};
6
7use crate::{Config, Result, signal::types::*};
8
9struct InnerSignalContext {
10 http_cli: HttpClient,
11 log_subscriber: Arc<dyn Subscriber + Send + Sync>,
12}
13
14impl Drop for InnerSignalContext {
15 fn drop(&mut self) {
16 dispatcher::with_default(&self.log_subscriber.clone().into(), || {
17 tracing::info!("signal context dropped");
18 });
19 }
20}
21
22#[derive(Clone)]
24pub struct SignalContext(Arc<InnerSignalContext>);
25
26impl SignalContext {
27 pub fn new(config: Arc<Config>) -> Self {
29 let log_subscriber = config.create_log_subscriber("signal");
30 dispatcher::with_default(&log_subscriber.clone().into(), || {
31 tracing::info!(language = ?config.language, "creating signal context");
32 });
33 let ctx = Self(Arc::new(InnerSignalContext {
34 http_cli: config.create_http_client(),
35 log_subscriber,
36 }));
37 dispatcher::with_default(&ctx.0.log_subscriber.clone().into(), || {
38 tracing::info!("signal context created");
39 });
40 ctx
41 }
42
43 #[inline]
45 pub fn log_subscriber(&self) -> Arc<dyn Subscriber + Send + Sync> {
46 self.0.log_subscriber.clone()
47 }
48
49 pub async fn signals(&self, opts: SignalsOptions) -> Result<SignalsResponse> {
53 Ok(self
54 .0
55 .http_cli
56 .request(Method::GET, "/v1/signals")
57 .query_params(opts)
58 .response::<Json<SignalsResponse>>()
59 .send()
60 .with_subscriber(self.0.log_subscriber.clone())
61 .await?
62 .0)
63 }
64
65 pub async fn signal(&self, signal_id: impl Into<String>) -> Result<Signal> {
70 #[derive(Debug, Deserialize)]
71 struct Response {
72 signal: Signal,
73 }
74
75 let signal_id = signal_id.into();
76 Ok(self
77 .0
78 .http_cli
79 .request(Method::GET, format!("/v1/signals/{signal_id}"))
80 .response::<Json<Response>>()
81 .send()
82 .with_subscriber(self.0.log_subscriber.clone())
83 .await?
84 .0
85 .signal)
86 }
87
88 pub async fn security_facts(&self, opts: SecurityFactsOptions) -> Result<Vec<SecurityFact>> {
96 #[derive(Debug, Deserialize)]
97 struct Response {
98 #[serde(default)]
99 facts: Vec<SecurityFact>,
100 }
101
102 Ok(self
103 .0
104 .http_cli
105 .request(Method::GET, "/v1/facts/security_facts")
106 .query_params(opts)
107 .response::<Json<Response>>()
108 .send()
109 .with_subscriber(self.0.log_subscriber.clone())
110 .await?
111 .0
112 .facts)
113 }
114}