am_api/
lib.rs

1//! Apple music api
2#![deny(missing_docs)]
3
4use crate::error::Error;
5pub use celes;
6use reqwest::{header, RequestBuilder};
7
8pub mod error;
9pub mod primitive;
10pub mod request;
11pub mod resource;
12pub mod utils;
13
14/// Cast a Resource to a more specific type
15///
16/// # Examples
17///
18/// ```no_run,ignore
19/// use
20/// let a: Resource = ...;
21/// let b: &DoubleProperty = cast!(Property, DoubleProperty, &a).unwrap();
22/// ```
23#[macro_export]
24macro_rules! cast {
25    ($type:path, $field:expr) => {
26        match $field {
27            $type { data } => Some(data),
28            _ => None,
29        }
30    };
31}
32
33/// Apple music api client
34///
35/// Api client can be cloned safely as reqwest uses Arc internally
36#[derive(Clone)]
37pub struct ApiClient {
38    client: reqwest::Client,
39    storefront_country: celes::Country,
40    localization: String,
41}
42
43impl ApiClient {
44    /// Create a new [`ApiClient`] instance
45    pub fn new(
46        developer_token: &str,
47        media_user_token: &str,
48        storefront_country: celes::Country,
49    ) -> Result<ApiClient, Error> {
50        let mut headers = header::HeaderMap::new();
51
52        let mut authorization_header =
53            header::HeaderValue::from_str(&format!("Bearer {}", developer_token))?;
54        authorization_header.set_sensitive(true);
55        headers.insert(header::AUTHORIZATION, authorization_header);
56
57        let mut media_user_token_header = header::HeaderValue::from_str(media_user_token)?;
58        media_user_token_header.set_sensitive(true);
59        headers.insert("media-user-token", media_user_token_header);
60
61        let client = reqwest::Client::builder()
62            .default_headers(headers)
63            .build()?;
64
65        Ok(ApiClient {
66            client,
67            storefront_country,
68            localization: String::from("en-US"),
69        })
70    }
71
72    /// Get the default storefront country for this client
73    pub fn get_storefront_country(&self) -> celes::Country {
74        self.storefront_country
75    }
76
77    /// Get the default localization for this client
78    pub fn get_localization(&self) -> &str {
79        self.localization.as_str()
80    }
81
82    /// Set the default localization for this client
83    pub fn set_localization(&mut self, localization: &str) {
84        self.localization = localization.to_string();
85    }
86
87    /// Convenience method to make a GET request to an endpoint
88    pub fn get(&self, endpoint: &str) -> RequestBuilder {
89        self.client
90            .get(format!("https://api.music.apple.com{}", endpoint))
91            .query(&[("art[url]", "f")])
92    }
93
94    /// Convenience method to make a POST request to an endpoint
95    pub fn post(&self, endpoint: &str) -> RequestBuilder {
96        self.client
97            .post(format!("https://api.music.apple.com{}", endpoint))
98            .query(&[("art[url]", "f")])
99    }
100
101    /// Convenience method to make a PUT request to an endpoint
102    pub fn put(&self, endpoint: &str) -> RequestBuilder {
103        self.client
104            .put(format!("https://api.music.apple.com{}", endpoint))
105            .query(&[("art[url]", "f")])
106    }
107
108    /// Convenience method to make a DELETE request to an endpoint
109    pub fn delete(&self, endpoint: &str) -> RequestBuilder {
110        self.client
111            .delete(format!("https://api.music.apple.com{}", endpoint))
112            .query(&[("art[url]", "f")])
113    }
114}