[wip] impl Client for ureq::Agent

This commit is contained in:
Jörn-Michael Miehe 2025-06-08 17:13:01 +00:00
parent 51ecab41bb
commit 90cecd015e
4 changed files with 68 additions and 8 deletions

View file

@ -2,7 +2,10 @@ use std::{error::Error, io};
use log::debug; use log::debug;
use super::api::{NewShareRequest, NewShareResponse, NotifyShareResponse, Uri}; use super::{
api::{NewShareRequest, NewShareResponse, NotifyShareResponse, Uri},
file::{FileChecked, FileUploading, SharryFile},
};
pub trait Client { pub trait Client {
fn sharry_share_create( fn sharry_share_create(
@ -19,7 +22,13 @@ pub trait Client {
share_id: &str, share_id: &str,
) -> Result<(), ClientError>; ) -> Result<(), ClientError>;
// fn sharry_file_create(&self); fn sharry_file_create(
&self,
uri: &Uri,
alias_id: &str,
share_id: &str,
file: FileChecked,
) -> Result<FileUploading, ClientError>;
// fn sharry_file_patch(&self); // fn sharry_file_patch(&self);
} }
@ -34,10 +43,10 @@ pub enum ClientError {
#[error("response parsing failed: {0}")] #[error("response parsing failed: {0}")]
ResponseParsing(String), ResponseParsing(String),
//
// #[error("unexpected response status: {actual} (expected {expected})")] #[error("unexpected response status: {actual} (expected {expected})")]
// ResponseStatus { actual: u64, expected: u64 }, ResponseStatus { actual: u16, expected: u16 },
//
#[error("unexpected response content: {0}")] #[error("unexpected response content: {0}")]
ResponseContent(String), ResponseContent(String),
// //
@ -95,4 +104,42 @@ impl Client for ureq::Agent {
Ok(()) Ok(())
} }
fn sharry_file_create(
&self,
uri: &Uri,
alias_id: &str,
share_id: &str,
file: FileChecked,
) -> Result<FileUploading, ClientError> {
let size = file.get_size();
let res = {
let endpoint = uri.get_endpoint(format!("alias/upload/{}/files/tus", share_id));
self.post(endpoint)
.header("Sharry-Alias", alias_id)
.header("Sharry-File-Name", file.get_name())
.header("Upload-Length", size)
.send_empty()
.map_err(|e| ClientError::Request(e.to_string()))?
};
if res.status() != ureq::http::StatusCode::CREATED {
return Err(ClientError::ResponseStatus {
actual: res.status().as_u16(),
expected: ureq::http::StatusCode::CREATED.as_u16(),
});
}
let location = (res.headers().get("Location"))
.ok_or_else(|| ClientError::ResponseParsing("Location header not found".to_owned()))?
.to_str()
.map_err(|_| ClientError::ResponseParsing("Location header invalid".to_owned()))?
.to_string();
debug!("patch uri: {location}");
Ok(FileUploading::new(file.into_path(), size, location))
}
} }

View file

@ -66,6 +66,10 @@ impl FileChecked {
} }
impl<'t> SharryFile<'t> for FileChecked { impl<'t> SharryFile<'t> for FileChecked {
fn into_path(self) -> PathBuf {
self.path
}
/// get a reference to the file's name /// get a reference to the file's name
/// ///
/// Uses `SharryFile::extract_file_name`, which may **panic**! /// Uses `SharryFile::extract_file_name`, which may **panic**!

View file

@ -1,7 +1,10 @@
mod checked; mod checked;
mod uploading; mod uploading;
use std::{ffi::OsStr, path::Path}; use std::{
ffi::OsStr,
path::{Path, PathBuf},
};
pub use checked::FileChecked; pub use checked::FileChecked;
pub use uploading::{ChunkState, FileUploading, UploadError}; pub use uploading::{ChunkState, FileUploading, UploadError};
@ -20,6 +23,8 @@ pub trait SharryFile<'t> {
.expect("bad file name") .expect("bad file name")
} }
fn into_path(self) -> PathBuf;
fn get_name(&'t self) -> &'t str; fn get_name(&'t self) -> &'t str;
fn get_size(&self) -> u64; fn get_size(&self) -> u64;

View file

@ -58,7 +58,7 @@ impl fmt::Display for FileUploading {
} }
impl FileUploading { impl FileUploading {
pub(super) fn new(path: PathBuf, size: u64, uri: String) -> Self { pub fn new(path: PathBuf, size: u64, uri: String) -> Self {
Self { Self {
path, path,
size, size,
@ -135,6 +135,10 @@ impl FileUploading {
} }
impl<'t> SharryFile<'t> for FileUploading { impl<'t> SharryFile<'t> for FileUploading {
fn into_path(self) -> PathBuf {
self.path
}
fn get_name(&'t self) -> &'t str { fn get_name(&'t self) -> &'t str {
<Self as SharryFile>::extract_file_name(&self.path) <Self as SharryFile>::extract_file_name(&self.path)
} }