syncthing_async/
client.rs1use crate::Fallible;
2use crate::events::EventStream;
3use http::Method;
4use http::header::HeaderValue;
5use http::uri::{Authority, Parts as UriParts, PathAndQuery, Scheme, Uri};
6use reqwest::Client as HttpClient;
7use serde::de::DeserializeOwned as Deserialize;
8use syncthing_types::events::{Event, EventType};
9use syncthing_types::routes::*;
10use syncthing_types::system;
11use syncthing_types::utils;
12
13static API_HEADER_KEY: &str = "X-API-Key";
14static API_DEFAULT_AUTHORITY: &str = "127.0.0.1:8384";
15static EMPTY_EVENT_SUBSCRIPTION: Vec<EventType> = Vec::new();
16
17pub struct Client {
18 client: HttpClient,
19 authority: Authority,
20 api_key: String,
21}
22
23impl Client {
24 pub fn new(api_key: impl Into<String>) -> Self {
25 Self {
26 client: HttpClient::new(),
27 authority: Authority::from_static(API_DEFAULT_AUTHORITY),
28 api_key: api_key.into(),
29 }
30 }
31
32 pub fn with_authority(api_key: impl Into<String>, authority: Authority) -> Self {
33 Self {
34 client: HttpClient::new(),
35 authority,
36 api_key: api_key.into(),
37 }
38 }
39
40 pub(crate) async fn request<D: Deserialize, T: AsRef<[u8]> + 'static>(
41 &self,
42 method: Method,
43 path_and_query: T,
44 ) -> Fallible<D> {
45 let mut uri_parts = UriParts::default();
46 uri_parts.authority = Some(self.authority.clone());
47 uri_parts.scheme = Some(Scheme::HTTP);
48 uri_parts.path_and_query = Some(PathAndQuery::from_maybe_shared(path_and_query)?);
49 let uri = Uri::from_parts(uri_parts)?;
50 let resp = self
51 .client
52 .request(method, uri.to_string())
53 .header(API_HEADER_KEY, HeaderValue::from_str(&self.api_key)?)
54 .send()
55 .await?
56 .error_for_status()?;
57 Ok(resp.json().await?)
58 }
59
60 pub async fn get_all_events(
61 &self,
62 since: Option<u64>,
63 limit: Option<u64>,
64 ) -> Fallible<Vec<Event>> {
65 self.get_events(since, limit, &EMPTY_EVENT_SUBSCRIPTION)
66 .await
67 }
68
69 pub async fn get_events(
70 &self,
71 since: Option<u64>,
72 limit: Option<u64>,
73 events: impl AsRef<[EventType]>,
74 ) -> Fallible<Vec<Event>> {
75 let path_and_query = utils::construct_event_url(since, limit, events)?;
76 self.request(Method::GET, path_and_query).await
77 }
78
79 pub fn subscribe_to(self, events: impl Into<Vec<EventType>>) -> EventStream {
80 EventStream::new(self, events.into())
81 }
82
83 pub fn subscribe_to_all(self) -> EventStream {
84 EventStream::new(self, EMPTY_EVENT_SUBSCRIPTION.clone())
85 }
86
87 pub async fn get_system_connections(&self) -> Fallible<system::Connections> {
88 self.request(Method::GET, SYSTEM_CONNECTIONS_PATH).await
89 }
90
91 pub async fn get_system_debug(&self) -> Fallible<system::DebugInfo> {
92 self.request(Method::GET, SYSTEM_DEBUG_PATH).await
93 }
94
95 pub async fn get_system_discovery(&self) -> Fallible<system::Discovery> {
96 self.request(Method::GET, SYSTEM_DISCOVERY_PATH).await
97 }
98
99 pub async fn get_system_log(&self) -> Fallible<system::Log> {
100 self.request(Method::GET, SYSTEM_LOG_PATH).await
101 }
102
103 pub async fn get_system_error(&self) -> Fallible<system::Error> {
104 self.request(Method::GET, SYSTEM_ERROR_PATH).await
105 }
106
107 pub async fn get_system_ping(&self) -> Fallible<system::Ping> {
108 self.request(Method::GET, SYSTEM_PING_PATH).await
109 }
110
111 pub async fn get_system_upgrade(&self) -> Fallible<system::UpgradeInfo> {
112 self.request(Method::GET, SYSTEM_UPGRADE_PATH).await
113 }
114
115 pub async fn get_system_version(&self) -> Fallible<system::Version> {
116 self.request(Method::GET, SYSTEM_VERSION_PATH).await
117 }
118}