From 11d8b7a6fefa2b47b5bd0a113c0f33f0ccdf6647 Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Tue, 13 Aug 2024 03:59:08 +0300 Subject: [PATCH] refactor: add `from_cargo_metadata` macro (#208) --- .changes/from_cargo_metadata_macro.md | 5 ++ .changes/from_cargo_metadata_removal.md | 5 ++ src/about_metadata.rs | 65 +++++++++++++------------ src/accelerator.rs | 8 +-- src/items/check.rs | 4 +- src/items/icon.rs | 4 +- src/items/normal.rs | 4 +- src/items/submenu.rs | 4 +- src/lib.rs | 2 +- src/menu.rs | 8 +-- src/platform_impl/windows/icon.rs | 2 +- 11 files changed, 62 insertions(+), 49 deletions(-) create mode 100644 .changes/from_cargo_metadata_macro.md create mode 100644 .changes/from_cargo_metadata_removal.md diff --git a/.changes/from_cargo_metadata_macro.md b/.changes/from_cargo_metadata_macro.md new file mode 100644 index 00000000..1a48be7b --- /dev/null +++ b/.changes/from_cargo_metadata_macro.md @@ -0,0 +1,5 @@ +--- +"muda": "minor" +--- + +Added `about_metadata` module and `about_metadata::from_cargo_metadata` macro. diff --git a/.changes/from_cargo_metadata_removal.md b/.changes/from_cargo_metadata_removal.md new file mode 100644 index 00000000..311fc860 --- /dev/null +++ b/.changes/from_cargo_metadata_removal.md @@ -0,0 +1,5 @@ +--- +"muda": "minor" +--- + +**Breaking Change** Removed `AboutMetadata::from_cargo_metadata` and `AboutMetadataBuilder::with_cargo_metadata` which had incorrect implementation, use the new `about_metadata::from_cargo_metadata` macro instead. diff --git a/src/about_metadata.rs b/src/about_metadata.rs index f5bc0688..6134519f 100644 --- a/src/about_metadata.rs +++ b/src/about_metadata.rs @@ -1,6 +1,8 @@ +//! Types and functions to create [`AboutMetadata`] for the [`PredefinedMenuItem::about`](crate::PredefinedMenuItem::about) dialog. + use crate::icon::Icon; -/// Application metadata for the [`PredefinedMenuItem::about`](crate::PredefinedMenuItem::about). +/// Application metadata for the [`PredefinedMenuItem::about`](crate::PredefinedMenuItem::about) dialog. #[derive(Debug, Clone, Default)] pub struct AboutMetadata { /// Sets the application name. @@ -70,29 +72,33 @@ impl AboutMetadata { .unwrap_or_default() )) } +} - /// Creates [`AboutMetadata`] from [Cargo metadata][cargo]. The following fields are set by this function. - /// - /// - [`AboutMetadata::name`] (from `CARGO_PKG_NAME`) - /// - [`AboutMetadata::version`] (from `CARGO_PKG_VERSION`) - /// - [`AboutMetadata::short_version`] (from `CARGO_PKG_VERSION_MAJOR` and `CARGO_PKG_VERSION_MINOR`) - /// - [`AboutMetadata::authors`] (from `CARGO_PKG_AUTHORS`) - /// - [`AboutMetadata::comments`] (from `CARGO_PKG_DESCRIPTION`) - /// - [`AboutMetadata::license`] (from `CARGO_PKG_LICENSE`) - /// - [`AboutMetadata::website`] (from `CARGO_PKG_HOMEPAGE`) - /// - /// [cargo]: https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates - pub fn from_cargo_metadata() -> Self { +/// Creates [`AboutMetadata`] from [Cargo metadata][cargo]. The following fields are set by this function. +/// +/// - [`AboutMetadata::name`] (from `CARGO_PKG_NAME`) +/// - [`AboutMetadata::version`] (from `CARGO_PKG_VERSION`) +/// - [`AboutMetadata::short_version`] (from `CARGO_PKG_VERSION_MAJOR` and `CARGO_PKG_VERSION_MINOR`) +/// - [`AboutMetadata::authors`] (from `CARGO_PKG_AUTHORS`) +/// - [`AboutMetadata::comments`] (from `CARGO_PKG_DESCRIPTION`) +/// - [`AboutMetadata::license`] (from `CARGO_PKG_LICENSE`) +/// - [`AboutMetadata::website`] (from `CARGO_PKG_HOMEPAGE`) +/// +/// [cargo]: https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates +#[macro_export] +#[doc(hidden)] +macro_rules! from_cargo_metadata { + () => {{ #[allow(unused_mut)] - let mut m = Self { - name: Some(env!("CARGO_PKG_NAME").into()), - version: Some(env!("CARGO_PKG_VERSION").into()), - short_version: Some(format!( + let mut m = $crate::about_metadata::AboutMetadata { + name: Some(::std::env!("CARGO_PKG_NAME").into()), + version: Some(::std::env!("CARGO_PKG_VERSION").into()), + short_version: Some(::std::format!( "{}.{}", env!("CARGO_PKG_VERSION_MAJOR"), env!("CARGO_PKG_VERSION_MINOR"), )), - ..Default::default() + ..::std::default::Default::default() }; #[cfg(not(target_os = "macos"))] @@ -100,13 +106,15 @@ impl AboutMetadata { let authors = env!("CARGO_PKG_AUTHORS") .split(';') .map(|a| a.trim().to_string()) - .collect::>(); + .collect::<::std::vec::Vec<_>>(); + m.authors = if !authors.is_empty() { Some(authors) } else { None }; + #[inline] fn non_empty(s: &str) -> Option { if !s.is_empty() { Some(s.to_string()) @@ -115,15 +123,17 @@ impl AboutMetadata { } } - m.comments = non_empty(env!("CARGO_PKG_DESCRIPTION")); - m.license = non_empty(env!("CARGO_PKG_LICENSE")); - m.website = non_empty(env!("CARGO_PKG_HOMEPAGE")); + m.comments = non_empty(::std::env!("CARGO_PKG_DESCRIPTION")); + m.license = non_empty(::std::env!("CARGO_PKG_LICENSE")); + m.website = non_empty(::std::env!("CARGO_PKG_HOMEPAGE")); } m - } + }}; } +pub use from_cargo_metadata; + /// A builder type for [`AboutMetadata`]. #[derive(Clone, Debug, Default)] pub struct AboutMetadataBuilder(AboutMetadata); @@ -133,12 +143,6 @@ impl AboutMetadataBuilder { Default::default() } - /// Creates [`AboutMetadataBuilder`] with Cargo metadata. - /// See [`AboutMetadata::from_cargo_metadata`] for more details. - pub fn with_cargo_metadata() -> Self { - Self(AboutMetadata::from_cargo_metadata()) - } - /// Sets the application name. pub fn name>(mut self, name: Option) -> Self { self.0.name = name.map(|s| s.into()); @@ -235,11 +239,10 @@ impl AboutMetadataBuilder { #[cfg(test)] mod tests { - use super::*; #[test] fn test_build_from_metadata() { - let m = AboutMetadata::from_cargo_metadata(); + let m = from_cargo_metadata!(); assert_eq!(m.name, Some("muda".to_string())); assert!(m.version.is_some()); assert!(m.short_version.is_some()); diff --git a/src/accelerator.rs b/src/accelerator.rs index 4eb567f2..7f614f18 100644 --- a/src/accelerator.rs +++ b/src/accelerator.rs @@ -5,8 +5,8 @@ //! Accelerators describe keyboard shortcuts for menu items. //! //! [`Accelerator`s](crate::accelerator::Accelerator) are used to define a keyboard shortcut consisting -//! of an optional combination of modifier keys (provided by [`Modifiers`](crate::accelerator::Modifiers)) and -//! one key ([`Code`](crate::accelerator::Code)). +//! of an optional combination of modifier keys (provided by [`Modifiers`]) and +//! one key ([`Code`]). //! //! # Examples //! They can be created directly @@ -46,8 +46,8 @@ pub enum AcceleratorParseError { } /// A keyboard shortcut that consists of an optional combination -/// of modifier keys (provided by [`Modifiers`](crate::accelerator::Modifiers)) and -/// one key ([`Code`](crate::accelerator::Code)). +/// of modifier keys (provided by [`Modifiers`] and +/// one key ([`Code`]). #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Accelerator { diff --git a/src/items/check.rs b/src/items/check.rs index cc562a4b..30d8beec 100644 --- a/src/items/check.rs +++ b/src/items/check.rs @@ -37,7 +37,7 @@ impl CheckMenuItem { /// Create a new check menu item. /// /// - `text` could optionally contain an `&` before a character to assign this character as the mnemonic - /// for this check menu item. To display a `&` without assigning a mnemenonic, use `&&`. + /// for this check menu item. To display a `&` without assigning a mnemenonic, use `&&`. pub fn new>( text: S, enabled: bool, @@ -60,7 +60,7 @@ impl CheckMenuItem { /// Create a new check menu item with the specified id. /// /// - `text` could optionally contain an `&` before a character to assign this character as the mnemonic - /// for this check menu item. To display a `&` without assigning a mnemenonic, use `&&`. + /// for this check menu item. To display a `&` without assigning a mnemenonic, use `&&`. pub fn with_id, S: AsRef>( id: I, text: S, diff --git a/src/items/icon.rs b/src/items/icon.rs index 5342ad99..98c97f1d 100644 --- a/src/items/icon.rs +++ b/src/items/icon.rs @@ -41,7 +41,7 @@ impl IconMenuItem { /// Create a new icon menu item. /// /// - `text` could optionally contain an `&` before a character to assign this character as the mnemonic - /// for this icon menu item. To display a `&` without assigning a mnemenonic, use `&&`. + /// for this icon menu item. To display a `&` without assigning a mnemenonic, use `&&`. pub fn new>( text: S, enabled: bool, @@ -64,7 +64,7 @@ impl IconMenuItem { /// Create a new icon menu item with the specified id. /// /// - `text` could optionally contain an `&` before a character to assign this character as the mnemonic - /// for this icon menu item. To display a `&` without assigning a mnemenonic, use `&&`. + /// for this icon menu item. To display a `&` without assigning a mnemenonic, use `&&`. pub fn with_id, S: AsRef>( id: I, text: S, diff --git a/src/items/normal.rs b/src/items/normal.rs index 8e1c3444..5257ae32 100644 --- a/src/items/normal.rs +++ b/src/items/normal.rs @@ -31,7 +31,7 @@ impl MenuItem { /// Create a new menu item. /// /// - `text` could optionally contain an `&` before a character to assign this character as the mnemonic - /// for this menu item. To display a `&` without assigning a mnemenonic, use `&&`. + /// for this menu item. To display a `&` without assigning a mnemenonic, use `&&`. pub fn new>(text: S, enabled: bool, acccelerator: Option) -> Self { let item = crate::platform_impl::MenuChild::new(text.as_ref(), enabled, acccelerator, None); Self { @@ -43,7 +43,7 @@ impl MenuItem { /// Create a new menu item with the specified id. /// /// - `text` could optionally contain an `&` before a character to assign this character as the mnemonic - /// for this menu item. To display a `&` without assigning a mnemenonic, use `&&`. + /// for this menu item. To display a `&` without assigning a mnemenonic, use `&&`. pub fn with_id, S: AsRef>( id: I, text: S, diff --git a/src/items/submenu.rs b/src/items/submenu.rs index 35319f87..6c3acc5b 100644 --- a/src/items/submenu.rs +++ b/src/items/submenu.rs @@ -37,7 +37,7 @@ impl Submenu { /// Create a new submenu. /// /// - `text` could optionally contain an `&` before a character to assign this character as the mnemonic - /// for this submenu. To display a `&` without assigning a mnemenonic, use `&&`. + /// for this submenu. To display a `&` without assigning a mnemenonic, use `&&`. pub fn new>(text: S, enabled: bool) -> Self { let submenu = crate::platform_impl::MenuChild::new_submenu(text.as_ref(), enabled, None); Self { @@ -49,7 +49,7 @@ impl Submenu { /// Create a new submenu with the specified id. /// /// - `text` could optionally contain an `&` before a character to assign this character as the mnemonic - /// for this submenu. To display a `&` without assigning a mnemenonic, use `&&`. + /// for this submenu. To display a `&` without assigning a mnemenonic, use `&&`. pub fn with_id, S: AsRef>(id: I, text: S, enabled: bool) -> Self { let id = id.into(); diff --git a/src/lib.rs b/src/lib.rs index b7b1df3a..fa522c69 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -129,7 +129,7 @@ use crossbeam_channel::{unbounded, Receiver, Sender}; use once_cell::sync::{Lazy, OnceCell}; -mod about_metadata; +pub mod about_metadata; pub mod accelerator; mod builders; mod error; diff --git a/src/menu.rs b/src/menu.rs index 921861da..7e9c87c5 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -164,10 +164,10 @@ impl Menu { /// Adds this menu to a [`gtk::Window`] /// /// - `container`: this is an optional paramter to specify a container for the [`gtk::MenuBar`], - /// it is highly recommended to pass a container, otherwise the menubar will be added directly to the window, - /// which is usually not the desired behavior. - /// If using a [`gtk::Box`] as a container, it is added using [`Box::pack_start(menubar, false, false, 0)`](gtk::prelude::BoxExt::pack_start) then - /// reordered to be the first child of [`gtk::Box`] using [`Box::reorder_child(menubar, 0)`](gtk::prelude::BoxExt::reorder_child). + /// it is highly recommended to pass a container, otherwise the menubar will be added directly to the window, + /// which is usually not the desired behavior. + /// If using a [`gtk::Box`] as a container, it is added using [`Box::pack_start(menubar, false, false, 0)`](gtk::prelude::BoxExt::pack_start) then + /// reordered to be the first child of [`gtk::Box`] using [`Box::reorder_child(menubar, 0)`](gtk::prelude::BoxExt::reorder_child). /// /// ## Example: /// ```no_run diff --git a/src/platform_impl/windows/icon.rs b/src/platform_impl/windows/icon.rs index 4a3c9fd3..e2e469c3 100644 --- a/src/platform_impl/windows/icon.rs +++ b/src/platform_impl/windows/icon.rs @@ -39,7 +39,7 @@ impl RgbaIcon { let pixels = unsafe { std::slice::from_raw_parts_mut(rgba.as_ptr() as *mut Pixel, pixel_count) }; for pixel in pixels { - and_mask.push(pixel.a.wrapping_sub(std::u8::MAX)); // invert alpha channel + and_mask.push(pixel.a.wrapping_sub(u8::MAX)); // invert alpha channel pixel.convert_to_bgra(); } assert_eq!(and_mask.len(), pixel_count);