From da507399ca8b3fe79b58c5b92571d2837383537a Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Fri, 10 Jun 2022 21:10:52 +0200 Subject: [PATCH] Make use of nightly rustfmt features --- favicon-scrapper/src/favicon.rs | 7 +-- favicon-scrapper/src/format.rs | 12 +++-- favicon-scrapper/src/lib.rs | 6 ++- favicon-scrapper/src/scrapper.rs | 3 +- rustfmt.toml | 7 +++ src/application.rs | 22 ++++---- src/backup/aegis.rs | 64 ++++++++++++++---------- src/backup/andotp.rs | 5 +- src/backup/bitwarden.rs | 8 +-- src/backup/freeotp.rs | 8 +-- src/backup/google.rs | 11 ++-- src/backup/legacy.rs | 8 +-- src/backup/mod.rs | 14 +++--- src/models/account.rs | 21 ++++---- src/models/account_sorter.rs | 3 +- src/models/accounts.rs | 6 ++- src/models/algorithm.rs | 3 +- src/models/database.rs | 3 +- src/models/keyring.rs | 6 ++- src/models/otp.rs | 10 ++-- src/models/otp_uri.rs | 9 ++-- src/models/provider.rs | 27 +++++----- src/models/provider_sorter.rs | 6 ++- src/models/providers.rs | 11 ++-- src/widgets/accounts/add.rs | 24 +++++---- src/widgets/accounts/details.rs | 22 ++++---- src/widgets/accounts/mod.rs | 3 +- src/widgets/accounts/qrcode_paintable.rs | 3 +- src/widgets/accounts/row.rs | 12 +++-- src/widgets/camera.rs | 10 ++-- src/widgets/camera_paintable.rs | 12 ++--- src/widgets/editable_label.rs | 3 +- src/widgets/error_revealer.rs | 3 +- src/widgets/preferences/camera_page.rs | 15 +++--- src/widgets/preferences/password_page.rs | 6 ++- src/widgets/preferences/window.rs | 31 +++++++----- src/widgets/progress_icon.rs | 10 ++-- src/widgets/providers/dialog.rs | 20 +++++--- src/widgets/providers/image.rs | 12 +++-- src/widgets/providers/list.rs | 8 +-- src/widgets/providers/page.rs | 20 +++++--- src/widgets/providers/row.rs | 14 ++++-- src/widgets/url_row.rs | 6 ++- src/widgets/window.rs | 14 +++--- 44 files changed, 316 insertions(+), 212 deletions(-) create mode 100644 rustfmt.toml diff --git a/favicon-scrapper/src/favicon.rs b/favicon-scrapper/src/favicon.rs index a21335b..4e2922a 100644 --- a/favicon-scrapper/src/favicon.rs +++ b/favicon-scrapper/src/favicon.rs @@ -1,5 +1,6 @@ -use image::io::Reader as ImageReader; use std::{fmt, io::Cursor, path::PathBuf}; + +use image::io::Reader as ImageReader; use tokio::{io::AsyncWriteExt, sync::Mutex}; use url::Url; @@ -45,8 +46,8 @@ impl Favicon { /// /// # Panics /// - /// If the favicon contains the data instead of a URL, you are supposed to check - /// it content using [`Favicon::is_url`] + /// If the favicon contains the data instead of a URL, you are supposed to + /// check it content using [`Favicon::is_url`] pub fn url(&self) -> &Url { match &self.url { Some(url) => url, diff --git a/favicon-scrapper/src/format.rs b/favicon-scrapper/src/format.rs index bbb5efd..5652ea0 100644 --- a/favicon-scrapper/src/format.rs +++ b/favicon-scrapper/src/format.rs @@ -1,7 +1,7 @@ -use url::Url; - use std::{fmt, path::Path}; +use url::Url; + /// Supported image formats. #[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Ord)] pub enum Format { @@ -11,11 +11,12 @@ pub enum Format { } impl Format { - /// Create a [`Format`] from a URL's path otherwise default to [`Format::Png`]. + /// Create a [`Format`] from a URL's path otherwise default to + /// [`Format::Png`]. /// /// ``` - /// use url::Url; /// use favicon_scrapper::Format; + /// use url::Url; /// /// let url = Url::parse("http://127.0.0.1:8000/favicon.ico").unwrap(); /// assert!(Format::from_url(&url).is_ico()); @@ -38,7 +39,8 @@ impl Format { } } - /// Create a [`Format`] from a mimetype otherwise default to [`Format::Png`]. + /// Create a [`Format`] from a mimetype otherwise default to + /// [`Format::Png`]. /// /// ``` /// use favicon_scrapper::Format; diff --git a/favicon-scrapper/src/lib.rs b/favicon-scrapper/src/lib.rs index cdae631..016bcb4 100644 --- a/favicon-scrapper/src/lib.rs +++ b/favicon-scrapper/src/lib.rs @@ -16,9 +16,10 @@ pub use scrapper::Scrapper; #[cfg(test)] mod tests { - use super::*; use url::Url; + use super::*; + #[tokio::test] async fn parse_from_file() { let base_url = Url::parse("https://github.com").unwrap(); @@ -127,7 +128,8 @@ mod tests { .await .unwrap(); assert!(!scrapper.is_empty()); - // There are 16 but we always add the favicon.ico to try in case it exists as well + // There are 16 but we always add the favicon.ico to try in case it exists as + // well assert_eq!(scrapper.len(), 16 + 1); assert_eq!( diff --git a/favicon-scrapper/src/scrapper.rs b/favicon-scrapper/src/scrapper.rs index cc94165..38cf351 100644 --- a/favicon-scrapper/src/scrapper.rs +++ b/favicon-scrapper/src/scrapper.rs @@ -1,6 +1,7 @@ +use std::{fmt, path::PathBuf}; + use percent_encoding::percent_decode_str; use quick_xml::events::{attributes::Attribute, BytesStart, Event}; -use std::{fmt, path::PathBuf}; use tracing::debug; use url::Url; diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..5f2b10f --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,7 @@ +imports_granularity = "Crate" +format_code_in_doc_comments = true +group_imports = "StdExternalCrate" +newline_style = "Unix" +normalize_comments = true +normalize_doc_attributes = true +wrap_comments = true diff --git a/src/application.rs b/src/application.rs index 6c2978e..2b54eb1 100644 --- a/src/application.rs +++ b/src/application.rs @@ -1,3 +1,12 @@ +use std::{collections::HashMap, str::FromStr}; + +use adw::prelude::*; +use gettextrs::gettext; +use glib::clone; +use gtk::{gio, glib, subclass::prelude::*}; +use gtk_macros::{action, get_action}; +use search_provider::{ResultID, ResultMeta, SearchProvider, SearchProviderImpl}; + use crate::{ config, models::{ @@ -6,20 +15,15 @@ use crate::{ utils::spawn_tokio_blocking, widgets::{PreferencesWindow, ProvidersDialog, Window}, }; -use adw::prelude::*; -use gettextrs::gettext; -use glib::clone; -use gtk::{gio, glib, subclass::prelude::*}; -use gtk_macros::{action, get_action}; -use search_provider::{ResultID, ResultMeta, SearchProvider, SearchProviderImpl}; -use std::{collections::HashMap, str::FromStr}; mod imp { - use super::*; + use std::cell::{Cell, RefCell}; + use adw::subclass::prelude::*; use glib::{ParamSpec, ParamSpecBoolean, Value, WeakRef}; use once_cell::sync::OnceCell; - use std::cell::{Cell, RefCell}; + + use super::*; // The basic struct that holds our state and widgets // (Ref)Cells are used for members which need to be mutable diff --git a/src/backup/aegis.rs b/src/backup/aegis.rs index 0134a6b..500345e 100644 --- a/src/backup/aegis.rs +++ b/src/backup/aegis.rs @@ -3,24 +3,24 @@ //! See https://github.com/beemdevelopment/Aegis/blob/master/docs/vault.md for a description of the //! aegis vault format. //! -//! This module does not convert all information from aegis (note, icon, group are lost). When -//! exporting to the aegis json format the icon, url, help url, and tags are lost. +//! This module does not convert all information from aegis (note, icon, group +//! are lost). When exporting to the aegis json format the icon, url, help url, +//! and tags are lost. //! -//! Exported files by this module cannot be decrypted by the python script provided in the aegis -//! repository (https://github.com/beemdevelopment/Aegis/blob/master/docs/decrypt.py). However, +//! Exported files by this module cannot be decrypted by the python script +//! provided in the aegis repository (https://github.com/beemdevelopment/Aegis/blob/master/docs/decrypt.py). However, //! aegis android app is able to read the files! See line 173 for a discussion. -use super::{Backupable, Restorable, RestorableItem}; -use crate::models::{Account, Algorithm, OTPMethod, Provider, ProvidersModel}; -use aes_gcm::aead::Aead; -use aes_gcm::NewAead; -use anyhow::Context; -use anyhow::Result; +use aes_gcm::{aead::Aead, NewAead}; +use anyhow::{Context, Result}; use gettextrs::gettext; use gtk::{glib::Cast, prelude::*}; use rand::RngCore; use serde::{Deserialize, Serialize}; +use super::{Backupable, Restorable, RestorableItem}; +use crate::models::{Account, Algorithm, OTPMethod, Provider, ProvidersModel}; + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(untagged)] pub enum Aegis { @@ -49,7 +49,8 @@ impl Default for AegisPlainText { } } -/// Encrypted version of the JSON format. `db` is simply a base64 encoded string with an encrypted AegisDatabase. +/// Encrypted version of the JSON format. `db` is simply a base64 encoded string +/// with an encrypted AegisDatabase. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct AegisEncrypted { version: u32, @@ -85,8 +86,8 @@ impl Aegis { slots: Some(vec![HeaderSlot::default()]), }; - // We only support password encrypted database so far so we don't have to do any checks - // for the slot type + // We only support password encrypted database so far so we don't have to do any + // checks for the slot type let mut password_slot = &mut header.slots.as_mut().unwrap().get_mut(0).unwrap(); // Derive key from given password let mut derived_key: [u8; 32] = [0u8; 32]; @@ -115,7 +116,8 @@ impl Aegis { ) .map_err(|_| anyhow::anyhow!("Encrypter master key"))?; - // Add encrypted master key and tag to our password slot. If this assignment fails, we have a mistake in our logic, thus unwrap is okay. + // Add encrypted master key and tag to our password slot. If this assignment + // fails, we have a mistake in our logic, thus unwrap is okay. password_slot.key_params.tag = ciphertext.split_off(32).try_into().unwrap(); password_slot.key = ciphertext.try_into().unwrap(); @@ -153,7 +155,8 @@ impl Aegis { /// Header of the Encrypted Aegis JSON File /// -/// Contains all necessary information for encrypting / decrypting the vault (db field). +/// Contains all necessary information for encrypting / decrypting the vault (db +/// field). #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct Header { #[serde(default)] @@ -177,9 +180,9 @@ pub struct HeaderSlot { // // TODO rename should be changed to `rename = 2`. However this does not work yet with serde, // see: https://github.com/serde-rs/serde/issues/745. This allows decrypting the exported file - // with the python script provided in the aegis repository. The python script expects an integer - // but we provide a string. Thus, change the string in header / slots / password slot / `type = "1"` - // to `type = 1` to use the python script. + // with the python script provided in the aegis repository. The python script expects an + // integer but we provide a string. Thus, change the string in header / slots / password + // slot / `type = "1"` to `type = 1` to use the python script. #[serde(rename = "type")] pub type_: u32, pub uuid: String, @@ -283,8 +286,8 @@ pub struct Item { pub tags: Option, // Note is omitted // Icon: - // TODO: Aegis encodes icons as JPEG's encoded in Base64 with padding. Does authenticator support - // this? + // TODO: Aegis encodes icons as JPEG's encoded in Base64 with padding. Does authenticator + // support this? // TODO tags are not imported/exported right now. #[serde(rename = "icon")] pub thumbnail: Option, @@ -482,8 +485,9 @@ impl Restorable for Aegis { // Add the encryption tag ciphertext.append(&mut encrypted.header.params.as_ref().unwrap().tag.into()); - // Find slots with type password and derive the corresponding key. This key is used - // to decrypt the master key which in turn can be used to decrypt the database. + // Find slots with type password and derive the corresponding key. This key is + // used to decrypt the master key which in turn can be used to + // decrypt the database. let master_keys: Vec> = encrypted .header .slots @@ -494,9 +498,11 @@ impl Restorable for Aegis { .map(|slot| -> Result> { tracing::info!("Found possible master key with UUID {}.", slot.uuid); - // Create parameters for scrypt function and derive decryption key for master key + // Create parameters for scrypt function and derive decryption key for + // master key // - // Somehow, scrypt errors do not implement StdErr and cannot be converted to anyhow::Error. Should be possible but don't know why it doesn't work. + // Somehow, scrypt errors do not implement StdErr and cannot be converted to + // anyhow::Error. Should be possible but don't know why it doesn't work. let params = scrypt::Params::new( // TODO log2 for u64 is not stable yet. Change this in the future. (slot.n() as f64).log2() as u8, // Defaults to 15 by aegis @@ -518,7 +524,8 @@ impl Restorable for Aegis { let mut ciphertext: Vec = slot.key.to_vec(); ciphertext.append(&mut slot.key_params.tag.to_vec()); - // Here we get the master key. The decrypt function does not return an error implementing std error. Thus, we have to convert it. + // Here we get the master key. The decrypt function does not return an error + // implementing std error. Thus, we have to convert it. cipher .decrypt( aes_gcm::Nonce::from_slice(&slot.key_params.nonce), @@ -526,7 +533,9 @@ impl Restorable for Aegis { ) .map_err(|_| anyhow::anyhow!("Cannot decrypt master key")) }) - // Here, we don't want to fail the whole function because one key slot failed to get the correct master key. Maybe there is another slot we were able to decrypt. + // Here, we don't want to fail the whole function because one key slot failed to + // get the correct master key. Maybe there is another slot we were able to + // decrypt. .filter_map(|x| match x { Ok(x) => Some(x), Err(e) => { @@ -536,7 +545,8 @@ impl Restorable for Aegis { }) .collect(); - // Choose the first valid master key. I don't think there are aegis installations with two valid password slots. + // Choose the first valid master key. I don't think there are aegis + // installations with two valid password slots. tracing::info!( "Found {} valid password slots / master keys.", master_keys.len() diff --git a/src/backup/andotp.rs b/src/backup/andotp.rs index 21ac875..b4a6a70 100644 --- a/src/backup/andotp.rs +++ b/src/backup/andotp.rs @@ -1,10 +1,11 @@ -use super::{Backupable, Restorable, RestorableItem}; -use crate::models::{Account, Algorithm, OTPMethod, Provider, ProvidersModel}; use anyhow::Result; use gettextrs::gettext; use gtk::{glib::Cast, prelude::*}; use serde::{Deserialize, Serialize}; +use super::{Backupable, Restorable, RestorableItem}; +use crate::models::{Account, Algorithm, OTPMethod, Provider, ProvidersModel}; + #[allow(clippy::upper_case_acronyms)] #[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct AndOTP { diff --git a/src/backup/bitwarden.rs b/src/backup/bitwarden.rs index 7bff9e2..b9c8fbc 100644 --- a/src/backup/bitwarden.rs +++ b/src/backup/bitwarden.rs @@ -1,9 +1,11 @@ -use super::{Restorable, RestorableItem}; -use crate::models::{Algorithm, OTPMethod, OTPUri}; +use std::str::FromStr; + use anyhow::Result; use gettextrs::gettext; use serde::{Deserialize, Serialize}; -use std::str::FromStr; + +use super::{Restorable, RestorableItem}; +use crate::models::{Algorithm, OTPMethod, OTPUri}; #[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct Bitwarden { diff --git a/src/backup/freeotp.rs b/src/backup/freeotp.rs index 225f846..a7fb8e6 100644 --- a/src/backup/freeotp.rs +++ b/src/backup/freeotp.rs @@ -1,10 +1,12 @@ -use super::{Backupable, Restorable}; -use crate::models::{Account, OTPUri, Provider, ProvidersModel}; +use std::str::FromStr; + use anyhow::Result; use gettextrs::gettext; use gtk::prelude::*; use serde::{Deserialize, Serialize}; -use std::str::FromStr; + +use super::{Backupable, Restorable}; +use crate::models::{Account, OTPUri, Provider, ProvidersModel}; #[allow(clippy::upper_case_acronyms)] #[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] diff --git a/src/backup/google.rs b/src/backup/google.rs index dd8f2b1..87beec2 100644 --- a/src/backup/google.rs +++ b/src/backup/google.rs @@ -1,12 +1,14 @@ -use super::Restorable; -use crate::models::{Algorithm, OTPMethod, OTPUri}; +use std::borrow::Cow; + use anyhow::Result; use gettextrs::gettext; use percent_encoding::percent_decode; use prost::{Enumeration, Message}; -use std::borrow::Cow; use url::Url; +use super::Restorable; +use crate::models::{Algorithm, OTPMethod, OTPUri}; + #[derive(Default, Debug, Clone, PartialEq, Eq)] pub struct Google; @@ -182,8 +184,7 @@ mod protobuf { #[cfg(test)] mod tests { - use super::super::RestorableItem; - use super::*; + use super::{super::RestorableItem, *}; #[test] fn test_google_restore_otpauth() { diff --git a/src/backup/legacy.rs b/src/backup/legacy.rs index 950f099..1c72741 100644 --- a/src/backup/legacy.rs +++ b/src/backup/legacy.rs @@ -1,9 +1,10 @@ -use super::{Restorable, RestorableItem}; -use crate::models::{Algorithm, OTPMethod}; use anyhow::Result; use gettextrs::gettext; use serde::{Deserialize, Serialize}; +use super::{Restorable, RestorableItem}; +use crate::models::{Algorithm, OTPMethod}; + // Same as andOTP except uses the first tag for the issuer #[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct LegacyAuthenticator { @@ -30,7 +31,8 @@ impl Restorable for LegacyAuthenticator { } fn title() -> String { - // Translators: this is for restoring a backup from the old Authenticator release + // Translators: this is for restoring a backup from the old Authenticator + // release gettext("Au_thenticator (Legacy)") } diff --git a/src/backup/mod.rs b/src/backup/mod.rs index d51a625..dcf4a61 100644 --- a/src/backup/mod.rs +++ b/src/backup/mod.rs @@ -1,9 +1,10 @@ use std::fmt::Debug; -use crate::models::{Account, Algorithm, OTPMethod, ProvidersModel}; use anyhow::Result; use gtk::{gio, gio::prelude::*}; +use crate::models::{Account, Algorithm, OTPMethod, ProvidersModel}; + #[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)] pub enum Operation { Backup, @@ -23,16 +24,17 @@ pub trait Restorable: Sized { fn subtitle() -> String; fn identifier() -> String; - /// Restore many items from a slice of data, optionally using a key to unencrypt it. + /// Restore many items from a slice of data, optionally using a key to + /// unencrypt it. /// - /// If `key` is `None`, then the implementation should assume that the slice is unencrypted, and - /// error if it only supports encrypted slices. + /// If `key` is `None`, then the implementation should assume that the slice + /// is unencrypted, and error if it only supports encrypted slices. fn restore_from_data(from: &[u8], key: Option<&str>) -> Result>; /// Restore many items from a file, optiontally using a key to unencrypt it. /// - /// If `key` is `None`, then the implementation should assume that the file is unencrypted, and - /// error if it only supports encrypted files. + /// If `key` is `None`, then the implementation should assume that the file + /// is unencrypted, and error if it only supports encrypted files. /// /// By default, this method reads the file and passes the files content to /// `Self::restore_from_data`. diff --git a/src/models/account.rs b/src/models/account.rs index 107679e..5f15b17 100644 --- a/src/models/account.rs +++ b/src/models/account.rs @@ -1,3 +1,13 @@ +use core::cmp::Ordering; +use std::cell::{Cell, RefCell}; + +use anyhow::{Context, Result}; +use diesel::{BelongingToDsl, ExpressionMethods, QueryDsl, RunQueryDsl}; +use glib::{clone, Cast, StaticType, ToValue}; +use gtk::{glib, prelude::*, subclass::prelude::*}; +use once_cell::sync::OnceCell; +use unicase::UniCase; + use super::{ provider::{DiProvider, Provider}, OTPMethod, OTPUri, RUNTIME, @@ -8,14 +18,6 @@ use crate::{ utils::spawn_tokio_blocking, widgets::QRCodeData, }; -use anyhow::{Context, Result}; -use core::cmp::Ordering; -use diesel::{BelongingToDsl, ExpressionMethods, QueryDsl, RunQueryDsl}; -use glib::{clone, Cast, StaticType, ToValue}; -use gtk::{glib, prelude::*, subclass::prelude::*}; -use once_cell::sync::OnceCell; -use std::cell::{Cell, RefCell}; -use unicase::UniCase; #[derive(Insertable)] #[table_name = "accounts"] @@ -39,9 +41,10 @@ pub struct DiAccount { #[doc(hidden)] mod imp { - use super::*; use glib::{ParamSpec, ParamSpecObject, ParamSpecString, ParamSpecUInt, Value}; + use super::*; + pub struct Account { pub id: Cell, pub otp: RefCell, diff --git a/src/models/account_sorter.rs b/src/models/account_sorter.rs index b0a26b3..a471539 100644 --- a/src/models/account_sorter.rs +++ b/src/models/account_sorter.rs @@ -1,9 +1,10 @@ use gtk::glib; mod imp { + use gtk::subclass::prelude::*; + use super::*; use crate::models::Account; - use gtk::subclass::prelude::*; #[derive(Debug, Default)] pub struct AccountSorter; diff --git a/src/models/accounts.rs b/src/models/accounts.rs index 9440349..1cc8562 100644 --- a/src/models/accounts.rs +++ b/src/models/accounts.rs @@ -1,11 +1,13 @@ -use super::account::Account; use glib::StaticType; use gtk::{gio, glib, prelude::*, subclass::prelude::*}; +use super::account::Account; + mod imp { - use super::*; use std::cell::RefCell; + use super::*; + #[derive(Debug, Default)] pub struct AccountsModel(pub RefCell>); diff --git a/src/models/algorithm.rs b/src/models/algorithm.rs index d912575..15044f4 100644 --- a/src/models/algorithm.rs +++ b/src/models/algorithm.rs @@ -1,8 +1,9 @@ +use std::{str::FromStr, string::ToString}; + use gettextrs::gettext; use gtk::glib; use ring::hmac; use serde::{de::Deserializer, ser::Serializer, Deserialize, Serialize}; -use std::{str::FromStr, string::ToString}; #[allow(clippy::upper_case_acronyms)] #[derive(Debug, Eq, PartialEq, Clone, Copy, glib::Enum)] diff --git a/src/models/database.rs b/src/models/database.rs index 5245783..a9ed6d8 100644 --- a/src/models/database.rs +++ b/src/models/database.rs @@ -1,7 +1,8 @@ +use std::{fs, fs::File, path::PathBuf}; + use anyhow::Result; use diesel::{prelude::*, r2d2, r2d2::ConnectionManager}; use once_cell::sync::Lazy; -use std::{fs, fs::File, path::PathBuf}; type Pool = r2d2::Pool>; diff --git a/src/models/keyring.rs b/src/models/keyring.rs index 525811e..4f1165f 100644 --- a/src/models/keyring.rs +++ b/src/models/keyring.rs @@ -1,7 +1,9 @@ -use crate::config; +use std::collections::HashMap; + use once_cell::sync::OnceCell; use rand::RngCore; -use std::collections::HashMap; + +use crate::config; pub static SECRET_SERVICE: OnceCell = OnceCell::new(); diff --git a/src/models/otp.rs b/src/models/otp.rs index d54ed42..35a4bd6 100644 --- a/src/models/otp.rs +++ b/src/models/otp.rs @@ -1,8 +1,12 @@ -use super::Algorithm; +use std::{ + convert::TryInto, + time::{SystemTime, UNIX_EPOCH}, +}; + use anyhow::{anyhow, Result}; use ring::hmac; -use std::convert::TryInto; -use std::time::{SystemTime, UNIX_EPOCH}; + +use super::Algorithm; pub static STEAM_CHARS: &str = "23456789BCDFGHJKMNPQRTVWXY"; pub static STEAM_DEFAULT_PERIOD: u32 = 30; diff --git a/src/models/otp_uri.rs b/src/models/otp_uri.rs index e97665d..4d01aac 100644 --- a/src/models/otp_uri.rs +++ b/src/models/otp_uri.rs @@ -1,11 +1,12 @@ +use std::{fmt::Write, str::FromStr}; + +use percent_encoding::percent_decode_str; +use url::Url; + use crate::{ backup::RestorableItem, models::{otp, Account, Algorithm, OTPMethod}, }; -use percent_encoding::percent_decode_str; -use std::fmt::Write; -use std::str::FromStr; -use url::Url; #[allow(clippy::upper_case_acronyms)] #[derive(Debug, Clone)] diff --git a/src/models/provider.rs b/src/models/provider.rs index 1282cff..3cedca0 100644 --- a/src/models/provider.rs +++ b/src/models/provider.rs @@ -1,22 +1,24 @@ -use super::algorithm::{Algorithm, OTPMethod}; -use crate::{ - models::{database, otp, Account, AccountsModel, FAVICONS_PATH}, - schema::providers, -}; -use anyhow::Result; use core::cmp::Ordering; -use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl}; -use glib::{clone, Cast, StaticType, ToValue}; -use gtk::{gdk_pixbuf, gio, glib, prelude::*, subclass::prelude::*}; use std::{ cell::{Cell, RefCell}, str::FromStr, string::ToString, time::{SystemTime, UNIX_EPOCH}, }; + +use anyhow::Result; +use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl}; +use glib::{clone, Cast, StaticType, ToValue}; +use gtk::{gdk_pixbuf, gio, glib, prelude::*, subclass::prelude::*}; use unicase::UniCase; use url::Url; +use super::algorithm::{Algorithm, OTPMethod}; +use crate::{ + models::{database, otp, Account, AccountsModel, FAVICONS_PATH}, + schema::providers, +}; + #[derive(Debug)] pub struct ProviderPatch { pub name: String, @@ -60,10 +62,11 @@ pub struct DiProvider { pub method: String, } mod imp { - use super::*; use glib::{ParamSpec, ParamSpecObject, ParamSpecString, ParamSpecUInt, Value}; use gst::glib::{ParamSpecUInt64, SourceId}; + use super::*; + pub struct Provider { pub id: Cell, pub name: RefCell, @@ -387,8 +390,8 @@ impl Provider { let icon_name = glib::base64_encode(icon_name.as_bytes()); let small_icon_name = format!("{icon_name}_32x32"); let large_icon_name = format!("{icon_name}_96x96"); - // TODO: figure out why trying to grab icons at specific size causes stack size errors - // We need two sizes: + // TODO: figure out why trying to grab icons at specific size causes stack size + // errors We need two sizes: // - 32x32 for the accounts lists // - 96x96 elsewhere if let Some(best_favicon) = favicon.find_best().await { diff --git a/src/models/provider_sorter.rs b/src/models/provider_sorter.rs index b8df82a..bc603a6 100644 --- a/src/models/provider_sorter.rs +++ b/src/models/provider_sorter.rs @@ -1,10 +1,12 @@ -use super::provider::Provider; use gtk::glib; +use super::provider::Provider; + mod imp { - use super::*; use gtk::subclass::prelude::*; + use super::*; + #[derive(Debug, Default)] pub struct ProviderSorter; diff --git a/src/models/providers.rs b/src/models/providers.rs index f593f17..9631c92 100644 --- a/src/models/providers.rs +++ b/src/models/providers.rs @@ -1,12 +1,14 @@ -use super::{otp, Account, Algorithm, OTPMethod, Provider, ProviderPatch}; use anyhow::Result; use glib::StaticType; use gtk::{gio, glib, prelude::*, subclass::prelude::*}; +use super::{otp, Account, Algorithm, OTPMethod, Provider, ProviderPatch}; + mod imp { - use super::*; use std::cell::RefCell; + use super::*; + #[derive(Debug, Default)] pub struct ProvidersModel(pub RefCell>); @@ -60,8 +62,9 @@ impl ProvidersModel { ) -> Result { let provider = match self.find_by_name(name) { Some(p) => { - // Update potenitally different properties than what we have in the pre-shipped database - // Note this does a comparaison first to avoid a uselesss rewrite + // Update potenitally different properties than what we have in the pre-shipped + // database Note this does a comparaison first to avoid a + // uselesss rewrite p.update(&ProviderPatch { name: name.to_owned(), website, diff --git a/src/widgets/accounts/add.rs b/src/widgets/accounts/add.rs index 3eb49e7..7ca6a65 100644 --- a/src/widgets/accounts/add.rs +++ b/src/widgets/accounts/add.rs @@ -1,21 +1,24 @@ -use crate::{ - models::{otp, Account, OTPMethod, OTPUri, Provider, ProvidersModel}, - widgets::{Camera, ErrorRevealer, ProviderImage, UrlRow}, -}; +use std::str::FromStr; + use anyhow::Result; use gettextrs::gettext; use glib::{clone, signal::Inhibit}; use gtk::{glib, prelude::*, subclass::prelude::*, CompositeTemplate}; use gtk_macros::spawn; use once_cell::sync::{Lazy, OnceCell}; -use std::str::FromStr; + +use crate::{ + models::{otp, Account, OTPMethod, OTPUri, Provider, ProvidersModel}, + widgets::{Camera, ErrorRevealer, ProviderImage, UrlRow}, +}; mod imp { - use crate::widgets::providers::ProviderPage; + use std::cell::RefCell; + + use glib::subclass::{InitializingObject, Signal}; use super::*; - use glib::subclass::{InitializingObject, Signal}; - use std::cell::RefCell; + use crate::widgets::providers::ProviderPage; #[derive(Debug, Default, CompositeTemplate)] #[template(resource = "/com/belmoussaoui/Authenticator/account_add.ui")] @@ -269,8 +272,9 @@ impl AccountAddDialog { }), ); - // in case the provider doesn't exists, let the user create a new one by showing a dialog for that - // TODO: replace this whole completion provider thing with a custom widget + // in case the provider doesn't exists, let the user create a new one by showing + // a dialog for that TODO: replace this whole completion provider thing + // with a custom widget imp.provider_completion.connect_no_matches(clone!(@weak self as dialog => move |completion| { let imp = dialog.imp(); let model = imp.model.get().unwrap(); diff --git a/src/widgets/accounts/details.rs b/src/widgets/accounts/details.rs index 019a93d..cde581a 100644 --- a/src/widgets/accounts/details.rs +++ b/src/widgets/accounts/details.rs @@ -1,8 +1,3 @@ -use super::qrcode_paintable::QRCodePaintable; -use crate::{ - models::{Account, OTPMethod, Provider, ProvidersModel}, - widgets::UrlRow, -}; use gettextrs::gettext; use gtk::{ gdk, @@ -11,17 +6,24 @@ use gtk::{ subclass::prelude::*, CompositeTemplate, }; + +use super::qrcode_paintable::QRCodePaintable; +use crate::{ + models::{Account, OTPMethod, Provider, ProvidersModel}, + widgets::UrlRow, +}; mod imp { + use std::cell::RefCell; + + use glib::subclass::{self, Signal}; + use once_cell::sync::{Lazy, OnceCell}; + + use super::*; use crate::{ models::Provider, widgets::{editable_label::EditableSpin, EditableLabel}, }; - use super::*; - use glib::subclass::{self, Signal}; - use once_cell::sync::{Lazy, OnceCell}; - use std::cell::RefCell; - #[derive(Debug, Default, CompositeTemplate)] #[template(resource = "/com/belmoussaoui/Authenticator/account_details_page.ui")] pub struct AccountDetailsPage { diff --git a/src/widgets/accounts/mod.rs b/src/widgets/accounts/mod.rs index 7153a94..3b0feb5 100644 --- a/src/widgets/accounts/mod.rs +++ b/src/widgets/accounts/mod.rs @@ -3,6 +3,7 @@ mod details; mod qrcode_paintable; mod row; -pub use self::{add::AccountAddDialog, row::AccountRow}; pub use details::AccountDetailsPage; pub use qrcode_paintable::{QRCodeData, QRCodePaintable}; + +pub use self::{add::AccountAddDialog, row::AccountRow}; diff --git a/src/widgets/accounts/qrcode_paintable.rs b/src/widgets/accounts/qrcode_paintable.rs index 112dfaa..dc5947a 100644 --- a/src/widgets/accounts/qrcode_paintable.rs +++ b/src/widgets/accounts/qrcode_paintable.rs @@ -63,9 +63,10 @@ mod imp { }); }); } - use super::*; use std::cell::RefCell; + use super::*; + #[allow(clippy::upper_case_acronyms)] #[derive(Debug, Default)] pub struct QRCodePaintable { diff --git a/src/widgets/accounts/row.rs b/src/widgets/accounts/row.rs index a815e6a..80a24ff 100644 --- a/src/widgets/accounts/row.rs +++ b/src/widgets/accounts/row.rs @@ -1,16 +1,18 @@ -use crate::models::{Account, OTPMethod}; -use gtk::{gdk, glib, prelude::*, subclass::prelude::*, CompositeTemplate}; use std::cell::RefCell; -mod imp { - use crate::widgets::Window; +use gtk::{gdk, glib, prelude::*, subclass::prelude::*, CompositeTemplate}; - use super::*; +use crate::models::{Account, OTPMethod}; + +mod imp { use adw::subclass::prelude::*; use gettextrs::gettext; use glib::{subclass, ParamSpec, ParamSpecObject, Value}; use once_cell::sync::Lazy; + use super::*; + use crate::widgets::Window; + #[derive(Debug, Default, CompositeTemplate)] #[template(resource = "/com/belmoussaoui/Authenticator/account_row.ui")] pub struct AccountRow { diff --git a/src/widgets/camera.rs b/src/widgets/camera.rs index 13fa7ea..4534c71 100644 --- a/src/widgets/camera.rs +++ b/src/widgets/camera.rs @@ -1,4 +1,8 @@ -use crate::widgets::CameraPaintable; +use std::{ + cell::{Cell, RefCell}, + os::unix::prelude::RawFd, +}; + use adw::subclass::prelude::*; use anyhow::Result; use ashpd::{desktop::screenshot::ScreenshotProxy, zbus}; @@ -17,10 +21,10 @@ use gtk::{ use gtk_macros::spawn; use image::GenericImageView; use once_cell::sync::Lazy; -use std::cell::{Cell, RefCell}; -use std::os::unix::prelude::RawFd; use zbar_rust::ZBarImageScanner; +use crate::widgets::CameraPaintable; + mod screenshot { use super::*; diff --git a/src/widgets/camera_paintable.rs b/src/widgets/camera_paintable.rs index c466c09..f60f3d6 100644 --- a/src/widgets/camera_paintable.rs +++ b/src/widgets/camera_paintable.rs @@ -1,17 +1,18 @@ use std::os::unix::io::AsRawFd; -use crate::widgets::camera::CameraEvent; use gst::prelude::*; -use gtk::prelude::*; -use gtk::subclass::prelude::*; use gtk::{ gdk, glib::{self, clone, Sender}, graphene, + prelude::*, + subclass::prelude::*, }; use gtk_macros::send; use once_cell::sync::Lazy; use tracing::error; + +use crate::widgets::camera::CameraEvent; static PIPELINE_NAME: Lazy = Lazy::new(|| glib::GString::from("camera")); /// Fancy Camera with QR code detection using ZBar /// @@ -21,8 +22,6 @@ static PIPELINE_NAME: Lazy = Lazy::new(|| glib::GString::from("ca /// pipewiresrc -- tee /// \ /// queue -- glsinkbin -/// -/// mod imp { use std::cell::RefCell; @@ -74,7 +73,8 @@ mod imp { ) { let snapshot = snapshot.downcast_ref::().unwrap(); if let Some(ref image) = *self.sink_paintable.borrow() { - // Transformation to avoid stretching the camera. We translate and scale the image. + // Transformation to avoid stretching the camera. We translate and scale the + // image. let aspect = width / height.max(std::f64::EPSILON); // Do not divide by zero. let image_aspect = image.intrinsic_aspect_ratio(); diff --git a/src/widgets/editable_label.rs b/src/widgets/editable_label.rs index 1924201..96d6f1d 100644 --- a/src/widgets/editable_label.rs +++ b/src/widgets/editable_label.rs @@ -1,9 +1,10 @@ use gtk::{glib, prelude::*, subclass::prelude::*}; mod imp { - use super::*; use adw::subclass::prelude::*; + use super::*; + #[derive(Debug, Default, gtk::CompositeTemplate)] #[template(resource = "/com/belmoussaoui/Authenticator/editable_label.ui")] pub struct EditableLabel { diff --git a/src/widgets/error_revealer.rs b/src/widgets/error_revealer.rs index 15fc777..71bff30 100644 --- a/src/widgets/error_revealer.rs +++ b/src/widgets/error_revealer.rs @@ -1,10 +1,11 @@ use gtk::{glib, prelude::*, subclass::prelude::*}; mod imp { - use super::*; use glib::subclass; use gtk::CompositeTemplate; + use super::*; + #[derive(Debug, Default, CompositeTemplate)] #[template(resource = "/com/belmoussaoui/Authenticator/error_revealer.ui")] pub struct ErrorRevealer { diff --git a/src/widgets/preferences/camera_page.rs b/src/widgets/preferences/camera_page.rs index c7148e6..59bda49 100644 --- a/src/widgets/preferences/camera_page.rs +++ b/src/widgets/preferences/camera_page.rs @@ -1,4 +1,5 @@ -use crate::{utils::spawn_tokio, widgets::Camera}; +use std::{cell::Cell, rc::Rc}; + use adw::subclass::prelude::*; use anyhow::Result; use gtk::{ @@ -10,14 +11,14 @@ use gtk::{ }; use gtk_macros::get_action; use once_cell::sync::OnceCell; -use std::cell::Cell; -use std::rc::Rc; use tokio::{ select, sync::oneshot, time::{sleep, Duration}, }; +use crate::{utils::spawn_tokio, widgets::Camera}; + mod imp { use super::*; @@ -67,8 +68,8 @@ impl CameraPage { let (tx, rx) = oneshot::channel(); - // This is required because for whatever reason `glib::clone!` wouldn't let it be moved into - // the closure. + // This is required because for whatever reason `glib::clone!` wouldn't let it + // be moved into the closure. let tx = Rc::new(Cell::new(Some(tx))); // This is to make it safe to access `src` inside of the connected closure to @@ -121,8 +122,8 @@ impl CameraPage { let (tx, rx) = oneshot::channel(); - // This is required because for whatever reason `glib::clone!` wouldn't let it be moved into - // the closure. + // This is required because for whatever reason `glib::clone!` wouldn't let it + // be moved into the closure. let tx = Rc::new(Cell::new(Some(tx))); // This is to make it safe to access `src` inside of the connected closure to diff --git a/src/widgets/preferences/password_page.rs b/src/widgets/preferences/password_page.rs index 4c5833a..7b1946d 100644 --- a/src/widgets/preferences/password_page.rs +++ b/src/widgets/preferences/password_page.rs @@ -1,4 +1,5 @@ -use crate::{config, models::keyring, utils::spawn_tokio, widgets::ErrorRevealer}; +use std::cell::{Cell, RefCell}; + use gettextrs::gettext; use gtk::{ gio, @@ -9,7 +10,8 @@ use gtk::{ }; use gtk_macros::{action, get_action}; use once_cell::sync::{Lazy, OnceCell}; -use std::cell::{Cell, RefCell}; + +use crate::{config, models::keyring, utils::spawn_tokio, widgets::ErrorRevealer}; mod imp { use super::*; diff --git a/src/widgets/preferences/window.rs b/src/widgets/preferences/window.rs index c406b63..046c7a9 100644 --- a/src/widgets/preferences/window.rs +++ b/src/widgets/preferences/window.rs @@ -1,5 +1,11 @@ -use super::camera_page::CameraPage; -use super::password_page::PasswordPage; +use adw::prelude::*; +use gettextrs::gettext; +use glib::clone; +use gtk::{gio, glib, subclass::prelude::*, CompositeTemplate}; +use gtk_macros::{action, get_action, spawn}; +use once_cell::sync::OnceCell; + +use super::{camera_page::CameraPage, password_page::PasswordPage}; use crate::{ backup::{ Aegis, AndOTP, Backupable, Bitwarden, FreeOTP, Google, LegacyAuthenticator, Operation, @@ -8,23 +14,21 @@ use crate::{ config, models::ProvidersModel, }; -use adw::prelude::*; -use gettextrs::gettext; -use glib::clone; -use gtk::{gio, glib, subclass::prelude::*, CompositeTemplate}; -use gtk_macros::{action, get_action, spawn}; -use once_cell::sync::OnceCell; mod imp { - use super::*; + use std::{ + cell::{Cell, RefCell}, + collections::HashMap, + }; + use adw::subclass::{preferences_window::PreferencesWindowImpl, window::AdwWindowImpl}; use glib::{ subclass::{self, Signal}, ParamSpec, ParamSpecBoolean, Value, }; use once_cell::sync::Lazy; - use std::cell::{Cell, RefCell}; - use std::collections::HashMap; + + use super::*; #[derive(Debug, CompositeTemplate)] #[template(resource = "/com/belmoussaoui/Authenticator/preferences.ui")] @@ -197,8 +201,9 @@ impl PreferencesWindow { }), ); - // FreeOTP is first in all of these lists, since its the way to backup Authenticator for use - // with Authenticator. Others are sorted alphabetically. + // FreeOTP is first in all of these lists, since its the way to backup + // Authenticator for use with Authenticator. Others are sorted + // alphabetically. self.register_backup::(&["text/plain"]); self.register_backup::(&["application/json"]); diff --git a/src/widgets/progress_icon.rs b/src/widgets/progress_icon.rs index c5d0ad0..44df58f 100644 --- a/src/widgets/progress_icon.rs +++ b/src/widgets/progress_icon.rs @@ -1,13 +1,13 @@ -use gtk::prelude::*; -use gtk::subclass::prelude::*; -use gtk::{gdk, glib}; +use gtk::{gdk, glib, prelude::*, subclass::prelude::*}; pub(crate) mod imp { - use super::*; + use std::cell::Cell; + use glib::{ParamSpec, ParamSpecFloat, Value}; use gtk::{graphene, gsk}; use once_cell::sync::Lazy; - use std::cell::Cell; + + use super::*; #[derive(Debug, Default)] pub struct ProgressIcon { diff --git a/src/widgets/providers/dialog.rs b/src/widgets/providers/dialog.rs index 52514a2..b14b1cc 100644 --- a/src/widgets/providers/dialog.rs +++ b/src/widgets/providers/dialog.rs @@ -1,11 +1,12 @@ -use super::ProviderPage; -use crate::models::{Provider, ProviderSorter, ProvidersModel}; use adw::{prelude::*, subclass::prelude::*}; use gettextrs::gettext; use glib::clone; use gtk::{glib, pango, subclass::prelude::*, CompositeTemplate}; use row::ProviderActionRow; +use super::ProviderPage; +use crate::models::{Provider, ProviderSorter, ProvidersModel}; + enum View { List, Form, @@ -13,12 +14,12 @@ enum View { } mod imp { - use crate::config; - - use super::*; use adw::subclass::window::AdwWindowImpl; use glib::subclass::{self, Signal}; + use super::*; + use crate::config; + #[derive(Debug, Default, CompositeTemplate)] #[template(resource = "/com/belmoussaoui/Authenticator/providers_dialog.ui")] pub struct ProvidersDialog { @@ -222,7 +223,8 @@ impl ProvidersDialog { fn add_provider(&self) { self.set_view(View::Form); - // By not setting the current provider we implicitly say it's for creating a new one + // By not setting the current provider we implicitly say it's for creating a new + // one self.imp().page.set_provider(None); } @@ -256,10 +258,12 @@ impl ProvidersDialog { mod row { use super::*; mod imp { - use super::*; - use glib::{ParamSpec, ParamSpecObject, Value}; use std::cell::RefCell; + use glib::{ParamSpec, ParamSpecObject, Value}; + + use super::*; + #[derive(Debug, Default)] pub struct ProviderActionRow { pub provider: RefCell>, diff --git a/src/widgets/providers/image.rs b/src/widgets/providers/image.rs index 3beef94..4096527 100644 --- a/src/widgets/providers/image.rs +++ b/src/widgets/providers/image.rs @@ -1,20 +1,22 @@ -use crate::models::RUNTIME; -use crate::models::{Provider, FAVICONS_PATH}; use glib::{clone, Receiver, Sender}; use gtk::{gio, glib, prelude::*, subclass::prelude::*, CompositeTemplate}; use gtk_macros::send; use tracing::error; +use crate::models::{Provider, FAVICONS_PATH, RUNTIME}; + pub enum ImageAction { Ready(String), Failed, } mod imp { - use super::*; - use glib::{subclass, ParamSpec, ParamSpecObject, ParamSpecUInt, Value}; use std::cell::{Cell, RefCell}; + use glib::{subclass, ParamSpec, ParamSpecObject, ParamSpecUInt, Value}; + + use super::*; + #[derive(Debug, CompositeTemplate)] #[template(resource = "/com/belmoussaoui/Authenticator/provider_image.ui")] pub struct ProviderImage { @@ -265,7 +267,7 @@ impl ProviderImage { fn do_action(&self, action: ImageAction) -> glib::Continue { let imp = self.imp(); let image_path = match action { - //TODO: handle network failure and other errors differently + // TODO: handle network failure and other errors differently ImageAction::Failed => { imp.image.set_from_icon_name(Some("provider-fallback")); "invalid".to_string() diff --git a/src/widgets/providers/list.rs b/src/widgets/providers/list.rs index 6645e2e..fa4cb18 100644 --- a/src/widgets/providers/list.rs +++ b/src/widgets/providers/list.rs @@ -1,9 +1,10 @@ +use glib::clone; +use gtk::{glib, prelude::*, subclass::prelude::*, CompositeTemplate}; + use crate::{ models::{Account, Provider, ProviderSorter, ProvidersModel}, widgets::providers::ProviderRow, }; -use glib::clone; -use gtk::{glib, prelude::*, subclass::prelude::*, CompositeTemplate}; #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)] pub enum ProvidersListView { @@ -12,9 +13,10 @@ pub enum ProvidersListView { } mod imp { - use super::*; use glib::subclass::{self, Signal}; + use super::*; + #[derive(Debug, Default, CompositeTemplate)] #[template(resource = "/com/belmoussaoui/Authenticator/providers_list.ui")] pub struct ProvidersList { diff --git a/src/widgets/providers/page.rs b/src/widgets/providers/page.rs index 00e82fc..0df759d 100644 --- a/src/widgets/providers/page.rs +++ b/src/widgets/providers/page.rs @@ -1,17 +1,20 @@ -use crate::{ - models::{i18n, otp, Algorithm, OTPMethod, Provider, ProviderPatch, FAVICONS_PATH}, - widgets::{ErrorRevealer, ProviderImage}, -}; use adw::prelude::*; use gettextrs::gettext; use glib::{clone, translate::IntoGlib}; use gtk::{gdk_pixbuf, gio, glib, subclass::prelude::*, CompositeTemplate}; +use crate::{ + models::{i18n, otp, Algorithm, OTPMethod, Provider, ProviderPatch, FAVICONS_PATH}, + widgets::{ErrorRevealer, ProviderImage}, +}; + mod imp { + use std::cell::RefCell; + + use glib::subclass::{self, Signal}; + use super::*; use crate::models::OTPMethod; - use glib::subclass::{self, Signal}; - use std::cell::RefCell; #[derive(Debug, CompositeTemplate)] #[template(resource = "/com/belmoussaoui/Authenticator/provider_page.ui")] @@ -230,8 +233,9 @@ impl ProviderPage { } } - // Validate the information typed by the user in order to enable/disable the save action - // Note that we don't validate the urls other than: does `url` crate can parse it or not + // Validate the information typed by the user in order to enable/disable the + // save action Note that we don't validate the urls other than: does `url` + // crate can parse it or not fn validate(&self) { let imp = self.imp(); diff --git a/src/widgets/providers/row.rs b/src/widgets/providers/row.rs index a9e4b62..8985dc0 100644 --- a/src/widgets/providers/row.rs +++ b/src/widgets/providers/row.rs @@ -1,19 +1,23 @@ +use std::time::{SystemTime, UNIX_EPOCH}; + +use adw::prelude::*; +use gtk::{glib, glib::clone, subclass::prelude::*, CompositeTemplate}; + use crate::{ models::{Account, AccountSorter, OTPMethod, Provider}, widgets::{accounts::AccountRow, ProgressIcon, ProviderImage}, }; -use adw::prelude::*; -use gtk::{glib, glib::clone, subclass::prelude::*, CompositeTemplate}; -use std::time::{SystemTime, UNIX_EPOCH}; mod imp { - use super::*; + use std::cell::RefCell; + use glib::{ subclass::{self, Signal}, ParamSpec, ParamSpecObject, Value, }; use once_cell::sync::Lazy; - use std::cell::RefCell; + + use super::*; #[derive(Debug, Default, CompositeTemplate)] #[template(resource = "/com/belmoussaoui/Authenticator/provider_row.ui")] diff --git a/src/widgets/url_row.rs b/src/widgets/url_row.rs index 69b68b7..f722bcc 100644 --- a/src/widgets/url_row.rs +++ b/src/widgets/url_row.rs @@ -3,10 +3,12 @@ use glib::{clone, ToValue}; use gtk::{glib, subclass::prelude::*}; mod imp { - use super::*; + use std::cell::RefCell; + use adw::subclass::prelude::*; use glib::{ParamSpec, ParamSpecString, Value}; - use std::cell::RefCell; + + use super::*; #[derive(Debug, Default)] pub struct UrlRow { diff --git a/src/widgets/window.rs b/src/widgets/window.rs index 59fdd8a..edb5f3c 100644 --- a/src/widgets/window.rs +++ b/src/widgets/window.rs @@ -1,3 +1,9 @@ +use gettextrs::gettext; +use glib::{clone, signal::Inhibit}; +use gtk::{gio, glib, prelude::*, subclass::prelude::*, CompositeTemplate}; +use gtk_macros::{action, get_action}; +use once_cell::sync::OnceCell; + use crate::{ application::Application, config, @@ -9,11 +15,6 @@ use crate::{ AccountAddDialog, ErrorRevealer, }, }; -use gettextrs::gettext; -use glib::{clone, signal::Inhibit}; -use gtk::{gio, glib, prelude::*, subclass::prelude::*, CompositeTemplate}; -use gtk_macros::{action, get_action}; -use once_cell::sync::OnceCell; #[derive(PartialEq, Eq, Debug)] pub enum View { @@ -23,10 +24,11 @@ pub enum View { } mod imp { - use super::*; use adw::subclass::prelude::*; use glib::subclass; + use super::*; + #[derive(Debug, CompositeTemplate)] #[template(resource = "/com/belmoussaoui/Authenticator/window.ui")] pub struct Window {