shopify_sdk/rest/resources/v2025_10/
user.rs1use serde::{Deserialize, Serialize};
39
40use crate::clients::RestClient;
41use crate::rest::{
42 ReadOnlyResource, ResourceError, ResourceOperation, ResourcePath, ResourceResponse,
43 RestResource,
44};
45use crate::HttpMethod;
46
47#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
75pub struct User {
76 #[serde(skip_serializing)]
78 pub id: Option<u64>,
79
80 #[serde(skip_serializing)]
82 pub first_name: Option<String>,
83
84 #[serde(skip_serializing)]
86 pub last_name: Option<String>,
87
88 #[serde(skip_serializing)]
90 pub email: Option<String>,
91
92 #[serde(skip_serializing)]
94 pub phone: Option<String>,
95
96 #[serde(skip_serializing)]
98 pub url: Option<String>,
99
100 #[serde(skip_serializing)]
102 pub bio: Option<String>,
103
104 #[serde(skip_serializing)]
106 pub im: Option<String>,
107
108 #[serde(skip_serializing)]
110 pub screen_name: Option<String>,
111
112 #[serde(skip_serializing)]
114 pub locale: Option<String>,
115
116 #[serde(skip_serializing)]
118 pub user_type: Option<String>,
119
120 #[serde(skip_serializing)]
122 pub account_owner: Option<bool>,
123
124 #[serde(skip_serializing)]
126 pub receive_announcements: Option<i32>,
127
128 #[serde(skip_serializing)]
130 pub permissions: Option<Vec<String>>,
131
132 #[serde(skip_serializing)]
134 pub admin_graphql_api_id: Option<String>,
135}
136
137impl User {
138 pub async fn current(client: &RestClient) -> Result<ResourceResponse<Self>, ResourceError> {
150 let url = "users/current";
151 let response = client.get(url, None).await?;
152
153 if !response.is_ok() {
154 return Err(ResourceError::from_http_response(
155 response.code,
156 &response.body,
157 Self::NAME,
158 Some("current"),
159 response.request_id(),
160 ));
161 }
162
163 let key = Self::resource_key();
164 ResourceResponse::from_http_response(response, &key)
165 }
166}
167
168impl RestResource for User {
169 type Id = u64;
170 type FindParams = UserFindParams;
171 type AllParams = UserListParams;
172 type CountParams = ();
173
174 const NAME: &'static str = "User";
175 const PLURAL: &'static str = "users";
176
177 const PATHS: &'static [ResourcePath] = &[
182 ResourcePath::new(
183 HttpMethod::Get,
184 ResourceOperation::Find,
185 &["id"],
186 "users/{id}",
187 ),
188 ResourcePath::new(HttpMethod::Get, ResourceOperation::All, &[], "users"),
189 ];
192
193 fn get_id(&self) -> Option<Self::Id> {
194 self.id
195 }
196}
197
198impl ReadOnlyResource for User {}
199
200#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
202pub struct UserFindParams {
203 #[serde(skip_serializing_if = "Option::is_none")]
205 pub fields: Option<String>,
206}
207
208#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
210pub struct UserListParams {
211 #[serde(skip_serializing_if = "Option::is_none")]
213 pub limit: Option<u32>,
214
215 #[serde(skip_serializing_if = "Option::is_none")]
217 pub page_info: Option<String>,
218}
219
220#[cfg(test)]
221mod tests {
222 use super::*;
223 use crate::rest::{get_path, ReadOnlyResource, ResourceOperation, RestResource};
224
225 #[test]
226 fn test_user_implements_read_only_resource() {
227 fn assert_read_only<T: ReadOnlyResource>() {}
228 assert_read_only::<User>();
229 }
230
231 #[test]
232 fn test_user_deserialization() {
233 let json = r#"{
234 "id": 548380009,
235 "first_name": "John",
236 "last_name": "Smith",
237 "email": "john@example.com",
238 "phone": "+1-555-0100",
239 "url": "https://store.myshopify.com/admin/users/548380009",
240 "bio": "Store manager",
241 "im": null,
242 "screen_name": null,
243 "locale": "en",
244 "user_type": "regular",
245 "account_owner": false,
246 "receive_announcements": 1,
247 "permissions": ["full"],
248 "admin_graphql_api_id": "gid://shopify/StaffMember/548380009"
249 }"#;
250
251 let user: User = serde_json::from_str(json).unwrap();
252
253 assert_eq!(user.id, Some(548380009));
254 assert_eq!(user.first_name, Some("John".to_string()));
255 assert_eq!(user.last_name, Some("Smith".to_string()));
256 assert_eq!(user.email, Some("john@example.com".to_string()));
257 assert_eq!(user.phone, Some("+1-555-0100".to_string()));
258 assert_eq!(user.locale, Some("en".to_string()));
259 assert_eq!(user.user_type, Some("regular".to_string()));
260 assert_eq!(user.account_owner, Some(false));
261 assert_eq!(user.receive_announcements, Some(1));
262 assert_eq!(user.permissions, Some(vec!["full".to_string()]));
263 }
264
265 #[test]
266 fn test_user_read_only_paths() {
267 let find_path = get_path(User::PATHS, ResourceOperation::Find, &["id"]);
269 assert!(find_path.is_some());
270 assert_eq!(find_path.unwrap().template, "users/{id}");
271
272 let all_path = get_path(User::PATHS, ResourceOperation::All, &[]);
274 assert!(all_path.is_some());
275 assert_eq!(all_path.unwrap().template, "users");
276
277 let count_path = get_path(User::PATHS, ResourceOperation::Count, &[]);
279 assert!(count_path.is_none());
280
281 let create_path = get_path(User::PATHS, ResourceOperation::Create, &[]);
283 assert!(create_path.is_none());
284
285 let update_path = get_path(User::PATHS, ResourceOperation::Update, &["id"]);
286 assert!(update_path.is_none());
287
288 let delete_path = get_path(User::PATHS, ResourceOperation::Delete, &["id"]);
289 assert!(delete_path.is_none());
290 }
291
292 #[test]
293 fn test_user_current_method_exists() {
294 let _: fn(
298 &RestClient,
299 ) -> std::pin::Pin<
300 Box<
301 dyn std::future::Future<Output = Result<ResourceResponse<User>, ResourceError>>
302 + Send
303 + '_,
304 >,
305 > = |client| Box::pin(User::current(client));
306 }
307
308 #[test]
309 fn test_user_constants() {
310 assert_eq!(User::NAME, "User");
311 assert_eq!(User::PLURAL, "users");
312 }
313
314 #[test]
315 fn test_user_get_id() {
316 let user_with_id = User {
317 id: Some(548380009),
318 first_name: Some("John".to_string()),
319 ..Default::default()
320 };
321 assert_eq!(user_with_id.get_id(), Some(548380009));
322
323 let user_without_id = User::default();
324 assert_eq!(user_without_id.get_id(), None);
325 }
326
327 #[test]
328 fn test_user_all_fields_are_read_only() {
329 let user = User {
331 id: Some(548380009),
332 first_name: Some("John".to_string()),
333 last_name: Some("Smith".to_string()),
334 email: Some("john@example.com".to_string()),
335 phone: Some("+1-555-0100".to_string()),
336 locale: Some("en".to_string()),
337 user_type: Some("regular".to_string()),
338 account_owner: Some(true),
339 receive_announcements: Some(1),
340 permissions: Some(vec!["full".to_string()]),
341 ..Default::default()
342 };
343
344 let json = serde_json::to_value(&user).unwrap();
345 assert_eq!(json, serde_json::json!({}));
347 }
348}