shared/api/endpoints/image/
user.rs

1//! Routes for the user image library
2
3use crate::{
4    api::{ApiEndpoint, Method},
5    domain::{
6        image::{
7            user::{
8                UserImageCreatePath, UserImageCreateRequest, UserImageDeletePath, UserImageGetPath,
9                UserImageListPath, UserImageListQuery, UserImageListResponse, UserImageResponse,
10                UserImageUploadPath, UserImageUploadRequest, UserImageUploadResponse,
11            },
12            ImageId,
13        },
14        CreateResponse,
15    },
16    error::EmptyError,
17};
18
19/// List user library images.
20///
21/// # Notes
22/// * Request includes an optional query, called as a query string.
23pub struct List;
24impl ApiEndpoint for List {
25    type Path = UserImageListPath;
26    type Req = UserImageListQuery;
27    type Res = UserImageListResponse;
28    type Err = EmptyError;
29    const METHOD: Method = Method::Get;
30}
31
32/// Get an user library image by ID.
33///
34/// # Errors
35/// * [`NotFound`](http::StatusCode::NOT_FOUND) if the image with the requested ID is not found for the user.
36/// Note that it will still return NOT_FOUND if an user image with the ID exists but is not owner by the
37/// requesting user.
38/// * TODO other errors here...
39pub struct Get;
40impl ApiEndpoint for Get {
41    type Path = UserImageGetPath;
42    type Req = ();
43    type Res = UserImageResponse;
44    type Err = EmptyError;
45    const METHOD: Method = Method::Get;
46}
47
48/// Create an user library image.
49pub struct Create;
50impl ApiEndpoint for Create {
51    type Path = UserImageCreatePath;
52    type Req = UserImageCreateRequest;
53    type Res = CreateResponse<ImageId>;
54    type Err = EmptyError;
55    const METHOD: Method = Method::Post;
56}
57
58/// Upload an image to the user image library.
59/// # Flow:
60///
61/// 1. User requests an upload session URI directly to Google Cloud Storage
62///     a. User uploads to processing bucket
63/// 2. Firestore is notified of `processing = true, ready = false` status at document `uploads/media/user/{id}`
64/// 3. Animation is processed and uploaded to the final bucket
65/// 4. Firestore is notified of `processing = true, ready = true` status at document `uploads/media/user/{id}`
66///
67/// # Notes:
68///
69/// * Can be used to update the raw data associated with the image.
70/// * If the client wants to re-upload an image after it has been successfully processed, it must repeat
71/// the entire flow instead of uploading to the same session URI.
72///
73/// # Errors:
74///
75/// * [`401 - Unauthorized`](http::StatusCode::UNAUTHORIZED) if authorization is not valid.
76/// * [`403 - Forbidden`](http::StatusCode::FORBIDDEN) if the user does not have sufficient permission to perform the action.
77/// * [`501 - NotImplemented`](http::StatusCode::NOT_IMPLEMENTED) when the s3/gcs service is disabled.
78pub struct Upload;
79impl ApiEndpoint for Upload {
80    type Path = UserImageUploadPath;
81    // raw bytes
82    type Req = UserImageUploadRequest;
83    type Res = UserImageUploadResponse;
84    type Err = EmptyError;
85    const METHOD: Method = Method::Put;
86}
87
88/// Delete an image from the user library.
89///
90/// # Errors
91/// * [`NotFound`](http::StatusCode::NOT_FOUND) if the image with the requested ID is not found for the user.
92/// Note that it will still return NOT_FOUND if an user image with the ID exists but is not owner by the
93/// requesting user.
94/// * TODO other errors here...
95pub struct Delete;
96impl ApiEndpoint for Delete {
97    type Path = UserImageDeletePath;
98    type Req = ();
99    type Res = ();
100    type Err = EmptyError;
101    const METHOD: Method = Method::Delete;
102}