From 089a91d5a29e546274ff5e954baf7416d3db5366 Mon Sep 17 00:00:00 2001 From: yggverse Date: Thu, 23 Jan 2025 11:46:43 +0200 Subject: [PATCH] remove scheme from scope, rename build constructors --- src/app/browser/window/tab/item.rs | 4 +- src/app/browser/window/tab/item/identity.rs | 12 +++--- .../item/identity/{gemini.rs => default.rs} | 41 +++++++++++++------ .../identity/{gemini => default}/widget.rs | 10 ++--- .../{gemini => default}/widget/action.rs | 0 .../widget/action/update.rs | 0 .../{gemini => default}/widget/form.rs | 26 ++++++------ .../{gemini => default}/widget/form/drop.rs | 2 +- .../{gemini => default}/widget/form/exit.rs | 33 ++++++++------- .../{gemini => default}/widget/form/file.rs | 2 +- .../{gemini => default}/widget/form/list.rs | 6 +-- .../widget/form/list/item.rs | 0 .../widget/form/list/item/error.rs | 0 .../widget/form/list/item/imp.rs | 0 .../widget/form/list/item/is_active.rs | 0 .../widget/form/list/item/subtitle.rs | 0 .../widget/form/list/item/title.rs | 0 .../widget/form/list/item/tooltip.rs | 0 .../widget/form/list/item/value.rs | 0 .../{gemini => default}/widget/form/name.rs | 2 +- .../{gemini => default}/widget/form/save.rs | 2 +- .../widget/form/save/certificate.rs | 0 .../widget/form/save/certificate/error.rs | 0 .../window/tab/item/page/navigation.rs | 10 +---- src/profile/identity/auth/memory.rs | 25 ++++++++++- 25 files changed, 103 insertions(+), 72 deletions(-) rename src/app/browser/window/tab/item/identity/{gemini.rs => default.rs} (78%) rename src/app/browser/window/tab/item/identity/{gemini => default}/widget.rs (96%) rename src/app/browser/window/tab/item/identity/{gemini => default}/widget/action.rs (100%) rename src/app/browser/window/tab/item/identity/{gemini => default}/widget/action/update.rs (100%) rename src/app/browser/window/tab/item/identity/{gemini => default}/widget/form.rs (83%) rename src/app/browser/window/tab/item/identity/{gemini => default}/widget/form/drop.rs (98%) rename src/app/browser/window/tab/item/identity/{gemini => default}/widget/form/exit.rs (81%) rename src/app/browser/window/tab/item/identity/{gemini => default}/widget/form/file.rs (98%) rename src/app/browser/window/tab/item/identity/{gemini => default}/widget/form/list.rs (97%) rename src/app/browser/window/tab/item/identity/{gemini => default}/widget/form/list/item.rs (100%) rename src/app/browser/window/tab/item/identity/{gemini => default}/widget/form/list/item/error.rs (100%) rename src/app/browser/window/tab/item/identity/{gemini => default}/widget/form/list/item/imp.rs (100%) rename src/app/browser/window/tab/item/identity/{gemini => default}/widget/form/list/item/is_active.rs (100%) rename src/app/browser/window/tab/item/identity/{gemini => default}/widget/form/list/item/subtitle.rs (100%) rename src/app/browser/window/tab/item/identity/{gemini => default}/widget/form/list/item/title.rs (100%) rename src/app/browser/window/tab/item/identity/{gemini => default}/widget/form/list/item/tooltip.rs (100%) rename src/app/browser/window/tab/item/identity/{gemini => default}/widget/form/list/item/value.rs (100%) rename src/app/browser/window/tab/item/identity/{gemini => default}/widget/form/name.rs (96%) rename src/app/browser/window/tab/item/identity/{gemini => default}/widget/form/save.rs (99%) rename src/app/browser/window/tab/item/identity/{gemini => default}/widget/form/save/certificate.rs (100%) rename src/app/browser/window/tab/item/identity/{gemini => default}/widget/form/save/certificate/error.rs (100%) diff --git a/src/app/browser/window/tab/item.rs b/src/app/browser/window/tab/item.rs index ffd2d2d8..19172044 100644 --- a/src/app/browser/window/tab/item.rs +++ b/src/app/browser/window/tab/item.rs @@ -97,7 +97,7 @@ impl Item { // Route by scheme let scheme = uri.scheme(); if scheme == "gemini" || scheme == "titan" { - return identity::new_gemini( + return identity::default( (&browser_action, &window_action), &profile, &uri, @@ -106,7 +106,7 @@ impl Item { } } // Show dialog with unsupported request message - identity::new_unsupported().present(Some(&parent)); + identity::unsupported().present(Some(&parent)); } }); diff --git a/src/app/browser/window/tab/item/identity.rs b/src/app/browser/window/tab/item/identity.rs index e02cf858..adafd1ea 100644 --- a/src/app/browser/window/tab/item/identity.rs +++ b/src/app/browser/window/tab/item/identity.rs @@ -1,7 +1,7 @@ -mod gemini; +mod default; mod unsupported; -use gemini::Gemini; +use default::Default; use unsupported::Unsupported; use super::{BrowserAction, Profile, WindowAction}; @@ -9,15 +9,15 @@ use gtk::glib::Uri; use std::rc::Rc; /// Create new identity widget for Gemini protocol match given URI -pub fn new_gemini( +pub fn default( action: (&Rc, &Rc), profile: &Rc, auth_uri: &Uri, -) -> Gemini { - Gemini::new(action, profile, auth_uri) +) -> Default { + Default::build(action, profile, auth_uri) } /// Create new identity widget for unknown request -pub fn new_unsupported() -> Unsupported { +pub fn unsupported() -> Unsupported { Unsupported::new() } diff --git a/src/app/browser/window/tab/item/identity/gemini.rs b/src/app/browser/window/tab/item/identity/default.rs similarity index 78% rename from src/app/browser/window/tab/item/identity/gemini.rs rename to src/app/browser/window/tab/item/identity/default.rs index 6fe65e4a..666bab4b 100644 --- a/src/app/browser/window/tab/item/identity/gemini.rs +++ b/src/app/browser/window/tab/item/identity/default.rs @@ -2,31 +2,49 @@ mod widget; use widget::{form::list::item::value::Value, Widget}; use super::{BrowserAction, Profile, WindowAction}; -use gtk::{glib::Uri, prelude::IsA}; +use gtk::{ + glib::{Regex, RegexCompileFlags, RegexMatchFlags, Uri}, + prelude::IsA, +}; use std::rc::Rc; -pub struct Gemini { +pub struct Default { // profile: Rc, widget: Rc, } -impl Gemini { +impl Default { // Construct /// Create new `Self` for given `Profile` - pub fn new( + pub fn build( (browser_action, window_action): (&Rc, &Rc), profile: &Rc, auth_uri: &Uri, ) -> Self { - // Init shared URL string from URI + // Init scope let auth_url = auth_uri.to_string(); + let scope = match Regex::split_simple( + r"^\w+://(.*)", + &auth_url, + RegexCompileFlags::DEFAULT, + RegexMatchFlags::DEFAULT, + ) + .get(1) + { + Some(postfix) => postfix.to_string(), + None => auth_url, // @TODO warn? + } + .trim() + .trim_end_matches("/") + .to_lowercase(); + // Init widget - let widget = Rc::new(Widget::new( + let widget = Rc::new(Widget::build( (browser_action, window_action), profile, - auth_uri, + &scope, )); // Init events @@ -63,16 +81,15 @@ impl Gemini { // Apply auth match option { - // Activate identity for `auth_uri` + // Activate identity for `scope` Some(profile_identity_id) => { - if let Err(e) = profile.identity.auth.apply(profile_identity_id, &auth_url) - { + if let Err(e) = profile.identity.auth.apply(profile_identity_id, &scope) { todo!("{}", e.to_string()) }; } - // Remove all identity auths for `auth_uri` + // Remove all identity auths for `scope` None => { - if let Err(e) = profile.identity.auth.remove_scope(&auth_url) { + if let Err(e) = profile.identity.auth.remove_scope(&scope) { todo!("{}", e.to_string()) }; } diff --git a/src/app/browser/window/tab/item/identity/gemini/widget.rs b/src/app/browser/window/tab/item/identity/default/widget.rs similarity index 96% rename from src/app/browser/window/tab/item/identity/gemini/widget.rs rename to src/app/browser/window/tab/item/identity/default/widget.rs index b6ecc566..50088eeb 100644 --- a/src/app/browser/window/tab/item/identity/gemini/widget.rs +++ b/src/app/browser/window/tab/item/identity/default/widget.rs @@ -12,7 +12,7 @@ use adw::{ prelude::{AdwDialogExt, AlertDialogExt, AlertDialogExtManual}, AlertDialog, ResponseAppearance, }; -use gtk::{glib::Uri, prelude::IsA}; +use gtk::prelude::IsA; use std::rc::Rc; // Defaults @@ -36,19 +36,19 @@ impl Widget { // Constructors /// Create new `Self` - pub fn new( + pub fn build( (browser_action, window_action): (&Rc, &Rc), profile: &Rc, - auth_uri: &Uri, + scope: &str, ) -> Self { // Init actions let widget_action = Rc::new(WidgetAction::new()); // Init child container - let form = Rc::new(Form::new( + let form = Rc::new(Form::build( (browser_action, window_action, &widget_action), profile, - auth_uri, + scope, )); // Init main widget diff --git a/src/app/browser/window/tab/item/identity/gemini/widget/action.rs b/src/app/browser/window/tab/item/identity/default/widget/action.rs similarity index 100% rename from src/app/browser/window/tab/item/identity/gemini/widget/action.rs rename to src/app/browser/window/tab/item/identity/default/widget/action.rs diff --git a/src/app/browser/window/tab/item/identity/gemini/widget/action/update.rs b/src/app/browser/window/tab/item/identity/default/widget/action/update.rs similarity index 100% rename from src/app/browser/window/tab/item/identity/gemini/widget/action/update.rs rename to src/app/browser/window/tab/item/identity/default/widget/action/update.rs diff --git a/src/app/browser/window/tab/item/identity/gemini/widget/form.rs b/src/app/browser/window/tab/item/identity/default/widget/form.rs similarity index 83% rename from src/app/browser/window/tab/item/identity/gemini/widget/form.rs rename to src/app/browser/window/tab/item/identity/default/widget/form.rs index 2f00ac10..c8062679 100644 --- a/src/app/browser/window/tab/item/identity/gemini/widget/form.rs +++ b/src/app/browser/window/tab/item/identity/default/widget/form.rs @@ -17,7 +17,7 @@ use crate::{ app::browser::{action::Action as BrowserAction, window::action::Action as WindowAction}, Profile, }; -use gtk::{glib::Uri, prelude::BoxExt, Box, Orientation}; +use gtk::{prelude::BoxExt, Box, Orientation}; use std::rc::Rc; pub struct Form { @@ -29,7 +29,7 @@ pub struct Form { pub name: Rc, pub save: Rc, pub g_box: Box, - auth_uri: Uri, + scope: String, profile: Rc, } @@ -37,26 +37,26 @@ impl Form { // Constructors /// Create new `Self` - pub fn new( + pub fn build( (browser_action, _window_action, widget_action): ( &Rc, &Rc, &Rc, ), profile: &Rc, - auth_uri: &Uri, + scope: &str, ) -> Self { // Init components - let list = Rc::new(List::new(widget_action, profile, auth_uri)); - let file = Rc::new(File::new(widget_action)); - let name = Rc::new(Name::new(widget_action)); - let save = Rc::new(Save::new(profile, &list)); - let drop = Rc::new(Drop::new(profile, &list)); - let exit = Rc::new(Exit::new( + let list = Rc::new(List::build(widget_action, profile, scope)); + let file = Rc::new(File::build(widget_action)); + let name = Rc::new(Name::build(widget_action)); + let save = Rc::new(Save::build(profile, &list)); + let drop = Rc::new(Drop::build(profile, &list)); + let exit = Rc::new(Exit::build( (browser_action, widget_action), profile, &list, - auth_uri, + scope, )); // Init main container @@ -79,7 +79,7 @@ impl Form { name, save, g_box, - auth_uri: auth_uri.clone(), + scope: scope.to_string(), profile: profile.clone(), } } @@ -112,7 +112,7 @@ impl Form { .identity .auth .memory - .match_scope(&self.auth_uri.to_string()) + .match_scope(&self.scope) .is_some_and(|auth| auth.profile_identity_id == profile_identity_id), ); self.save.update(true); diff --git a/src/app/browser/window/tab/item/identity/gemini/widget/form/drop.rs b/src/app/browser/window/tab/item/identity/default/widget/form/drop.rs similarity index 98% rename from src/app/browser/window/tab/item/identity/gemini/widget/form/drop.rs rename to src/app/browser/window/tab/item/identity/default/widget/form/drop.rs index 34f44898..14b7133c 100644 --- a/src/app/browser/window/tab/item/identity/gemini/widget/form/drop.rs +++ b/src/app/browser/window/tab/item/identity/default/widget/form/drop.rs @@ -29,7 +29,7 @@ impl Drop { // Constructors /// Create new `Self` - pub fn new(profile: &Rc, list: &Rc) -> Self { + pub fn build(profile: &Rc, list: &Rc) -> Self { // Init main widget let button = Button::builder() .label(LABEL) diff --git a/src/app/browser/window/tab/item/identity/gemini/widget/form/exit.rs b/src/app/browser/window/tab/item/identity/default/widget/form/exit.rs similarity index 81% rename from src/app/browser/window/tab/item/identity/gemini/widget/form/exit.rs rename to src/app/browser/window/tab/item/identity/default/widget/form/exit.rs index 19be9ae5..8de9c1b6 100644 --- a/src/app/browser/window/tab/item/identity/gemini/widget/form/exit.rs +++ b/src/app/browser/window/tab/item/identity/default/widget/form/exit.rs @@ -8,7 +8,6 @@ use adw::{ AlertDialog, ResponseAppearance, }; use gtk::{ - glib::Uri, prelude::{ButtonExt, WidgetExt}, Button, }; @@ -33,11 +32,11 @@ impl Exit { // Constructors /// Create new `Self` - pub fn new( + pub fn build( (browser_action, widget_action): (&Rc, &Rc), profile: &Rc, list: &Rc, - auth_uri: &Uri, + scope: &str, ) -> Self { // Init main widget let button = Button::builder() @@ -49,7 +48,7 @@ impl Exit { // Init events button.connect_clicked({ - let auth_uri = auth_uri.clone(); + let scope = scope.to_string(); let browser_action = browser_action.clone(); let button = button.clone(); let list = list.clone(); @@ -84,7 +83,7 @@ impl Exit { // Connect confirmation event alert_dialog.connect_response(Some(RESPONSE_CONFIRM.0), { - let auth_uri = auth_uri.clone(); + let scope = scope.clone(); let button = button.clone(); let list = list.clone(); let profile = profile.clone(); @@ -92,19 +91,19 @@ impl Exit { let widget_action = widget_action.clone(); move |_, _| { match profile.identity.auth.remove_ref(profile_identity_id) { - Ok(_) => match list - .selected() - .update(&profile, &auth_uri.to_string()) - { - Ok(_) => { - button.set_css_classes(&["success"]); - button.set_label("Identity successfully disconnected") + Ok(_) => { + match list.selected().update(&profile, &scope.to_string()) { + Ok(_) => { + button.set_css_classes(&["success"]); + button + .set_label("Identity successfully disconnected") + } + Err(e) => { + button.set_css_classes(&["error"]); + button.set_label(&e.to_string()) + } } - Err(e) => { - button.set_css_classes(&["error"]); - button.set_label(&e.to_string()) - } - }, + } Err(e) => { button.set_css_classes(&["error"]); button.set_label(&e.to_string()) diff --git a/src/app/browser/window/tab/item/identity/gemini/widget/form/file.rs b/src/app/browser/window/tab/item/identity/default/widget/form/file.rs similarity index 98% rename from src/app/browser/window/tab/item/identity/gemini/widget/form/file.rs rename to src/app/browser/window/tab/item/identity/default/widget/form/file.rs index 2db475bd..3e7b9815 100644 --- a/src/app/browser/window/tab/item/identity/gemini/widget/form/file.rs +++ b/src/app/browser/window/tab/item/identity/default/widget/form/file.rs @@ -21,7 +21,7 @@ impl File { // Constructors /// Create new `Self` - pub fn new(widget_action: &Rc) -> Self { + pub fn build(widget_action: &Rc) -> Self { // Init PEM let pem = Rc::new(RefCell::new(None)); diff --git a/src/app/browser/window/tab/item/identity/gemini/widget/form/list.rs b/src/app/browser/window/tab/item/identity/default/widget/form/list.rs similarity index 97% rename from src/app/browser/window/tab/item/identity/gemini/widget/form/list.rs rename to src/app/browser/window/tab/item/identity/default/widget/form/list.rs index 1748a098..a93bff2f 100644 --- a/src/app/browser/window/tab/item/identity/gemini/widget/form/list.rs +++ b/src/app/browser/window/tab/item/identity/default/widget/form/list.rs @@ -11,7 +11,6 @@ use gtk::{ prelude::{Cast, CastNone}, ListStore, }, - glib::Uri, prelude::{BoxExt, ListItemExt, ObjectExt, WidgetExt}, Align, Box, DropDown, Image, Label, ListItem, Orientation, SignalListItemFactory, }; @@ -25,7 +24,7 @@ impl List { // Constructors /// Create new `Self` - pub fn new(widget_action: &Rc, profile: &Rc, auth_uri: &Uri) -> Self { + pub fn build(widget_action: &Rc, profile: &Rc, scope: &str) -> Self { // Init dropdown items let guest_session = Item::new_guest_session(); let generate_pem = Item::new_generate_pem(); @@ -42,8 +41,7 @@ impl List { Ok(identities) => { let mut is_guest_session = true; for identity in identities { - match Item::new_profile_identity_id(profile, identity.id, &auth_uri.to_string()) - { + match Item::new_profile_identity_id(profile, identity.id, scope) { Ok(item) => { if item.is_active() { is_guest_session = false; diff --git a/src/app/browser/window/tab/item/identity/gemini/widget/form/list/item.rs b/src/app/browser/window/tab/item/identity/default/widget/form/list/item.rs similarity index 100% rename from src/app/browser/window/tab/item/identity/gemini/widget/form/list/item.rs rename to src/app/browser/window/tab/item/identity/default/widget/form/list/item.rs diff --git a/src/app/browser/window/tab/item/identity/gemini/widget/form/list/item/error.rs b/src/app/browser/window/tab/item/identity/default/widget/form/list/item/error.rs similarity index 100% rename from src/app/browser/window/tab/item/identity/gemini/widget/form/list/item/error.rs rename to src/app/browser/window/tab/item/identity/default/widget/form/list/item/error.rs diff --git a/src/app/browser/window/tab/item/identity/gemini/widget/form/list/item/imp.rs b/src/app/browser/window/tab/item/identity/default/widget/form/list/item/imp.rs similarity index 100% rename from src/app/browser/window/tab/item/identity/gemini/widget/form/list/item/imp.rs rename to src/app/browser/window/tab/item/identity/default/widget/form/list/item/imp.rs diff --git a/src/app/browser/window/tab/item/identity/gemini/widget/form/list/item/is_active.rs b/src/app/browser/window/tab/item/identity/default/widget/form/list/item/is_active.rs similarity index 100% rename from src/app/browser/window/tab/item/identity/gemini/widget/form/list/item/is_active.rs rename to src/app/browser/window/tab/item/identity/default/widget/form/list/item/is_active.rs diff --git a/src/app/browser/window/tab/item/identity/gemini/widget/form/list/item/subtitle.rs b/src/app/browser/window/tab/item/identity/default/widget/form/list/item/subtitle.rs similarity index 100% rename from src/app/browser/window/tab/item/identity/gemini/widget/form/list/item/subtitle.rs rename to src/app/browser/window/tab/item/identity/default/widget/form/list/item/subtitle.rs diff --git a/src/app/browser/window/tab/item/identity/gemini/widget/form/list/item/title.rs b/src/app/browser/window/tab/item/identity/default/widget/form/list/item/title.rs similarity index 100% rename from src/app/browser/window/tab/item/identity/gemini/widget/form/list/item/title.rs rename to src/app/browser/window/tab/item/identity/default/widget/form/list/item/title.rs diff --git a/src/app/browser/window/tab/item/identity/gemini/widget/form/list/item/tooltip.rs b/src/app/browser/window/tab/item/identity/default/widget/form/list/item/tooltip.rs similarity index 100% rename from src/app/browser/window/tab/item/identity/gemini/widget/form/list/item/tooltip.rs rename to src/app/browser/window/tab/item/identity/default/widget/form/list/item/tooltip.rs diff --git a/src/app/browser/window/tab/item/identity/gemini/widget/form/list/item/value.rs b/src/app/browser/window/tab/item/identity/default/widget/form/list/item/value.rs similarity index 100% rename from src/app/browser/window/tab/item/identity/gemini/widget/form/list/item/value.rs rename to src/app/browser/window/tab/item/identity/default/widget/form/list/item/value.rs diff --git a/src/app/browser/window/tab/item/identity/gemini/widget/form/name.rs b/src/app/browser/window/tab/item/identity/default/widget/form/name.rs similarity index 96% rename from src/app/browser/window/tab/item/identity/gemini/widget/form/name.rs rename to src/app/browser/window/tab/item/identity/default/widget/form/name.rs index 6b84d0b3..4a968d8f 100644 --- a/src/app/browser/window/tab/item/identity/gemini/widget/form/name.rs +++ b/src/app/browser/window/tab/item/identity/default/widget/form/name.rs @@ -19,7 +19,7 @@ impl Name { // Constructors /// Create new `Self` - pub fn new(widget_action: &Rc) -> Self { + pub fn build(widget_action: &Rc) -> Self { // Init main gobject let entry = Entry::builder() .margin_top(MARGIN) diff --git a/src/app/browser/window/tab/item/identity/gemini/widget/form/save.rs b/src/app/browser/window/tab/item/identity/default/widget/form/save.rs similarity index 99% rename from src/app/browser/window/tab/item/identity/gemini/widget/form/save.rs rename to src/app/browser/window/tab/item/identity/default/widget/form/save.rs index f093d167..c0bdeda7 100644 --- a/src/app/browser/window/tab/item/identity/gemini/widget/form/save.rs +++ b/src/app/browser/window/tab/item/identity/default/widget/form/save.rs @@ -23,7 +23,7 @@ impl Save { // Constructors /// Create new `Self` - pub fn new(profile: &Rc, list: &Rc) -> Self { + pub fn build(profile: &Rc, list: &Rc) -> Self { // Init main widget let button = Button::builder() .label(LABEL) diff --git a/src/app/browser/window/tab/item/identity/gemini/widget/form/save/certificate.rs b/src/app/browser/window/tab/item/identity/default/widget/form/save/certificate.rs similarity index 100% rename from src/app/browser/window/tab/item/identity/gemini/widget/form/save/certificate.rs rename to src/app/browser/window/tab/item/identity/default/widget/form/save/certificate.rs diff --git a/src/app/browser/window/tab/item/identity/gemini/widget/form/save/certificate/error.rs b/src/app/browser/window/tab/item/identity/default/widget/form/save/certificate/error.rs similarity index 100% rename from src/app/browser/window/tab/item/identity/gemini/widget/form/save/certificate/error.rs rename to src/app/browser/window/tab/item/identity/default/widget/form/save/certificate/error.rs diff --git a/src/app/browser/window/tab/item/page/navigation.rs b/src/app/browser/window/tab/item/page/navigation.rs index 31741142..15a21d16 100644 --- a/src/app/browser/window/tab/item/page/navigation.rs +++ b/src/app/browser/window/tab/item/page/navigation.rs @@ -76,14 +76,8 @@ impl Navigation { .update(self.profile.bookmark.get(&request).is_ok()); self.history.update(); self.reload.update(!request.is_empty()); - self.request.update( - self.profile - .identity - .auth - .memory - .match_scope(&request) - .is_some(), - ); + self.request + .update(self.profile.identity.match_scope(&request).is_some()); self.home.update(); } diff --git a/src/profile/identity/auth/memory.rs b/src/profile/identity/auth/memory.rs index 7483adc0..af503225 100644 --- a/src/profile/identity/auth/memory.rs +++ b/src/profile/identity/auth/memory.rs @@ -65,8 +65,10 @@ impl Memory { let mut result = Vec::new(); // Get all records starts with `scope` + let query = filter_scope(request); + for (scope, &profile_identity_id) in self.index.borrow().iter() { - if request.starts_with(scope) { + if query.starts_with(scope) { result.push(Auth { profile_identity_id, scope: scope.clone(), @@ -81,3 +83,24 @@ impl Memory { result.first().cloned() } } + +/// Get valid identity scope for given URL +/// * helper function for different protocol drivers implementation +fn filter_scope(url: &str) -> String { + use gtk::glib::{Regex, RegexCompileFlags, RegexMatchFlags}; + + match Regex::split_simple( + r"^\w+://(.*)", + url, + RegexCompileFlags::DEFAULT, + RegexMatchFlags::DEFAULT, + ) + .get(1) + { + Some(postfix) => postfix.to_string(), + None => url.to_string(), + } + .trim() + .trim_end_matches("/") + .to_lowercase() +}