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}
25
26#[derive(Debug, Deserialize)]
27pub struct RetainRequest {
28 pub oids: Vec<String>,
29 #[serde(default)]
30 pub dry_run: bool,
31}
32
33#[derive(Debug, Deserialize)]
34pub struct DedupeRequest {
35 #[serde(default)]
36 pub dry_run: bool,
37}
38
39#[derive(Debug, Serialize)]
40pub struct BatchResponse {
41 pub transfer: &'static str,
42 pub objects: Vec<ObjectSpec>,
43}
44
45#[derive(Debug, Serialize)]
46pub struct ObjectSpec {
47 #[serde(flatten)]
48 pub id: ObjectId,
49 #[serde(skip_serializing_if = "Option::is_none")]
50 pub actions: Option<Actions>,
51 #[serde(skip_serializing_if = "Option::is_none")]
52 pub error: Option<ObjectError>,
53}
54
55#[derive(Debug, Default, Serialize)]
56pub struct Actions {
57 #[serde(skip_serializing_if = "Option::is_none")]
58 pub upload: Option<Action>,
59 #[serde(skip_serializing_if = "Option::is_none")]
60 pub download: Option<Action>,
61 #[serde(skip_serializing_if = "Option::is_none")]
62 pub verify: Option<Action>,
63}
64
65#[derive(Debug, Serialize)]
66pub struct Action {
67 pub href: String,
68 pub expires_in: u32,
69}
70
71#[derive(Debug, Serialize)]
72pub struct ObjectError {
73 pub code: u16,
74 pub message: String,
75}
76
77impl ObjectSpec {
78 pub fn missing(id: ObjectId) -> Self {
79 Self {
80 id,
81 actions: None,
82 error: Some(ObjectError {
83 code: 404,
84 message: "object not found".into(),
85 }),
86 }
87 }
88
89 pub fn too_large(id: ObjectId, limit: u64) -> Self {
90 Self {
91 error: Some(ObjectError {
92 code: 413,
93 message: format!(
94 "object is {} bytes, over the {limit} byte limit this server accepts",
95 id.size
96 ),
97 }),
98 id,
99 actions: None,
100 }
101 }
102
103 pub fn over_quota(id: ObjectId, used: u64, limit: u64) -> Self {
104 Self {
105 id,
106 actions: None,
107 error: Some(ObjectError {
108 code: 507,
109 message: format!(
110 "this repository holds {used} bytes of its {limit} byte budget — collect what \
111 it no longer references, or ask for more room"
112 ),
113 }),
114 }
115 }
116}
117
118#[derive(Debug, Deserialize)]
119pub struct CreateLockRequest {
120 pub path: String,
121}
122
123#[derive(Debug, Deserialize)]
124pub struct ListLocksQuery {
125 pub path: Option<String>,
126 pub id: Option<String>,
127}
128
129#[derive(Debug, Default, Deserialize)]
130pub struct VerifyLocksRequest {}
131
132#[derive(Debug, Deserialize)]
133pub struct UnlockRequest {
134 #[serde(default)]
135 pub force: bool,
136}
137
138#[derive(Debug, Serialize)]
139pub struct LockResponse {
140 pub lock: Lock,
141}
142
143#[derive(Debug, Serialize)]
144pub struct ListLocksResponse {
145 pub locks: Vec<Lock>,
146 pub next_cursor: &'static str,
147}
148
149#[derive(Debug, Serialize)]
150pub struct VerifyLocksResponse {
151 pub ours: Vec<Lock>,
152 pub theirs: Vec<Lock>,
153 pub next_cursor: &'static str,
154}
155
156#[derive(Debug, Serialize)]
157pub struct StatsResponse {
158 pub objects: u64,
159 pub bytes: u64,
160 pub locks: usize,
161}