1use crate::*;
2use serde::{Serialize, Deserialize};
3use serde_json::Value;
4
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct Album {
8 pub cant_migrate_condition: Value,
9 pub create_time: i64,
10 pub end_time: i64,
11 pub freeze_album: bool,
12 pub id: i64,
13 pub item_count: i64,
14 pub name: String,
15 pub owner_user_id: i64,
16 pub passphrase: String,
17 pub shared: bool,
18 pub sort_by: String,
19 pub sort_direction: String,
20 pub start_time: i64,
21 pub temporary_shared: bool,
22 #[serde(rename = "type")]
23 pub type_field: String,
24 pub version: i64,
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct CreateResponse {
29 pub album: Album,
30 pub error_list: Vec<Value>,
31}
32
33#[derive(Debug, Clone)]
34pub struct CreateRequest {
35 pub name: String,
36 pub items: Vec<i64>,
37}
38
39impl Request for CreateRequest {
40 type Response = CreateResponse;
41 fn query(&self) -> String {
42 let Self {name, items} = self;
43 let name = urlencoding::encode(name);
44 format!("api=SYNO.Foto.Browse.NormalAlbum&method=create&version=1&name={name}&item={items:?}")
45 }
46}
47
48#[test]
49fn test_parse_create_response() {
50 let response = include_str!("test/create-album-response.json");
51 let parsed: Response<CreateResponse> = serde_json::from_str(response).unwrap();
52 let data = parsed.body.as_result().unwrap();
53 assert_eq!("normal".to_owned(), data.album.type_field);
54 assert!(data.error_list.is_empty());
55}
56
57
58
59#[derive(Debug, Clone, Serialize, Deserialize)]
60pub struct AddItemsResponse {
61 pub error_list: Vec<Value>,
62}
63
64#[derive(Debug, Clone)]
65pub enum Destination {
66 Owned(i64),
67 Shared(String)
68}
69
70#[derive(Debug, Clone)]
71pub struct AddItemsRequest {
72 destination: Destination,
73 items: Vec<i64>
74}
75
76impl Request for AddItemsRequest {
77 type Response = AddItemsResponse;
78
79 fn query(&self) -> String {
80 let destination = match &self.destination {
81 Destination::Owned(id) => format!("id={id}"),
82 Destination::Shared(token) => format!("passphrase={token}"),
83 };
84 format!("api=SYNO.Foto.Browse.NormalAlbum&method=add_item&version=1&item={:?}&{destination}", self.items)
85 }
86}
87
88
89#[derive(Debug, Clone, Serialize, Deserialize)]
90pub struct ListResponse {
91 pub list: Vec<Album>,
92}
93
94#[derive(Default, Debug, Clone)]
95pub struct ListRequest {
96 pub offset: u32,
97 pub limit: u32,
98}
99
100impl Request for ListRequest {
101 type Response = ListResponse;
102 fn query(&self) -> String {
103 let Self { offset, limit } = self;
104 format!("api=SYNO.Foto.Browse.Album&method=list&version=2&offset={offset}&limit={limit}")
105 }
106}
107
108#[test]
109fn test_parse_album_list_response() {
110 let response = include_str!("test/album-list-response.json");
111 let parsed: Response<ListResponse> = serde_json::from_str(response).unwrap();
112 assert!(parsed.body.as_result().is_ok());
113}
114
115#[derive(Default, Debug, Clone)]
116pub struct ListSharedRequest {
117 pub offset: u32,
118 pub limit: u32,
119}
120
121impl Request for ListSharedRequest {
122 type Response = ListResponse;
123
124 fn query(&self) -> String {
125 let Self { offset, limit } = self;
126 format!("api=SYNO.Foto.Sharing.Misc&method=list_shared_with_me_album&version=2&offset={offset}&limit={limit}")
127 }
128}