automatons_github/resource/
app.rs

1use std::collections::HashMap;
2use std::fmt::{Display, Formatter};
3
4use chrono::{DateTime, Utc};
5use serde::{Deserialize, Serialize};
6use url::Url;
7
8use crate::resource::{Account, NodeId};
9use crate::{id, name};
10
11id!(
12    /// App id
13    ///
14    /// The [`AppId`] is a unique, numerical id that is used to interact with an app through
15    /// [GitHub's REST API](https://docs.github.com/en/rest).
16    AppId
17);
18
19name!(
20    /// App name
21    ///
22    /// Apps on GitHub have a human-readable name that is used throughout GitHub's website as well
23    /// as for status checks.
24    AppName
25);
26
27name!(
28    /// App slug
29    ///
30    /// The [`AppSlug`] is a URL-friendly version of the app's name.
31    AppSlug
32);
33
34/// GitHub App
35///
36/// Third-parties can create integrations with the GitHub platform by creating a GitHub App. Apps
37/// have their own identify and authentication, and can request granular permissions and access to
38/// events. Every [`App`] is owned by an [`Account`].
39#[derive(Clone, Eq, PartialEq, Debug, Deserialize, Serialize)]
40pub struct App {
41    id: AppId,
42    node_id: NodeId,
43    name: AppName,
44    slug: AppSlug,
45    owner: Account,
46    description: String,
47    external_url: Url,
48    html_url: Url,
49    created_at: DateTime<Utc>,
50    updated_at: DateTime<Utc>,
51    permissions: HashMap<String, String>,
52    events: Vec<String>,
53}
54
55impl App {
56    /// Returns the app's id.
57    #[cfg_attr(feature = "tracing", tracing::instrument)]
58    pub fn id(&self) -> AppId {
59        self.id
60    }
61
62    /// Returns the app's node id.
63    #[cfg_attr(feature = "tracing", tracing::instrument)]
64    pub fn node_id(&self) -> &NodeId {
65        &self.node_id
66    }
67
68    /// Returns the app's name.
69    #[cfg_attr(feature = "tracing", tracing::instrument)]
70    pub fn name(&self) -> &AppName {
71        &self.name
72    }
73
74    /// Returns the app's slug.
75    #[cfg_attr(feature = "tracing", tracing::instrument)]
76    pub fn slug(&self) -> &AppSlug {
77        &self.slug
78    }
79
80    /// Returns the app's owner.
81    #[cfg_attr(feature = "tracing", tracing::instrument)]
82    pub fn owner(&self) -> &Account {
83        &self.owner
84    }
85
86    /// Returns the app's description.
87    #[cfg_attr(feature = "tracing", tracing::instrument)]
88    pub fn description(&self) -> &String {
89        &self.description
90    }
91
92    /// Returns the URL to the app's external website.
93    #[cfg_attr(feature = "tracing", tracing::instrument)]
94    pub fn external_url(&self) -> &Url {
95        &self.external_url
96    }
97
98    /// Returns the URL to the app's website on GitHub.
99    #[cfg_attr(feature = "tracing", tracing::instrument)]
100    pub fn html_url(&self) -> &Url {
101        &self.html_url
102    }
103
104    /// Returns the date when the app was created.
105    #[cfg_attr(feature = "tracing", tracing::instrument)]
106    pub fn created_at(&self) -> &DateTime<Utc> {
107        &self.created_at
108    }
109
110    /// Returns the date when the app was last updated.
111    #[cfg_attr(feature = "tracing", tracing::instrument)]
112    pub fn updated_at(&self) -> &DateTime<Utc> {
113        &self.updated_at
114    }
115
116    /// Returns the app's permissions.
117    #[cfg_attr(feature = "tracing", tracing::instrument)]
118    pub fn permissions(&self) -> &HashMap<String, String> {
119        &self.permissions
120    }
121
122    /// Returns the events to which the app is subscribed.
123    #[cfg_attr(feature = "tracing", tracing::instrument)]
124    pub fn events(&self) -> &Vec<String> {
125        &self.events
126    }
127}
128
129impl Display for App {
130    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
131        write!(f, "{}", self.name)
132    }
133}
134
135#[cfg(test)]
136mod tests {
137    use super::App;
138
139    #[test]
140    fn trait_deserialize() {
141        let app: App =
142            serde_json::from_str(include_str!("../../tests/fixtures/resource/app.json")).unwrap();
143
144        assert_eq!("devxbots/checkbot", app.name().get());
145    }
146
147    #[test]
148    fn trait_display() {
149        let app: App =
150            serde_json::from_str(include_str!("../../tests/fixtures/resource/app.json")).unwrap();
151
152        assert_eq!("devxbots/checkbot", app.to_string());
153    }
154
155    #[test]
156    fn trait_send() {
157        fn assert_send<T: Send>() {}
158        assert_send::<App>();
159    }
160
161    #[test]
162    fn trait_sync() {
163        fn assert_sync<T: Sync>() {}
164        assert_sync::<App>();
165    }
166}