Compare commits

...

3 commits

4 changed files with 58 additions and 33 deletions

View file

@ -62,7 +62,7 @@ impl AppState {
if let Some(upl) = self.inner.peek_uploading() {
if bar.length().is_none() {
bar.set_length(upl.get_size());
bar.set_message(upl.get_name().to_owned());
bar.set_message(upl.get_name().to_string());
bar.enable_steady_tick(Duration::from_millis(100));
}

View file

@ -2,11 +2,7 @@ use std::{convert::Infallible, fmt, io, time::Duration};
use base64ct::{Base64UrlUnpadded, Encoding};
use blake2b_simd::Params as Blake2b;
use clap::{
Parser,
builder::{PossibleValuesParser, TypedValueParser},
value_parser,
};
use clap::{Parser, builder::TypedValueParser, value_parser};
use log::LevelFilter;
use crate::{
@ -25,14 +21,6 @@ pub struct Cli {
)]
timeout: Duration,
/// Protocol for Sharry instance
#[arg(
short, long,
default_value = "https", value_name = "VARIANT",
value_parser = PossibleValuesParser::new(["http", "https"]),
)]
protocol: String,
/// Number of times actions are retried
#[arg(short, long, default_value_t = 5, value_name = "N")]
retry_limit: u32,
@ -118,7 +106,7 @@ impl Cli {
#[must_use]
pub fn get_uri(&self) -> Uri {
Uri::new(&self.protocol, &self.url)
Uri::from(self.url.clone())
}
#[must_use]

View file

@ -54,13 +54,13 @@ impl TryFrom<String> for FileID {
fn try_from(value: String) -> crate::Result<Self> {
/// Pattern breakdown:
/// - `^([^:/?#]+)://` scheme (anything but `:/?#`) + `"://"`
/// - `([^/?#]+)` authority/host (anything but `/?#`)
/// - `/api/v2/alias/upload/` literal path segment
/// - `([^/]+)` capture SID (one or more non-slash chars)
/// - `/files/tus/` literal path segment
/// - `(?P<fid>[^/]+)` capture FID (one or more non-slash chars)
/// - `$` end of string
/// - `^([^:/?#]+)://` - scheme (anything but `:/?#`) + `"://"`
/// - `([^/?#]+)` - authority/host (anything but `/?#`)
/// - `/api/v2/alias/upload/` - literal path segment
/// - `([^/]+)` - capture SID (one or more non-slash chars)
/// - `/files/tus/` - literal path segment
/// - `(?P<fid>[^/]+)` - capture FID (one or more non-slash chars)
/// - `$` - end of string
static UPLOAD_URL_RE: LazyLock<Regex> = LazyLock::new(|| {
trace!("compiling UPLOAD_URL_RE");
@ -76,13 +76,13 @@ impl TryFrom<String> for FileID {
.captures(&value)
.and_then(|caps| caps.name("fid").map(|m| m.as_str()))
{
let result = Self(fid.to_owned());
let result = Self(fid.to_string());
debug!("{result:?}");
Ok(result)
} else {
Err(crate::Error::mismatch(
"<proto>://<base>/api/v2/alias/upload/<share>/files/tus/<file>",
"<proto>://<host>/api/v2/alias/upload/<share>/files/tus/<file>",
value,
))
}
@ -112,8 +112,8 @@ mod tests {
];
for (good, expected_fid) in cases {
let s = good.to_string();
let file_id = FileID::try_from(s.clone()).expect("URL should parse successfully");
let file_id =
FileID::try_from(good.to_string()).expect("URL should parse successfully");
assert_eq!(
file_id.0, expected_fid,
"Expected `{}` → FileID({}), got {:?}",
@ -143,7 +143,7 @@ mod tests {
match err {
crate::Error::Mismatch { expected, actual } => {
assert_eq!(
expected, "<proto>://<base>/api/v2/alias/upload/<share>/files/tus/<file>",
expected, "<proto>://<host>/api/v2/alias/upload/<share>/files/tus/<file>",
"Error should output expected format"
);
assert_eq!(actual, bad.to_string(), "Error should echo back the input");

View file

@ -1,6 +1,7 @@
use std::fmt;
use std::{fmt, sync::LazyLock};
use log::trace;
use log::{debug, trace};
use regex::Regex;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
@ -18,11 +19,47 @@ impl AsRef<[u8]> for Uri {
}
}
impl Uri {
pub fn new(protocol: impl fmt::Display, base_url: impl fmt::Display) -> Self {
Self(format!("{protocol}://{base_url}"))
}
impl From<String> for Uri {
fn from(value: String) -> Self {
fn parse_url(value: &str) -> Option<(String, String)> {
/// Pattern breakdown:
/// - `^(?P<scheme>[^:/?#]+)://` - capture scheme (anything but `:/?#`) + `"://"`
/// - `(?P<host>[^/?#]+)` - capture authority/host (anything but `/?#`)
/// - `(/.*)?` - maybe trailing slash and some path
/// - `$` - end of string
static SHARRY_URI_RE: LazyLock<Regex> = LazyLock::new(|| {
trace!("compiling SHARRY_URI_RE");
Regex::new(r"^(?P<scheme>[^:/?#]+)://(?P<host>[^/?#]+)(/.*)?$")
.expect("Regex compilation failed")
});
SHARRY_URI_RE.captures(value).map(|caps| {
let captured = |name| {
caps.name(name)
.expect(&format!("{name} not captured"))
.as_str()
.to_string()
};
(captured("scheme"), captured("host"))
})
}
trace!("TryFrom {value:?}");
if let Some((scheme, host)) = parse_url(&value) {
let result = Self(format!("{scheme}://{host}"));
debug!("{result:?}");
result
} else {
Self(value)
}
}
}
impl Uri {
fn endpoint(&self, path: fmt::Arguments) -> String {
let uri = format!("{}/api/v2/{path}", self.0);
trace!("endpoint: {uri:?}");