jotta_fs/
files.rs

1//! Utilities for the API at `api.jottacloud.com/files/v1`.
2use std::ops::RangeInclusive;
3
4use chrono::{DateTime, Utc};
5use md5::Digest;
6
7use serde::{Deserialize, Serialize};
8use serde_with::serde_as;
9
10use crate::{jfs::RevisionState, path::PathOnDevice};
11
12/// Allocation request.
13#[serde_as]
14#[derive(Debug, Serialize)]
15pub struct AllocReq<'a> {
16    /// Path of the file to be uploaded.
17    pub path: &'a PathOnDevice,
18
19    /// How many *more* bytes to allocate.
20    pub bytes: u64,
21
22    /// [MD5](https://en.wikipedia.org/wiki/MD5) checksum. For some reason, Jottacloud seems to deduplicate files.
23    #[serde(with = "crate::serde::md5_hex")]
24    pub md5: md5::Digest,
25
26    /// Handle conflicts.
27    pub conflict_handler: ConflictHandler,
28
29    /// Creation date of the file.
30    #[serde_as(as = "Option<serde_with::TimestampMilliSeconds<i64>>")]
31    #[serde(skip_serializing_if = "Option::is_none")]
32    pub created: Option<DateTime<Utc>>,
33
34    /// Modification date of the file to be uploaded.
35    #[serde_as(as = "Option<serde_with::TimestampMilliSeconds<i64>>")]
36    #[serde(skip_serializing_if = "Option::is_none")]
37    pub modified: Option<DateTime<Utc>>,
38}
39
40/// Handle conflicts when allocating/uploading a file.
41#[derive(Debug, Serialize, Deserialize)]
42#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
43pub enum ConflictHandler {
44    /// Reject all conflicts.
45    RejectConflicts,
46    /// Create a new revision if the file already exists.
47    CreateNewRevision,
48}
49
50/// Allocation response.
51#[derive(Debug, Deserialize)]
52pub struct AllocRes {
53    /// Name of the file.
54    pub name: String,
55
56    /// Path.
57    pub path: PathOnDevice,
58
59    /// State of the file upload (and revision).
60    pub state: RevisionState,
61
62    /// Id of the upload. Might be a JWT.
63    pub upload_id: String,
64
65    /// Upload url. I think you still need your bearer token to upload.
66    pub upload_url: String,
67
68    /// Total number of bytes to upload.
69    pub bytes: u64,
70
71    /// Where to resume the upload from, if the upload is chunked for instance.
72    pub resume_pos: u64,
73}
74
75/// Successful upload response.
76#[serde_as]
77#[derive(Debug, Deserialize)]
78pub struct CompleteUploadRes {
79    /// MD5 sum of the upload. If it doesn't match the one specified
80    /// in the allocation request, the revision will probably be considered
81    /// corrupt by Jottacloud.
82    #[serde(with = "crate::serde::md5_hex")]
83    pub md5: Digest,
84
85    /// Bytes uploaded in total.
86    pub bytes: u64,
87
88    /// Content id?
89    pub content_id: String,
90
91    /// Path.
92    pub path: PathOnDevice,
93
94    /// Modification date.
95    #[serde_as(as = "serde_with::TimestampMilliSeconds<i64>")]
96    pub modified: DateTime<Utc>,
97}
98
99/// Pretty-print of the Jottacloud exception returned when performing a
100/// chunked upload.
101#[derive(Debug)]
102pub struct IncompleteUploadRes {
103    /// Range of the bytes uploaded now -- NOT the total bytes uploaded (for all chunks).
104    pub range: RangeInclusive<u64>,
105}
106
107/// Upload response.
108#[derive(Debug)]
109pub enum UploadRes {
110    /// Complete upload.
111    Complete(CompleteUploadRes),
112    /// Incomplete upload.
113    Incomplete(IncompleteUploadRes),
114}