1use thiserror::Error;
2
3pub mod graphql;
4pub mod rest;
5pub mod utils;
6#[cfg(feature = "webhooks")]
7pub mod webhooks;
8
9#[derive(Clone, Debug)]
10pub struct Shopify {
11 pub api_version: String,
12 #[cfg(feature = "webhooks")]
13 shared_secret: Option<String>,
14 api_key: String,
15 query_url: String,
16 rest_url: String,
17 shop: String,
18}
19
20#[derive(Debug, Error)]
21pub enum ShopifyAPIError {
22 #[error("Connection failed")]
23 ConnectionFailed(#[from] reqwest::Error),
24
25 #[error("Response broken")]
26 ResponseBroken,
27
28 #[error("Not a JSON response: {0}")]
29 NotJson(String),
30
31 #[error("Not wanted JSON format: {0}")]
32 NotWantedJsonFormat(String),
33
34 #[error("Throttled")]
35 Throttled,
36
37 #[error("JSON parsing error: {0}")]
38 JsonParseError(#[from] serde_json::Error),
39
40 #[error("Other error: {0}")]
41 Other(String),
42}
43
44pub static VERSION: &str = "shopify_api/0.8";
45
46impl Shopify {
47 pub fn new(
56 shop: &str,
57 api_key: &str,
58 api_version: String,
59 #[cfg(feature = "webhooks")] shared_secret: Option<&str>,
60 ) -> Shopify {
61 let shop_domain = {
62 let mut shop_domain = shop.to_string();
63 if !shop_domain.ends_with(".myshopify.com") {
64 shop_domain.push_str(".myshopify.com");
65 }
66 shop_domain
67 };
68
69 let query_url = format!(
70 "https://{}/admin/api/{}/graphql.json",
71 shop_domain, api_version
72 );
73 let rest_url = format!("https://{}/admin/api/{}/", shop_domain, api_version);
74
75 Shopify {
76 api_version,
77 #[cfg(feature = "webhooks")]
78 shared_secret: shared_secret.map(|secret| secret.to_string()),
79 api_key: api_key.to_string(),
80 query_url,
81 rest_url,
82 shop: shop.to_string(),
83 }
84 }
85
86 pub fn get_shop(&self) -> &str {
94 self.shop.as_ref()
95 }
96
97 pub fn set_api_key(&mut self, api_key: &str) -> Result<&mut Shopify, String> {
107 if api_key.is_empty() {
108 return Err("API key cannot be empty".to_string());
109 }
110
111 self.api_key = api_key.to_string();
112 Ok(self)
113 }
114
115 pub fn get_query_url(&self) -> &str {
117 self.query_url.as_ref()
118 }
119
120 pub fn rest_url(&self) -> &str {
122 self.rest_url.as_ref()
123 }
124
125 pub fn get_api_endpoint(&self, endpoint: &str) -> String {
134 format!("{}{}", self.rest_url(), endpoint)
135 }
136}