Skip to main content

longbridge/content/
context.rs

1use std::sync::Arc;
2
3use longbridge_httpcli::{HttpClient, Json, Method};
4use serde::Deserialize;
5
6use super::types::{
7    CreateReplyOptions, CreateTopicOptions, ListTopicRepliesOptions, MyTopicsOptions, NewsItem,
8    OwnedTopic, TopicItem, TopicReply,
9};
10use crate::{Config, Result};
11
12struct InnerContentContext {
13    http_cli: HttpClient,
14}
15
16/// Content context
17#[derive(Clone)]
18pub struct ContentContext(Arc<InnerContentContext>);
19
20impl ContentContext {
21    /// Create a `ContentContext`
22    pub fn new(config: Arc<Config>) -> Self {
23        Self(Arc::new(InnerContentContext {
24            http_cli: config.create_http_client(),
25        }))
26    }
27
28    /// Get topics created by the current authenticated user.
29    ///
30    /// See: <https://open.longbridge.com/docs/api?op=list_my_topics>
31    pub async fn my_topics(&self, opts: MyTopicsOptions) -> Result<Vec<OwnedTopic>> {
32        #[derive(Debug, Deserialize)]
33        struct Response {
34            items: Vec<OwnedTopic>,
35        }
36
37        Ok(self
38            .0
39            .http_cli
40            .request(Method::GET, "/v1/content/topics/mine")
41            .query_params(opts)
42            .response::<Json<Response>>()
43            .send()
44            .await?
45            .0
46            .items)
47    }
48
49    /// Create a new community topic.
50    ///
51    /// See: <https://open.longbridge.com/docs/api?op=create_topic>
52    pub async fn create_topic(&self, opts: CreateTopicOptions) -> Result<String> {
53        #[derive(Debug, Deserialize)]
54        struct TopicId {
55            id: String,
56        }
57
58        #[derive(Debug, Deserialize)]
59        struct Response {
60            item: TopicId,
61        }
62
63        Ok(self
64            .0
65            .http_cli
66            .request(Method::POST, "/v1/content/topics")
67            .body(Json(opts))
68            .response::<Json<Response>>()
69            .send()
70            .await?
71            .0
72            .item
73            .id)
74    }
75
76    /// Get discussion topics list
77    pub async fn topics(&self, symbol: impl Into<String>) -> Result<Vec<TopicItem>> {
78        #[derive(Debug, Deserialize)]
79        struct Response {
80            items: Vec<TopicItem>,
81        }
82
83        let symbol = symbol.into();
84        Ok(self
85            .0
86            .http_cli
87            .request(Method::GET, format!("/v1/content/{symbol}/topics"))
88            .response::<Json<Response>>()
89            .send()
90            .await?
91            .0
92            .items)
93    }
94
95    /// Get full details of a topic by its ID.
96    ///
97    /// See: <https://open.longbridge.com/docs/api?op=topic_detail>
98    pub async fn topic_detail(&self, id: impl Into<String>) -> Result<OwnedTopic> {
99        #[derive(Debug, Deserialize)]
100        struct Response {
101            item: OwnedTopic,
102        }
103
104        let id = id.into();
105        Ok(self
106            .0
107            .http_cli
108            .request(Method::GET, format!("/v1/content/topics/{id}"))
109            .response::<Json<Response>>()
110            .send()
111            .await?
112            .0
113            .item)
114    }
115
116    /// List replies on a topic.
117    ///
118    /// See: <https://open.longbridge.com/docs/api?op=list_topic_replies>
119    pub async fn list_topic_replies(
120        &self,
121        topic_id: impl Into<String>,
122        opts: ListTopicRepliesOptions,
123    ) -> Result<Vec<TopicReply>> {
124        #[derive(Debug, Deserialize)]
125        struct Response {
126            items: Vec<TopicReply>,
127        }
128
129        let topic_id = topic_id.into();
130        Ok(self
131            .0
132            .http_cli
133            .request(
134                Method::GET,
135                format!("/v1/content/topics/{topic_id}/comments"),
136            )
137            .query_params(opts)
138            .response::<Json<Response>>()
139            .send()
140            .await?
141            .0
142            .items)
143    }
144
145    /// Post a reply to a community topic.
146    ///
147    /// See: <https://open.longbridge.com/docs/api?op=create_topic_reply>
148    pub async fn create_topic_reply(
149        &self,
150        topic_id: impl Into<String>,
151        opts: CreateReplyOptions,
152    ) -> Result<TopicReply> {
153        #[derive(Debug, Deserialize)]
154        struct Response {
155            item: TopicReply,
156        }
157
158        let topic_id = topic_id.into();
159        Ok(self
160            .0
161            .http_cli
162            .request(
163                Method::POST,
164                format!("/v1/content/topics/{topic_id}/comments"),
165            )
166            .body(Json(opts))
167            .response::<Json<Response>>()
168            .send()
169            .await?
170            .0
171            .item)
172    }
173
174    /// Get news list
175    pub async fn news(&self, symbol: impl Into<String>) -> Result<Vec<NewsItem>> {
176        #[derive(Debug, Deserialize)]
177        struct Response {
178            items: Vec<NewsItem>,
179        }
180
181        let symbol = symbol.into();
182        Ok(self
183            .0
184            .http_cli
185            .request(Method::GET, format!("/v1/content/{symbol}/news"))
186            .response::<Json<Response>>()
187            .send()
188            .await?
189            .0
190            .items)
191    }
192}