From 470ebc4305f81a49fe983b9b03b1e292a6cdd397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn-Michael=20Miehe?= <40151420+ldericher@users.noreply.github.com> Date: Thu, 3 Jul 2025 12:58:53 +0000 Subject: [PATCH] `uri::Uri` creation --- src/cli.rs | 16 ++-------------- src/sharry/uri.rs | 49 +++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 45 insertions(+), 20 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index b6dc9ca..abc0237 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -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] diff --git a/src/sharry/uri.rs b/src/sharry/uri.rs index 793a133..2a257a5 100644 --- a/src/sharry/uri.rs +++ b/src/sharry/uri.rs @@ -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 for Uri { + fn from(value: String) -> Self { + fn parse_url(value: &str) -> Option<(String, String)> { + /// Pattern breakdown: + /// - `^(?P[^:/?#]+)://` - capture scheme (anything but `:/?#`) + `"://"` + /// - `(?P[^/?#]+)` - capture authority/host (anything but `/?#`) + /// - `(/.*)?` - maybe trailing slash and some path + /// - `$` - end of string + static SHARRY_URI_RE: LazyLock = LazyLock::new(|| { + trace!("compiling SHARRY_URI_RE"); + Regex::new(r"^(?P[^:/?#]+)://(?P[^/?#]+)(/.*)?$") + .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:?}");