1use serde::{Deserialize, Serialize};
2
3use crate::locks::Lock;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
6#[serde(rename_all = "lowercase")]
7pub enum Operation {
8 Upload,
9 Download,
10}
11
12#[derive(Debug, Clone, Deserialize, Serialize)]
13pub struct ObjectId {
14 pub oid: String,
15 pub size: u64,
16}
17
18#[derive(Debug, Deserialize)]
19pub struct BatchRequest {
20 pub operation: Operation,
21 #[serde(default)]
22 pub transfers: Vec<String>,
23 pub objects: Vec<ObjectId>,
24 #[serde(rename = "ref")]
25 pub reference: Option<Reference>,
26}
27
28#[derive(Debug, Deserialize)]
29pub struct RetainRequest {
30 pub oids: Vec<String>,
31 #[serde(default)]
32 pub dry_run: bool,
33}
34
35#[derive(Debug, Deserialize)]
36pub struct CompressRequest {
37 #[serde(default)]
38 pub dry_run: bool,
39}
40
41#[derive(Debug, Deserialize)]
42pub struct DedupeRequest {
43 #[serde(default)]
44 pub dry_run: bool,
45}
46
47#[derive(Debug, Serialize)]
48pub struct BatchResponse {
49 pub transfer: &'static str,
50 pub objects: Vec<ObjectSpec>,
51}
52
53#[derive(Debug, Serialize)]
54pub struct ObjectSpec {
55 #[serde(flatten)]
56 pub id: ObjectId,
57 #[serde(skip_serializing_if = "Option::is_none")]
58 pub actions: Option<Actions>,
59 #[serde(skip_serializing_if = "Option::is_none")]
60 pub error: Option<ObjectError>,
61}
62
63#[derive(Debug, Default, Serialize)]
64pub struct Actions {
65 #[serde(skip_serializing_if = "Option::is_none")]
66 pub upload: Option<Action>,
67 #[serde(skip_serializing_if = "Option::is_none")]
68 pub download: Option<Action>,
69 #[serde(skip_serializing_if = "Option::is_none")]
70 pub verify: Option<Action>,
71}
72
73#[derive(Debug, Serialize)]
74pub struct Action {
75 pub href: String,
76 pub expires_in: u32,
77}
78
79#[derive(Debug, Serialize)]
80pub struct ObjectError {
81 pub code: u16,
82 pub message: String,
83}
84
85impl ObjectSpec {
86 pub fn missing(id: ObjectId) -> Self {
87 Self {
88 id,
89 actions: None,
90 error: Some(ObjectError {
91 code: 404,
92 message: "object not found".into(),
93 }),
94 }
95 }
96
97 pub fn too_large(id: ObjectId, limit: u64) -> Self {
98 Self {
99 error: Some(ObjectError {
100 code: 413,
101 message: format!(
102 "object is {} bytes, over the {limit} byte limit this server accepts",
103 id.size
104 ),
105 }),
106 id,
107 actions: None,
108 }
109 }
110
111 pub fn over_quota(id: ObjectId, used: u64, limit: u64) -> Self {
112 Self {
113 id,
114 actions: None,
115 error: Some(ObjectError {
116 code: 507,
117 message: format!(
118 "this repository holds {used} bytes of its {limit} byte budget — collect what \
119 it no longer references, or ask for more room"
120 ),
121 }),
122 }
123 }
124}
125
126#[derive(Debug, Deserialize)]
127pub struct CreateLockRequest {
128 pub path: String,
129}
130
131#[derive(Debug, Deserialize)]
132pub struct ListLocksQuery {
133 pub path: Option<String>,
134 pub id: Option<String>,
135 pub cursor: Option<String>,
136 pub limit: Option<usize>,
137 #[serde(rename = "refspec")]
140 pub refspec: Option<String>,
141}
142
143#[derive(Debug, Default, Deserialize)]
144pub struct VerifyLocksRequest {
145 pub cursor: Option<String>,
146 pub limit: Option<usize>,
147 #[serde(rename = "ref")]
148 pub reference: Option<Reference>,
149}
150
151#[derive(Debug, Deserialize)]
152pub struct Reference {
153 pub name: String,
154}
155
156#[derive(Debug, Deserialize)]
157pub struct UnlockRequest {
158 #[serde(default)]
159 pub force: bool,
160}
161
162#[derive(Debug, Serialize)]
163pub struct LockResponse {
164 pub lock: Lock,
165}
166
167#[derive(Debug, Serialize)]
168pub struct ListLocksResponse {
169 pub locks: Vec<Lock>,
170 #[serde(skip_serializing_if = "String::is_empty")]
171 pub next_cursor: String,
172}
173
174#[derive(Debug, Serialize)]
175pub struct VerifyLocksResponse {
176 pub ours: Vec<Lock>,
177 pub theirs: Vec<Lock>,
178 #[serde(skip_serializing_if = "String::is_empty")]
179 pub next_cursor: String,
180}
181
182#[derive(Debug, Serialize)]
183pub struct StatsResponse {
184 pub objects: u64,
185 pub bytes: u64,
186 pub locks: usize,
187}