remove async dependencies

This commit is contained in:
yggverse 2025-07-23 02:27:48 +03:00
parent e2b0cd6b0d
commit b187f36028
33 changed files with 120 additions and 129 deletions

View file

@ -10,12 +10,12 @@ use gtk::{
prelude::{ActionExt, ApplicationExt, ApplicationExtManual, GtkApplicationExt}, prelude::{ActionExt, ApplicationExt, ApplicationExtManual, GtkApplicationExt},
}; };
use sqlite::Transaction; use sqlite::Transaction;
use std::{rc::Rc, sync::Arc}; use std::rc::Rc;
const APPLICATION_ID: &str = "io.github.yggverse.Yoda"; const APPLICATION_ID: &str = "io.github.yggverse.Yoda";
pub struct App { pub struct App {
profile: Arc<Profile>, profile: Rc<Profile>,
application: Application, application: Application,
} }
@ -30,7 +30,7 @@ impl App {
.build(); .build();
// Init components // Init components
let profile = Arc::new(profile); let profile = Rc::new(profile);
let browser = Rc::new(Browser::build(&profile)); let browser = Rc::new(Browser::build(&profile));
// Prevent startup warning @TODO // Prevent startup warning @TODO

View file

@ -18,7 +18,7 @@ use gtk::{
prelude::GtkWindowExt, prelude::GtkWindowExt,
}; };
use sqlite::Transaction; use sqlite::Transaction;
use std::{rc::Rc, sync::Arc}; use std::rc::Rc;
pub struct Browser { pub struct Browser {
pub action: Rc<Action>, pub action: Rc<Action>,
@ -30,7 +30,7 @@ impl Browser {
// Constructors // Constructors
/// Build new `Self` /// Build new `Self`
pub fn build(profile: &Arc<Profile>) -> Browser { pub fn build(profile: &Rc<Profile>) -> Browser {
// Init components // Init components
let action = Rc::new(Action::new()); let action = Rc::new(Action::new());
let window = Rc::new(Window::build(profile, &action)); let window = Rc::new(Window::build(profile, &action));

View file

@ -11,7 +11,7 @@ use anyhow::Result;
use gtk::{Box, Orientation, prelude::BoxExt}; use gtk::{Box, Orientation, prelude::BoxExt};
use header::Header; use header::Header;
use sqlite::Transaction; use sqlite::Transaction;
use std::{rc::Rc, sync::Arc}; use std::rc::Rc;
use tab::Tab; use tab::Tab;
pub struct Window { pub struct Window {
@ -24,7 +24,7 @@ impl Window {
// Constructors // Constructors
/// Build new `Self` /// Build new `Self`
pub fn build(profile: &Arc<Profile>, browser_action: &Rc<BrowserAction>) -> Self { pub fn build(profile: &Rc<Profile>, browser_action: &Rc<BrowserAction>) -> Self {
// Init local actions // Init local actions
let action = Rc::new(Action::new()); let action = Rc::new(Action::new());

View file

@ -4,12 +4,12 @@ use super::{Action as WindowAction, BrowserAction, Profile};
use adw::{TabView, ToolbarView}; use adw::{TabView, ToolbarView};
use bar::Bar; use bar::Bar;
use gtk::Box; use gtk::Box;
use std::{rc::Rc, sync::Arc}; use std::rc::Rc;
pub trait Header { pub trait Header {
fn header( fn header(
action: (&Rc<BrowserAction>, &Rc<WindowAction>), action: (&Rc<BrowserAction>, &Rc<WindowAction>),
profile: &Arc<Profile>, profile: &Rc<Profile>,
tab_view: &TabView, tab_view: &TabView,
) -> Self; ) -> Self;
} }
@ -20,7 +20,7 @@ impl Header for ToolbarView {
/// Build new `Self` /// Build new `Self`
fn header( fn header(
(browser_action, window_action): (&Rc<BrowserAction>, &Rc<WindowAction>), (browser_action, window_action): (&Rc<BrowserAction>, &Rc<WindowAction>),
profile: &Arc<Profile>, profile: &Rc<Profile>,
tab_view: &TabView, tab_view: &TabView,
) -> Self { ) -> Self {
let toolbar_view = ToolbarView::builder().build(); let toolbar_view = ToolbarView::builder().build();

View file

@ -9,12 +9,12 @@ use tab::Tab;
use super::{BrowserAction, Profile, WindowAction}; use super::{BrowserAction, Profile, WindowAction};
use adw::{TabBar, TabView}; use adw::{TabBar, TabView};
use gtk::{Box, MenuButton, Orientation, prelude::BoxExt}; use gtk::{Box, MenuButton, Orientation, prelude::BoxExt};
use std::{rc::Rc, sync::Arc}; use std::rc::Rc;
pub trait Bar { pub trait Bar {
fn bar( fn bar(
action: (&Rc<BrowserAction>, &Rc<WindowAction>), action: (&Rc<BrowserAction>, &Rc<WindowAction>),
profile: &Arc<Profile>, profile: &Rc<Profile>,
view: &TabView, view: &TabView,
) -> Self; ) -> Self;
} }
@ -25,7 +25,7 @@ impl Bar for Box {
/// Build new `Self` /// Build new `Self`
fn bar( fn bar(
(browser_action, window_action): (&Rc<BrowserAction>, &Rc<WindowAction>), (browser_action, window_action): (&Rc<BrowserAction>, &Rc<WindowAction>),
profile: &Arc<Profile>, profile: &Rc<Profile>,
view: &TabView, view: &TabView,
) -> Self { ) -> Self {
let g_box = Box::builder() let g_box = Box::builder()

View file

@ -6,13 +6,13 @@ use gtk::{
prelude::{ActionExt, ToVariant}, prelude::{ActionExt, ToVariant},
}; };
use indexmap::IndexMap; use indexmap::IndexMap;
use std::{rc::Rc, sync::Arc}; use std::rc::Rc;
// Config options // Config options
const LABEL_MAX_LENGTH: usize = 28; const LABEL_MAX_LENGTH: usize = 28;
pub trait Menu { pub trait Menu {
fn menu(action: (&Rc<BrowserAction>, &Rc<WindowAction>), profile: &Arc<Profile>) -> Self; fn menu(action: (&Rc<BrowserAction>, &Rc<WindowAction>), profile: &Rc<Profile>) -> Self;
} }
#[rustfmt::skip] // @TODO template builder? #[rustfmt::skip] // @TODO template builder?
@ -22,7 +22,7 @@ impl Menu for MenuButton {
/// Build new `Self` /// Build new `Self`
fn menu( fn menu(
(browser_action, window_action): (&Rc<BrowserAction>, &Rc<WindowAction>), (browser_action, window_action): (&Rc<BrowserAction>, &Rc<WindowAction>),
profile: &Arc<Profile>, profile: &Rc<Profile>,
) -> Self { ) -> Self {
// Main // Main
let main = gio::Menu::new(); let main = gio::Menu::new();

View file

@ -13,12 +13,12 @@ pub use item::Item;
use menu::Menu; use menu::Menu;
use sourceview::prelude::IsA; use sourceview::prelude::IsA;
use sqlite::Transaction; use sqlite::Transaction;
use std::{cell::RefCell, collections::HashMap, rc::Rc, sync::Arc}; use std::{cell::RefCell, collections::HashMap, rc::Rc};
// Main // Main
pub struct Tab { pub struct Tab {
window_action: Rc<WindowAction>, window_action: Rc<WindowAction>,
profile: Arc<Profile>, profile: Rc<Profile>,
index: Rc<RefCell<HashMap<TabPage, Rc<Item>>>>, index: Rc<RefCell<HashMap<TabPage, Rc<Item>>>>,
pub action: Rc<Action>, pub action: Rc<Action>,
pub tab_view: TabView, pub tab_view: TabView,
@ -28,7 +28,7 @@ impl Tab {
// Constructors // Constructors
/// Build new `Self` /// Build new `Self`
pub fn build(profile: &Arc<Profile>, window_action: &Rc<WindowAction>) -> Self { pub fn build(profile: &Rc<Profile>, window_action: &Rc<WindowAction>) -> Self {
let action = Rc::new(Action::new()); let action = Rc::new(Action::new());
// Init empty HashMap index // Init empty HashMap index

View file

@ -15,7 +15,7 @@ use gtk::{
}; };
use page::Page; use page::Page;
use sqlite::Transaction; use sqlite::Transaction;
use std::{rc::Rc, sync::Arc}; use std::rc::Rc;
pub struct Item { pub struct Item {
// Multi-protocol handler // Multi-protocol handler
@ -32,7 +32,7 @@ impl Item {
/// Build new `Self` /// Build new `Self`
pub fn build( pub fn build(
(tab_page, target_child): (&TabPage, &Box), (tab_page, target_child): (&TabPage, &Box),
profile: &Arc<Profile>, profile: &Rc<Profile>,
(window_action, tab_action): (&Rc<WindowAction>, &Rc<TabAction>), (window_action, tab_action): (&Rc<WindowAction>, &Rc<TabAction>),
request: Option<&str>, request: Option<&str>,
is_load: bool, is_load: bool,

View file

@ -9,21 +9,21 @@ use gtk::{
glib::{Uri, UriFlags}, glib::{Uri, UriFlags},
prelude::CancellableExt, prelude::CancellableExt,
}; };
use std::{cell::Cell, rc::Rc, sync::Arc}; use std::{cell::Cell, rc::Rc};
/// Multi-protocol client API for tab `Item` /// Multi-protocol client API for tab `Item`
pub struct Client { pub struct Client {
cancellable: Cell<Cancellable>, cancellable: Cell<Cancellable>,
driver: Rc<Driver>, driver: Rc<Driver>,
page: Rc<Page>, page: Rc<Page>,
profile: Arc<Profile>, profile: Rc<Profile>,
} }
impl Client { impl Client {
// Constructors // Constructors
/// Create new `Self` /// Create new `Self`
pub fn init(profile: &Arc<Profile>, page: &Rc<Page>) -> Self { pub fn init(profile: &Rc<Profile>, page: &Rc<Page>) -> Self {
Self { Self {
cancellable: Cell::new(Cancellable::new()), cancellable: Cell::new(Cancellable::new()),
driver: Rc::new(Driver::build(page)), driver: Rc::new(Driver::build(page)),
@ -118,7 +118,7 @@ impl Client {
/// Create request using async DNS resolver (slow method) /// Create request using async DNS resolver (slow method)
/// * return suggestion [Uri](https://docs.gtk.org/glib/struct.Uri.html) on failure (to handle as redirect) /// * return suggestion [Uri](https://docs.gtk.org/glib/struct.Uri.html) on failure (to handle as redirect)
fn lookup( fn lookup(
profile: &Arc<Profile>, profile: &Rc<Profile>,
query: &str, query: &str,
cancellable: Cancellable, cancellable: Cancellable,
callback: impl FnOnce(Rc<Feature>, Cancellable, Result<Uri, String>) + 'static, callback: impl FnOnce(Rc<Feature>, Cancellable, Result<Uri, String>) + 'static,

View file

@ -13,10 +13,10 @@ use input::Input;
use navigation::Navigation; use navigation::Navigation;
use search::Search; use search::Search;
use sqlite::Transaction; use sqlite::Transaction;
use std::{rc::Rc, sync::Arc}; use std::rc::Rc;
pub struct Page { pub struct Page {
pub profile: Arc<Profile>, pub profile: Rc<Profile>,
// Actions // Actions
pub item_action: Rc<ItemAction>, pub item_action: Rc<ItemAction>,
pub window_action: Rc<WindowAction>, pub window_action: Rc<WindowAction>,
@ -38,7 +38,7 @@ impl Page {
// Constructors // Constructors
pub fn build( pub fn build(
profile: &Arc<Profile>, profile: &Rc<Profile>,
(window_action, tab_action, item_action): ( (window_action, tab_action, item_action): (
&Rc<WindowAction>, &Rc<WindowAction>,
&Rc<TabAction>, &Rc<TabAction>,

View file

@ -18,7 +18,7 @@ use home::Home;
use reload::Reload; use reload::Reload;
use request::Request; use request::Request;
use sqlite::Transaction; use sqlite::Transaction;
use std::{rc::Rc, sync::Arc}; use std::rc::Rc;
const MARGIN: i32 = 6; const MARGIN: i32 = 6;
const SPACING: i32 = 6; const SPACING: i32 = 6;
@ -31,7 +31,7 @@ pub struct Navigation {
impl Navigation { impl Navigation {
pub fn build( pub fn build(
profile: &Arc<Profile>, profile: &Rc<Profile>,
(window_action, tab_action, item_action): ( (window_action, tab_action, item_action): (
&Rc<WindowAction>, &Rc<WindowAction>,
&Rc<TabAction>, &Rc<TabAction>,

View file

@ -3,19 +3,19 @@ use gtk::{
Button, Entry, Button, Entry,
prelude::{ActionExt, ButtonExt, EditableExt, WidgetExt}, prelude::{ActionExt, ButtonExt, EditableExt, WidgetExt},
}; };
use std::{rc::Rc, sync::Arc}; use std::rc::Rc;
const ICON_NAME: (&str, &str) = ("non-starred-symbolic", "starred-symbolic"); const ICON_NAME: (&str, &str) = ("non-starred-symbolic", "starred-symbolic");
const TOOLTIP_TEXT: (&str, &str) = ("Add Bookmark", "Remove Bookmark"); const TOOLTIP_TEXT: (&str, &str) = ("Add Bookmark", "Remove Bookmark");
pub struct Bookmark { pub struct Bookmark {
profile: Arc<Profile>, profile: Rc<Profile>,
request: Entry, request: Entry,
pub button: Button, pub button: Button,
} }
impl Bookmark { impl Bookmark {
pub fn build(action: &Rc<WindowAction>, profile: &Arc<Profile>, request: &Entry) -> Self { pub fn build(action: &Rc<WindowAction>, profile: &Rc<Profile>, request: &Entry) -> Self {
let button = Button::builder() let button = Button::builder()
.action_name(format!( .action_name(format!(
"{}.{}", "{}.{}",
@ -65,7 +65,7 @@ fn icon_name(has_bookmark: bool) -> &'static str {
} }
} }
fn update(profile: &Arc<Profile>, button: &Button, request: gtk::glib::GString) { fn update(profile: &Rc<Profile>, button: &Button, request: gtk::glib::GString) {
let profile = profile.clone(); let profile = profile.clone();
let button = button.clone(); let button = button.clone();
gtk::glib::spawn_future_local(async move { gtk::glib::spawn_future_local(async move {

View file

@ -19,7 +19,6 @@ use sqlite::Transaction;
use std::{ use std::{
cell::{Cell, RefCell}, cell::{Cell, RefCell},
rc::Rc, rc::Rc,
sync::Arc,
}; };
use suggestion::Suggestion; use suggestion::Suggestion;
@ -30,14 +29,14 @@ pub struct Request {
pub entry: Entry, pub entry: Entry,
pub info: Rc<RefCell<Info>>, pub info: Rc<RefCell<Info>>,
suggestion: Rc<Suggestion>, suggestion: Rc<Suggestion>,
profile: Arc<Profile>, profile: Rc<Profile>,
} }
impl Request { impl Request {
// Constructors // Constructors
/// Build new `Self` /// Build new `Self`
pub fn build(item_action: &Rc<ItemAction>, profile: &Arc<Profile>) -> Self { pub fn build(item_action: &Rc<ItemAction>, profile: &Rc<Profile>) -> Self {
// Init components // Init components
let info = Rc::new(RefCell::new(Info::new())); let info = Rc::new(RefCell::new(Info::new()));
@ -364,7 +363,7 @@ fn is_focused(entry: &Entry) -> bool {
} }
/// Present Identity [AlertDialog](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.AlertDialog.html) for `Self` /// Present Identity [AlertDialog](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.AlertDialog.html) for `Self`
fn show_identity_dialog(entry: &Entry, profile: &Arc<Profile>) { fn show_identity_dialog(entry: &Entry, profile: &Rc<Profile>) {
// connect identity traits // connect identity traits
use identity::{Common, Unsupported}; use identity::{Common, Unsupported};
if let Some(uri) = uri(entry) { if let Some(uri) = uri(entry) {
@ -390,7 +389,7 @@ fn show_identity_dialog(entry: &Entry, profile: &Arc<Profile>) {
} }
/// Present Search providers [AlertDialog](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.AlertDialog.html) for `Self` /// Present Search providers [AlertDialog](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.AlertDialog.html) for `Self`
fn show_search_dialog(entry: &Entry, profile: &Arc<Profile>) { fn show_search_dialog(entry: &Entry, profile: &Rc<Profile>) {
use search::Search; use search::Search;
AlertDialog::search(profile).present(Some(entry)) AlertDialog::search(profile).present(Some(entry))
} }

View file

@ -5,16 +5,13 @@ use crate::Profile;
use action::Action as WidgetAction; use action::Action as WidgetAction;
use adw::AlertDialog; use adw::AlertDialog;
use gtk::{glib::Uri, prelude::EditableExt}; use gtk::{glib::Uri, prelude::EditableExt};
use std::{rc::Rc, sync::Arc}; use std::rc::Rc;
// Select options // Select options
pub trait Common { pub trait Common {
fn common( fn common(profile: &Rc<Profile>, request: &Uri, callback: &Rc<impl Fn(bool) + 'static>)
profile: &Arc<Profile>, -> Self;
request: &Uri,
callback: &Rc<impl Fn(bool) + 'static>,
) -> Self;
} }
impl Common for AlertDialog { impl Common for AlertDialog {
@ -22,7 +19,7 @@ impl Common for AlertDialog {
/// Create new `Self` /// Create new `Self`
fn common( fn common(
profile: &Arc<Profile>, profile: &Rc<Profile>,
request: &Uri, request: &Uri,
callback: &Rc<impl Fn(bool) + 'static>, callback: &Rc<impl Fn(bool) + 'static>,
) -> Self { ) -> Self {

View file

@ -19,7 +19,7 @@ use gtk::{
glib::Uri, glib::Uri,
prelude::{BoxExt, WidgetExt}, prelude::{BoxExt, WidgetExt},
}; };
use std::{rc::Rc, sync::Arc}; use std::rc::Rc;
pub struct Form { pub struct Form {
// pub action_widget: Rc<Action>, // pub action_widget: Rc<Action>,
@ -30,14 +30,14 @@ pub struct Form {
pub name: Entry, pub name: Entry,
pub save: Rc<Save>, pub save: Rc<Save>,
pub g_box: Box, pub g_box: Box,
profile: Arc<Profile>, profile: Rc<Profile>,
} }
impl Form { impl Form {
// Constructors // Constructors
/// Create new `Self` /// Create new `Self`
pub fn build(widget_action: &Rc<WidgetAction>, profile: &Arc<Profile>, request: &Uri) -> Self { pub fn build(widget_action: &Rc<WidgetAction>, profile: &Rc<Profile>, request: &Uri) -> Self {
// Init components // Init components
let list = Rc::new(List::build(widget_action, profile, request)); let list = Rc::new(List::build(widget_action, profile, request));
let file = Rc::new(File::build(widget_action)); let file = Rc::new(File::build(widget_action));

View file

@ -9,7 +9,7 @@ use gtk::{
glib::timeout_add_seconds_local_once, glib::timeout_add_seconds_local_once,
prelude::{ButtonExt, WidgetExt}, prelude::{ButtonExt, WidgetExt},
}; };
use std::{rc::Rc, sync::Arc}; use std::rc::Rc;
// Defaults // Defaults
@ -30,7 +30,7 @@ impl Drop {
// Constructors // Constructors
/// Create new `Self` /// Create new `Self`
pub fn build(profile: &Arc<Profile>, list: &Rc<List>) -> Self { pub fn build(profile: &Rc<Profile>, list: &Rc<List>) -> Self {
// Init main widget // Init main widget
let button = Button::builder() let button = Button::builder()
.label(LABEL) .label(LABEL)

View file

@ -8,12 +8,12 @@ use gtk::{
glib::{Uri, timeout_add_seconds_local_once}, glib::{Uri, timeout_add_seconds_local_once},
prelude::{ButtonExt, WidgetExt}, prelude::{ButtonExt, WidgetExt},
}; };
use std::{rc::Rc, sync::Arc}; use std::rc::Rc;
pub trait Exit { pub trait Exit {
fn exit( fn exit(
widget_action: &Rc<WidgetAction>, widget_action: &Rc<WidgetAction>,
profile: &Arc<Profile>, profile: &Rc<Profile>,
list: &Rc<List>, list: &Rc<List>,
request: &Uri, request: &Uri,
) -> Self; ) -> Self;
@ -25,7 +25,7 @@ impl Exit for Button {
/// Create new `Self` /// Create new `Self`
fn exit( fn exit(
widget_action: &Rc<WidgetAction>, widget_action: &Rc<WidgetAction>,
profile: &Arc<Profile>, profile: &Rc<Profile>,
list: &Rc<List>, list: &Rc<List>,
request: &Uri, request: &Uri,
) -> Self { ) -> Self {

View file

@ -1,5 +1,5 @@
pub mod item; pub mod item;
use std::{rc::Rc, sync::Arc}; use std::rc::Rc;
use item::Item; use item::Item;
@ -25,7 +25,7 @@ impl List {
// Constructors // Constructors
/// Create new `Self` /// Create new `Self`
pub fn build(widget_action: &Rc<WidgetAction>, profile: &Arc<Profile>, request: &Uri) -> Self { pub fn build(widget_action: &Rc<WidgetAction>, profile: &Rc<Profile>, request: &Uri) -> Self {
// Init dropdown items // Init dropdown items
let guest_session = Item::new_guest_session(); let guest_session = Item::new_guest_session();
let generate_pem = Item::new_generate_pem(); let generate_pem = Item::new_generate_pem();

View file

@ -14,7 +14,7 @@ use gtk::{
gio::TlsCertificate, gio::TlsCertificate,
glib::{self, Object}, glib::{self, Object},
}; };
use std::sync::Arc; use std::rc::Rc;
glib::wrapper! { glib::wrapper! {
pub struct Item(ObjectSubclass<imp::Item>); pub struct Item(ObjectSubclass<imp::Item>);
@ -54,7 +54,7 @@ impl Item {
} }
pub fn new_profile_identity_id( pub fn new_profile_identity_id(
profile: &Arc<Profile>, profile: &Rc<Profile>,
profile_identity_id: i64, profile_identity_id: i64,
auth_url: &str, auth_url: &str,
) -> Result<Self, Error> { ) -> Result<Self, Error> {
@ -96,7 +96,7 @@ impl Item {
// Actions // Actions
/// Update properties for `Self` for given `Profile` and `auth_url` /// Update properties for `Self` for given `Profile` and `auth_url`
pub fn update(&self, profile: &Arc<Profile>, auth_url: &str) -> Result<(), Error> { pub fn update(&self, profile: &Rc<Profile>, auth_url: &str) -> Result<(), Error> {
// Update item depending on value type // Update item depending on value type
match self.value_enum() { match self.value_enum() {
Value::ProfileIdentityId(profile_identity_id) => { Value::ProfileIdentityId(profile_identity_id) => {

View file

@ -1,8 +1,8 @@
use crate::profile::Profile; use crate::profile::Profile;
use std::sync::Arc; use std::rc::Rc;
pub fn new_for_profile_identity_id( pub fn new_for_profile_identity_id(
profile: &Arc<Profile>, profile: &Rc<Profile>,
profile_identity_id: i64, profile_identity_id: i64,
auth_url: &str, auth_url: &str,
) -> bool { ) -> bool {

View file

@ -9,7 +9,7 @@ use gtk::{
glib::{Priority, timeout_add_seconds_local_once}, glib::{Priority, timeout_add_seconds_local_once},
prelude::{ButtonExt, FileExt, OutputStreamExtManual, WidgetExt}, prelude::{ButtonExt, FileExt, OutputStreamExtManual, WidgetExt},
}; };
use std::{path::MAIN_SEPARATOR, rc::Rc, sync::Arc}; use std::{path::MAIN_SEPARATOR, rc::Rc};
const LABEL: &str = "Export"; const LABEL: &str = "Export";
const TOOLTIP_TEXT: &str = "Export selected identity to file"; const TOOLTIP_TEXT: &str = "Export selected identity to file";
@ -24,7 +24,7 @@ impl Save {
// Constructors // Constructors
/// Create new `Self` /// Create new `Self`
pub fn build(profile: &Arc<Profile>, list: &Rc<List>) -> Self { pub fn build(profile: &Rc<Profile>, list: &Rc<List>) -> Self {
// Init main widget // Init main widget
let button = Button::builder() let button = Button::builder()
.label(LABEL) .label(LABEL)

View file

@ -2,7 +2,7 @@ use anyhow::{Result, bail};
use crate::profile::Profile; use crate::profile::Profile;
use gtk::{gio::TlsCertificate, prelude::TlsCertificateExt}; use gtk::{gio::TlsCertificate, prelude::TlsCertificateExt};
use std::sync::Arc; use std::rc::Rc;
/// Certificate details holder for export to file action /// Certificate details holder for export to file action
pub struct Certificate { pub struct Certificate {
@ -14,7 +14,7 @@ impl Certificate {
// Constructors // Constructors
/// Create new `Self` /// Create new `Self`
pub fn build(profile: &Arc<Profile>, profile_identity_id: i64) -> Result<Self> { pub fn build(profile: &Rc<Profile>, profile_identity_id: i64) -> Result<Self> {
let record = profile.identity.database.record(profile_identity_id)?; let record = profile.identity.database.record(profile_identity_id)?;
match record { match record {
Some(identity) => Ok(Self { Some(identity) => Ok(Self {

View file

@ -10,7 +10,6 @@ use form::{Form, Query, list::Item, list::item::Value};
use gtk::prelude::{EditableExt, WidgetExt}; use gtk::prelude::{EditableExt, WidgetExt};
use sourceview::prelude::CastNone; use sourceview::prelude::CastNone;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc;
// Response variants // Response variants
const RESPONSE_APPLY: (&str, &str) = ("apply", "Apply"); const RESPONSE_APPLY: (&str, &str) = ("apply", "Apply");
@ -18,14 +17,14 @@ const RESPONSE_CANCEL: (&str, &str) = ("cancel", "Cancel");
// const RESPONSE_MANAGE: (&str, &str) = ("manage", "Manage"); // const RESPONSE_MANAGE: (&str, &str) = ("manage", "Manage");
pub trait Search { pub trait Search {
fn search(profile: &Arc<Profile>) -> Self; fn search(profile: &Rc<Profile>) -> Self;
} }
impl Search for AlertDialog { impl Search for AlertDialog {
// Constructors // Constructors
/// Create new `Self` /// Create new `Self`
fn search(profile: &Arc<Profile>) -> Self { fn search(profile: &Rc<Profile>) -> Self {
// Init child container // Init child container
let form = Rc::new(Form::build(profile)); let form = Rc::new(Form::build(profile));

View file

@ -7,7 +7,7 @@ use drop::Drop;
use gtk::{Box, Button, Entry, Orientation, prelude::BoxExt}; use gtk::{Box, Button, Entry, Orientation, prelude::BoxExt};
use list::List; use list::List;
pub use query::Query; pub use query::Query;
use std::{rc::Rc, sync::Arc}; use std::rc::Rc;
pub struct Form { pub struct Form {
pub drop: Button, pub drop: Button,
@ -20,7 +20,7 @@ impl Form {
// Constructors // Constructors
/// Create new `Self` /// Create new `Self`
pub fn build(profile: &Arc<Profile>) -> Self { pub fn build(profile: &Rc<Profile>) -> Self {
// Init components // Init components
let list = Rc::new(List::build(profile)); let list = Rc::new(List::build(profile));
let query = Entry::query(); let query = Entry::query();

View file

@ -9,17 +9,17 @@ use gtk::{
glib::timeout_add_seconds_local_once, glib::timeout_add_seconds_local_once,
prelude::{ButtonExt, WidgetExt}, prelude::{ButtonExt, WidgetExt},
}; };
use std::{rc::Rc, sync::Arc}; use std::rc::Rc;
pub trait Drop { pub trait Drop {
fn drop(profile: &Arc<Profile>, list: &Rc<List>) -> Self; fn drop(profile: &Rc<Profile>, list: &Rc<List>) -> Self;
} }
impl Drop for Button { impl Drop for Button {
// Constructors // Constructors
/// Create new `Self` /// Create new `Self`
fn drop(profile: &Arc<Profile>, list: &Rc<List>) -> Self { fn drop(profile: &Rc<Profile>, list: &Rc<List>) -> Self {
// Defaults // Defaults
const LABEL: &str = "Delete"; const LABEL: &str = "Delete";

View file

@ -10,7 +10,7 @@ use gtk::{
prelude::{BoxExt, ListItemExt, ObjectExt, WidgetExt}, prelude::{BoxExt, ListItemExt, ObjectExt, WidgetExt},
}; };
pub use item::Item; pub use item::Item;
use std::sync::Arc; use std::rc::Rc;
pub struct List { pub struct List {
pub dropdown: DropDown, pub dropdown: DropDown,
@ -21,7 +21,7 @@ impl List {
// Constructors // Constructors
/// Create new `Self` /// Create new `Self`
pub fn build(profile: &Arc<Profile>) -> Self { pub fn build(profile: &Rc<Profile>) -> Self {
// Init dropdown items // Init dropdown items
let new_search_provider = Item::add(); let new_search_provider = Item::add();

View file

@ -17,14 +17,14 @@ use gtk::{
}; };
pub use item::Item; pub use item::Item;
use sourceview::prelude::ListModelExt; use sourceview::prelude::ListModelExt;
use std::{cell::RefCell, rc::Rc, sync::Arc}; use std::{cell::RefCell, rc::Rc};
pub struct Suggestion { pub struct Suggestion {
list_store: ListStore, list_store: ListStore,
list_view: ListView, list_view: ListView,
single_selection: SingleSelection, single_selection: SingleSelection,
entry: Entry, entry: Entry,
profile: Arc<Profile>, profile: Rc<Profile>,
popover: Popover, popover: Popover,
pub signal_handler_id: Rc<RefCell<Option<SignalHandlerId>>>, pub signal_handler_id: Rc<RefCell<Option<SignalHandlerId>>>,
} }
@ -33,7 +33,7 @@ impl Suggestion {
// Constructors // Constructors
/// Create new `Self` /// Create new `Self`
pub fn build(profile: &Arc<Profile>, entry: &Entry) -> Self { pub fn build(profile: &Rc<Profile>, entry: &Entry) -> Self {
let signal_handler_id = Rc::new(RefCell::new(None)); let signal_handler_id = Rc::new(RefCell::new(None));
let list_store = ListStore::new::<Item>(); let list_store = ListStore::new::<Item>();
let single_selection = { let single_selection = {

View file

@ -10,11 +10,11 @@ use memory::Memory;
use r2d2::Pool; use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager; use r2d2_sqlite::SqliteConnectionManager;
use sqlite::Transaction; use sqlite::Transaction;
use std::sync::RwLock; use std::cell::RefCell;
pub struct Bookmark { pub struct Bookmark {
database: Database, // permanent storage database: Database, // permanent storage
memory: RwLock<Memory>, // fast search index memory: RefCell<Memory>, // fast search index
} }
impl Bookmark { impl Bookmark {
@ -24,11 +24,11 @@ impl Bookmark {
pub fn build(database_pool: &Pool<SqliteConnectionManager>, profile_id: i64) -> Result<Self> { pub fn build(database_pool: &Pool<SqliteConnectionManager>, profile_id: i64) -> Result<Self> {
// Init children components // Init children components
let database = Database::new(database_pool, profile_id); let database = Database::new(database_pool, profile_id);
let memory = RwLock::new(Memory::new()); let memory = RefCell::new(Memory::new());
// Build initial index // Build initial index
{ {
let mut memory = memory.write().unwrap(); let mut memory = memory.borrow_mut();
for item in database.records(None, None)? { for item in database.records(None, None)? {
memory.add(item); memory.add(item);
} }
@ -43,7 +43,7 @@ impl Bookmark {
/// Toggle bookmark in `database` and `memory` index /// Toggle bookmark in `database` and `memory` index
/// * return `true` on bookmark create, `false` on delete /// * return `true` on bookmark create, `false` on delete
pub fn toggle(&self, request: &str, title: Option<&str>) -> Result<bool> { pub fn toggle(&self, request: &str, title: Option<&str>) -> Result<bool> {
let mut memory = self.memory.write().unwrap(); let mut memory = self.memory.borrow_mut();
Ok(match memory.delete_by_request(request) { Ok(match memory.delete_by_request(request) {
Some(item) => { Some(item) => {
self.database.delete(item.id)?; self.database.delete(item.id)?;
@ -64,20 +64,17 @@ impl Bookmark {
/// Check `request` exists in the memory index /// Check `request` exists in the memory index
pub fn is_match_request(&self, request: &str) -> bool { pub fn is_match_request(&self, request: &str) -> bool {
self.memory.write().unwrap().is_match_request(request) self.memory.borrow_mut().is_match_request(request)
} }
/// Find Items match `request` /// Find Items match `request`
pub fn contains_request(&self, request: &str, limit: Option<usize>) -> Vec<Item> { pub fn contains_request(&self, request: &str, limit: Option<usize>) -> Vec<Item> {
self.memory self.memory.borrow_mut().contains_request(request, limit)
.write()
.unwrap()
.contains_request(request, limit)
} }
/// Get recent Items vector from `memory`, sorted by `ID` DESC /// Get recent Items vector from `memory`, sorted by `ID` DESC
pub fn recent(&self, limit: Option<usize>) -> Vec<Item> { pub fn recent(&self, limit: Option<usize>) -> Vec<Item> {
self.memory.read().unwrap().recent(limit) self.memory.borrow().recent(limit)
} }
} }

View file

@ -10,11 +10,11 @@ use memory::Memory;
use r2d2::Pool; use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager; use r2d2_sqlite::SqliteConnectionManager;
use sqlite::Transaction; use sqlite::Transaction;
use std::sync::RwLock; use std::cell::RefCell;
pub struct History { pub struct History {
database: Database, // permanent storage database: Database, // permanent storage
memory: RwLock<Memory>, // fast search index memory: RefCell<Memory>, // fast search index
} }
impl History { impl History {
@ -24,10 +24,10 @@ impl History {
pub fn build(database_pool: &Pool<SqliteConnectionManager>, profile_id: i64) -> Result<Self> { pub fn build(database_pool: &Pool<SqliteConnectionManager>, profile_id: i64) -> Result<Self> {
// Init children components // Init children components
let database = Database::build(database_pool, profile_id); let database = Database::build(database_pool, profile_id);
let memory = RwLock::new(Memory::new()); let memory = RefCell::new(Memory::new());
for item in database.records(None, None)? { for item in database.records(None, None)? {
memory.write().unwrap().add(item) memory.borrow_mut().add(item)
} }
// Return new `Self` // Return new `Self`
@ -37,7 +37,7 @@ impl History {
// Actions // Actions
pub fn save(&self) -> Result<()> { pub fn save(&self) -> Result<()> {
for item in self.memory.read().unwrap().items() { for item in self.memory.borrow().items() {
if !item.is_saved { if !item.is_saved {
match item.id { match item.id {
Some(_) => { Some(_) => {
@ -56,7 +56,7 @@ impl History {
/// Create new history record /// Create new history record
pub fn open(&self, request: GString, title: Option<GString>) { pub fn open(&self, request: GString, title: Option<GString>) {
let mut memory = self.memory.write().unwrap(); let mut memory = self.memory.borrow_mut();
if !memory.open(&request) { if !memory.open(&request) {
memory.add(Item { memory.add(Item {
id: None, id: None,
@ -71,24 +71,24 @@ impl History {
/// Close existing history record /// Close existing history record
pub fn close(&self, request: &str) { pub fn close(&self, request: &str) {
self.memory.write().unwrap().close(request) self.memory.borrow_mut().close(request)
} }
// Getters // Getters
/// Get recently `opened` Items vector from the memory index, sorted by ASC /// Get recently `opened` Items vector from the memory index, sorted by ASC
pub fn recently_opened(&self, limit: Option<usize>) -> Vec<Item> { pub fn recently_opened(&self, limit: Option<usize>) -> Vec<Item> {
self.memory.read().unwrap().recently_opened(limit) self.memory.borrow().recently_opened(limit)
} }
/// Get recently `closed` Items vector from the memory index, sorted by ASC /// Get recently `closed` Items vector from the memory index, sorted by ASC
pub fn recently_closed(&self, limit: Option<usize>) -> Vec<Item> { pub fn recently_closed(&self, limit: Option<usize>) -> Vec<Item> {
self.memory.read().unwrap().recently_closed(limit) self.memory.borrow().recently_closed(limit)
} }
/// Get unordered Items vector that contains given `request` /// Get unordered Items vector that contains given `request`
pub fn contains_request(&self, request: &str, limit: Option<usize>) -> Vec<Item> { pub fn contains_request(&self, request: &str, limit: Option<usize>) -> Vec<Item> {
self.memory.read().unwrap().contains_request(request, limit) self.memory.borrow().contains_request(request, limit)
} // @TODO close memory member } // @TODO close memory member
} }

View file

@ -2,11 +2,11 @@ pub mod auth;
use anyhow::{Result, bail}; use anyhow::{Result, bail};
pub use auth::Auth; pub use auth::Auth;
use std::{collections::HashMap, sync::RwLock}; use std::{cell::RefCell, collections::HashMap};
/// Reduce disk usage by cache Auth index in memory /// Reduce disk usage by cache Auth index in memory
pub struct Memory { pub struct Memory {
index: RwLock<HashMap<String, i64>>, index: RefCell<HashMap<String, i64>>,
} }
impl Default for Memory { impl Default for Memory {
@ -21,7 +21,7 @@ impl Memory {
/// Create new `Self` /// Create new `Self`
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
index: RwLock::new(HashMap::new()), index: RefCell::new(HashMap::new()),
} }
} }
@ -31,7 +31,7 @@ impl Memory {
/// * validate record with same key does not exist yet /// * validate record with same key does not exist yet
pub fn add(&self, scope: String, profile_identity_id: i64) -> Result<()> { pub fn add(&self, scope: String, profile_identity_id: i64) -> Result<()> {
// Borrow shared index access // Borrow shared index access
let mut index = self.index.write().unwrap(); let mut index = self.index.borrow_mut();
// Prevent existing key overwrite // Prevent existing key overwrite
if index.contains_key(&scope) { if index.contains_key(&scope) {
@ -47,7 +47,7 @@ impl Memory {
/// Cleanup index /// Cleanup index
pub fn clear(&self) -> Result<()> { pub fn clear(&self) -> Result<()> {
let mut index = self.index.write().unwrap(); let mut index = self.index.borrow_mut();
index.clear(); index.clear();
if index.is_empty() { if index.is_empty() {
Ok(()) Ok(())
@ -62,7 +62,7 @@ impl Memory {
pub fn match_scope(&self, scope: &str) -> Option<Auth> { pub fn match_scope(&self, scope: &str) -> Option<Auth> {
let mut result = Vec::new(); let mut result = Vec::new();
for (value, &profile_identity_id) in self.index.read().unwrap().iter() { for (value, &profile_identity_id) in self.index.borrow().iter() {
if scope.starts_with(value) { if scope.starts_with(value) {
result.push(Auth { result.push(Auth {
profile_identity_id, profile_identity_id,
@ -83,7 +83,7 @@ impl Memory {
/// * see also parent `is_match_request` /// * see also parent `is_match_request`
pub fn total(&self, profile_identity_id: i64) -> usize { pub fn total(&self, profile_identity_id: i64) -> usize {
let mut total = 0; let mut total = 0;
for (_, _profile_identity_id) in self.index.read().unwrap().iter() { for (_, _profile_identity_id) in self.index.borrow().iter() {
if *_profile_identity_id == profile_identity_id { if *_profile_identity_id == profile_identity_id {
total += 1 total += 1
} }

View file

@ -1,9 +1,9 @@
use anyhow::{Result, bail}; use anyhow::{Result, bail};
use std::{collections::HashMap, sync::RwLock}; use std::{cell::RefCell, collections::HashMap};
/// Reduce disk usage by cache index in memory /// Reduce disk usage by cache index in memory
pub struct Memory { pub struct Memory {
index: RwLock<HashMap<i64, String>>, index: RefCell<HashMap<i64, String>>,
} }
impl Default for Memory { impl Default for Memory {
@ -18,7 +18,7 @@ impl Memory {
/// Create new `Self` /// Create new `Self`
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
index: RwLock::new(HashMap::new()), index: RefCell::new(HashMap::new()),
} }
} }
@ -28,7 +28,7 @@ impl Memory {
/// * validate record with same key does not exist yet /// * validate record with same key does not exist yet
pub fn add(&self, profile_identity_id: i64, pem: String) -> Result<()> { pub fn add(&self, profile_identity_id: i64, pem: String) -> Result<()> {
// Borrow shared index access // Borrow shared index access
let mut index = self.index.write().unwrap(); let mut index = self.index.borrow_mut();
// Prevent existing key overwrite // Prevent existing key overwrite
if index.contains_key(&profile_identity_id) { if index.contains_key(&profile_identity_id) {
@ -44,7 +44,7 @@ impl Memory {
/// Get `pem` clone by `id` from memory index /// Get `pem` clone by `id` from memory index
pub fn get(&self, id: i64) -> Result<String> { pub fn get(&self, id: i64) -> Result<String> {
match self.index.read().unwrap().get(&id) { match self.index.borrow().get(&id) {
Some(pem) => Ok(pem.clone()), Some(pem) => Ok(pem.clone()),
None => bail!("Record `{id}` not found in memory index"), None => bail!("Record `{id}` not found in memory index"),
} }
@ -52,7 +52,7 @@ impl Memory {
/// Cleanup index /// Cleanup index
pub fn clear(&self) -> Result<()> { pub fn clear(&self) -> Result<()> {
let mut index = self.index.write().unwrap(); let mut index = self.index.borrow_mut();
index.clear(); index.clear();
if index.is_empty() { if index.is_empty() {
Ok(()) Ok(())

View file

@ -1,9 +1,9 @@
use super::database::Row; use super::database::Row;
use std::sync::RwLock; use std::cell::RefCell;
/// Reduce disk usage by cache Bookmarks index in memory /// Reduce disk usage by cache Bookmarks index in memory
pub struct Memory { pub struct Memory {
index: RwLock<Vec<Row>>, index: RefCell<Vec<Row>>,
} }
impl Memory { impl Memory {
@ -12,7 +12,7 @@ impl Memory {
/// Create new `Self` /// Create new `Self`
pub fn init() -> Self { pub fn init() -> Self {
Self { Self {
index: RwLock::new(Vec::new()), index: RefCell::new(Vec::new()),
} }
} }
@ -20,7 +20,7 @@ impl Memory {
/// Add new record /// Add new record
pub fn push(&self, id: i64, query: String, is_default: bool) { pub fn push(&self, id: i64, query: String, is_default: bool) {
self.index.write().unwrap().push(Row { self.index.borrow_mut().push(Row {
id, id,
query, query,
is_default, is_default,
@ -29,19 +29,19 @@ impl Memory {
/// Clear all records /// Clear all records
pub fn clear(&self) { pub fn clear(&self) {
self.index.write().unwrap().clear() self.index.borrow_mut().clear()
} }
// Getters // Getters
/// Get all records /// Get all records
pub fn records(&self) -> Vec<Row> { pub fn records(&self) -> Vec<Row> {
self.index.read().unwrap().clone() self.index.borrow().clone()
} }
/// Get all records /// Get all records
pub fn default(&self) -> Option<Row> { pub fn default(&self) -> Option<Row> {
for record in self.index.read().unwrap().iter() { for record in self.index.borrow().iter() {
if record.is_default { if record.is_default {
return Some(record.clone()); return Some(record.clone());
} }

View file

@ -9,14 +9,14 @@ use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager; use r2d2_sqlite::SqliteConnectionManager;
use sourceview::prelude::TlsCertificateExt; use sourceview::prelude::TlsCertificateExt;
use sqlite::Transaction; use sqlite::Transaction;
use std::sync::RwLock; use std::cell::RefCell;
/// TOFU wrapper for the Gemini protocol /// TOFU wrapper for the Gemini protocol
/// ///
/// https://geminiprotocol.net/docs/protocol-specification.gmi#tls-server-certificate-validation /// https://geminiprotocol.net/docs/protocol-specification.gmi#tls-server-certificate-validation
pub struct Tofu { pub struct Tofu {
database: Database, database: Database,
memory: RwLock<Vec<Certificate>>, memory: RefCell<Vec<Certificate>>,
} }
impl Tofu { impl Tofu {
@ -26,11 +26,11 @@ impl Tofu {
let database = Database::init(database_pool, profile_id); let database = Database::init(database_pool, profile_id);
let records = database.records()?; let records = database.records()?;
let memory = RwLock::new(Vec::with_capacity(records.len())); let memory = RefCell::new(Vec::with_capacity(records.len()));
{ {
// build in-memory index... // build in-memory index...
let mut m = memory.write().unwrap(); let mut m = memory.borrow_mut();
for r in records { for r in records {
m.push(Certificate::from_db(Some(r.id), &r.pem, r.time)?) m.push(Certificate::from_db(Some(r.id), &r.pem, r.time)?)
} }
@ -43,8 +43,7 @@ impl Tofu {
pub fn add(&self, tls_certificate: TlsCertificate) -> Result<()> { pub fn add(&self, tls_certificate: TlsCertificate) -> Result<()> {
self.memory self.memory
.write() .borrow_mut()
.unwrap()
.push(Certificate::from_tls_certificate(tls_certificate)?); .push(Certificate::from_tls_certificate(tls_certificate)?);
Ok(()) Ok(())
} }
@ -59,7 +58,7 @@ impl Tofu {
} }
if let Some(h) = uri.host() { if let Some(h) = uri.host() {
let k = f(&h); let k = f(&h);
let m = self.memory.read().unwrap(); let m = self.memory.borrow();
let b: Vec<TlsCertificate> = m let b: Vec<TlsCertificate> = m
.iter() .iter()
.filter_map(|certificate| { .filter_map(|certificate| {
@ -80,7 +79,7 @@ impl Tofu {
/// Save in-memory index to the permanent database (on app close) /// Save in-memory index to the permanent database (on app close)
pub fn save(&self) -> Result<()> { pub fn save(&self) -> Result<()> {
for c in self.memory.read().unwrap().iter() { for c in self.memory.borrow().iter() {
if c.id().is_none() { if c.id().is_none() {
self.database.add(c.time(), &c.pem())?; self.database.add(c.time(), &c.pem())?;
} }