1use serde::Serialize;
2use surf::http::Method;
3
4use crate::presenters::{CreateTopic, PublishMessage};
5use crate::Client;
6use crate::Error;
7use crate::Subscription;
8
9#[derive(Debug)]
10pub struct Topic {
11 pub name: String,
12 pub(crate) client: crate::Client,
13}
14
15impl Topic {
16 pub fn new(client: Client, name: &str) -> Self {
17 Self {
18 name: format!("projects/{}/topics/{}", client.project(), name),
19 client,
20 }
21 }
22
23 pub async fn create(client: Client, name: &str) -> Result<Topic, Error> {
24 let topic = Self::new(client, name);
25 let url = format!("https://pubsub.googleapis.com/v1/{}", topic.name);
26 let payload = CreateTopic::from(&topic.name);
27 let mut response = topic
28 .client
29 .base_request(Method::PUT, &url)
30 .body_json(&payload)?
31 .await
32 .unwrap();
33 if response.status().is_success() {
34 return Ok(topic);
35 } else {
36 response
37 .body_string()
38 .await
39 .map_err(|err| Error::Unexpected(format!("{}", err)))
40 .and_then(|json| Err(Error::PubSub(json)))
41 }
42 }
43
44 pub async fn create_subscription(&self) -> Result<Subscription, Error> {
45 Subscription::create(self.clone()).await
46 }
47
48 pub async fn publish<T: Serialize>(&self, data: T) -> Result<(), Error> {
49 let url = format!("https://pubsub.googleapis.com/v1/{}:publish", self.name);
50 let payload = PublishMessage::from(&data);
51 let mut response = self
52 .client
53 .base_request(Method::POST, &url)
54 .body_json(&payload)?
55 .await
56 .unwrap();
57 if response.status().is_success() {
58 Ok(())
59 } else {
60 response
61 .body_string()
62 .await
63 .map_err(|err| Error::Unexpected(format!("{}", err)))
64 .and_then(|json| Err(Error::PubSub(json)))
65 }
66 }
67}