mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-04-24 09:38:32 +02:00
refactor(derive-ahk): enforce no_implicit_prelude
Starting to implement the feedback I got from this post on Reddit https://old.reddit.com/r/rust/comments/pa2997/code_review_request_first_derive_macro/.
This commit is contained in:
@@ -1,19 +1,28 @@
|
|||||||
#![warn(clippy::all, clippy::nursery, clippy::pedantic)]
|
#![warn(clippy::all, clippy::nursery, clippy::pedantic)]
|
||||||
#![allow(clippy::missing_errors_doc)]
|
#![allow(clippy::missing_errors_doc)]
|
||||||
|
#![no_implicit_prelude]
|
||||||
|
|
||||||
use std::stringify;
|
use ::std::clone::Clone;
|
||||||
|
use ::std::convert::From;
|
||||||
|
use ::std::convert::Into;
|
||||||
|
use ::std::iter::Extend;
|
||||||
|
use ::std::iter::Iterator;
|
||||||
|
use ::std::matches;
|
||||||
|
use ::std::string::ToString;
|
||||||
|
use ::std::unreachable;
|
||||||
|
|
||||||
use quote::quote;
|
use ::quote::quote;
|
||||||
use syn::parse_macro_input;
|
use ::std::option::Option::Some;
|
||||||
use syn::Data;
|
use ::syn::parse_macro_input;
|
||||||
use syn::DataEnum;
|
use ::syn::Data;
|
||||||
use syn::DeriveInput;
|
use ::syn::DataEnum;
|
||||||
use syn::Fields;
|
use ::syn::DeriveInput;
|
||||||
use syn::FieldsNamed;
|
use ::syn::Fields;
|
||||||
use syn::FieldsUnnamed;
|
use ::syn::FieldsNamed;
|
||||||
|
use ::syn::FieldsUnnamed;
|
||||||
|
|
||||||
#[proc_macro_derive(Ahk)]
|
#[proc_macro_derive(AhkFunction)]
|
||||||
pub fn ahk(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
pub fn ahk_function(input: ::proc_macro::TokenStream) -> ::proc_macro::TokenStream {
|
||||||
let input = parse_macro_input!(input as DeriveInput);
|
let input = parse_macro_input!(input as DeriveInput);
|
||||||
let name = input.ident;
|
let name = input.ident;
|
||||||
|
|
||||||
@@ -21,22 +30,23 @@ pub fn ahk(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
|||||||
Data::Struct(s) => match s.fields {
|
Data::Struct(s) => match s.fields {
|
||||||
Fields::Named(FieldsNamed { named, .. }) => {
|
Fields::Named(FieldsNamed { named, .. }) => {
|
||||||
let idents = named.iter().map(|f| &f.ident);
|
let idents = named.iter().map(|f| &f.ident);
|
||||||
let arguments = format!("{}", quote! {#(#idents), *});
|
let arguments = quote! {#(#idents), *}.to_string();
|
||||||
|
|
||||||
let idents = named.iter().map(|f| &f.ident);
|
let idents = named.iter().map(|f| &f.ident);
|
||||||
let called_arguments = format!("{}", quote! {#(%#idents%) *})
|
let called_arguments = quote! {#(%#idents%) *}
|
||||||
|
.to_string()
|
||||||
.replace(" %", "%")
|
.replace(" %", "%")
|
||||||
.replace("% ", "%")
|
.replace("% ", "%")
|
||||||
.replace("%%", "% %");
|
.replace("%%", "% %");
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
impl #name {
|
impl AhkFunction for #name {
|
||||||
fn ahk_function() -> String {
|
fn generate_ahk_function() -> String {
|
||||||
format!(r#"
|
::std::format!(r#"
|
||||||
{}({}) {{
|
{}({}) {{
|
||||||
Run, komorebic.exe {} {}, , Hide
|
Run, komorebic.exe {} {}, , Hide
|
||||||
}}"#,
|
}}"#,
|
||||||
stringify!(#name),
|
::std::stringify!(#name),
|
||||||
#arguments,
|
#arguments,
|
||||||
stringify!(#name).to_kebab_case(),
|
stringify!(#name).to_kebab_case(),
|
||||||
#called_arguments
|
#called_arguments
|
||||||
@@ -47,31 +57,42 @@ pub fn ahk(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
|||||||
}
|
}
|
||||||
_ => unreachable!("only to be used on structs with named fields"),
|
_ => unreachable!("only to be used on structs with named fields"),
|
||||||
},
|
},
|
||||||
|
_ => unreachable!("only to be used on structs"),
|
||||||
|
}
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro_derive(AhkLibrary)]
|
||||||
|
pub fn ahk_library(input: ::proc_macro::TokenStream) -> ::proc_macro::TokenStream {
|
||||||
|
let input = parse_macro_input!(input as DeriveInput);
|
||||||
|
let name = input.ident;
|
||||||
|
|
||||||
|
match input.data {
|
||||||
Data::Enum(DataEnum { variants, .. }) => {
|
Data::Enum(DataEnum { variants, .. }) => {
|
||||||
let enums = variants.iter().filter(|&v| {
|
let enums = variants.iter().filter(|&v| {
|
||||||
matches!(v.fields, Fields::Unit) || matches!(v.fields, Fields::Unnamed(..))
|
matches!(v.fields, Fields::Unit) || matches!(v.fields, Fields::Unnamed(..))
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut stream = proc_macro2::TokenStream::new();
|
let mut stream = ::proc_macro2::TokenStream::new();
|
||||||
|
|
||||||
for variant in enums.clone() {
|
for variant in enums.clone() {
|
||||||
match &variant.fields {
|
match &variant.fields {
|
||||||
Fields::Unnamed(FieldsUnnamed { unnamed, .. }) => {
|
Fields::Unnamed(FieldsUnnamed { unnamed, .. }) => {
|
||||||
for field in unnamed {
|
for field in unnamed {
|
||||||
stream.extend(quote! {
|
stream.extend(quote! {
|
||||||
v.push(#field::ahk_function());
|
v.push(#field::generate_ahk_function());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Fields::Unit => {
|
Fields::Unit => {
|
||||||
let name = &variant.ident;
|
let name = &variant.ident;
|
||||||
stream.extend(quote! {
|
stream.extend(quote! {
|
||||||
v.push(format!(r#"
|
v.push(::std::format!(r#"
|
||||||
{}() {{
|
{}() {{
|
||||||
Run, komorebic.exe {}, , Hide
|
Run, komorebic.exe {}, , Hide
|
||||||
}}"#,
|
}}"#,
|
||||||
stringify!(#name),
|
::std::stringify!(#name),
|
||||||
stringify!(#name).to_kebab_case()
|
::std::stringify!(#name).to_kebab_case()
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -93,7 +114,7 @@ pub fn ahk(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Data::Union(_) => unreachable!("only to be used on enums and structs"),
|
_ => unreachable!("only to be used on enums"),
|
||||||
}
|
}
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ use bindings::Windows::Win32::Foundation::HWND;
|
|||||||
use bindings::Windows::Win32::UI::WindowsAndMessaging::ShowWindow;
|
use bindings::Windows::Win32::UI::WindowsAndMessaging::ShowWindow;
|
||||||
use bindings::Windows::Win32::UI::WindowsAndMessaging::SHOW_WINDOW_CMD;
|
use bindings::Windows::Win32::UI::WindowsAndMessaging::SHOW_WINDOW_CMD;
|
||||||
use bindings::Windows::Win32::UI::WindowsAndMessaging::SW_RESTORE;
|
use bindings::Windows::Win32::UI::WindowsAndMessaging::SW_RESTORE;
|
||||||
use derive_ahk::Ahk;
|
use derive_ahk::AhkFunction;
|
||||||
|
use derive_ahk::AhkLibrary;
|
||||||
use komorebi_core::ApplicationIdentifier;
|
use komorebi_core::ApplicationIdentifier;
|
||||||
use komorebi_core::CycleDirection;
|
use komorebi_core::CycleDirection;
|
||||||
use komorebi_core::Flip;
|
use komorebi_core::Flip;
|
||||||
@@ -35,6 +36,14 @@ use komorebi_core::OperationDirection;
|
|||||||
use komorebi_core::Sizing;
|
use komorebi_core::Sizing;
|
||||||
use komorebi_core::SocketMessage;
|
use komorebi_core::SocketMessage;
|
||||||
|
|
||||||
|
trait AhkLibrary {
|
||||||
|
fn generate_ahk_library() -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
trait AhkFunction {
|
||||||
|
fn generate_ahk_function() -> String;
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(ArgEnum)]
|
#[derive(ArgEnum)]
|
||||||
enum BooleanState {
|
enum BooleanState {
|
||||||
Enable,
|
Enable,
|
||||||
@@ -55,7 +64,7 @@ macro_rules! gen_enum_subcommand_args {
|
|||||||
( $( $name:ident: $element:ty ),+ ) => {
|
( $( $name:ident: $element:ty ),+ ) => {
|
||||||
$(
|
$(
|
||||||
paste! {
|
paste! {
|
||||||
#[derive(clap::Clap, derive_ahk::Ahk)]
|
#[derive(clap::Clap, derive_ahk::AhkFunction)]
|
||||||
pub struct $name {
|
pub struct $name {
|
||||||
#[clap(arg_enum)]
|
#[clap(arg_enum)]
|
||||||
[<$element:snake>]: $element
|
[<$element:snake>]: $element
|
||||||
@@ -80,7 +89,7 @@ macro_rules! gen_target_subcommand_args {
|
|||||||
// SubCommand Pattern
|
// SubCommand Pattern
|
||||||
( $( $name:ident ),+ ) => {
|
( $( $name:ident ),+ ) => {
|
||||||
$(
|
$(
|
||||||
#[derive(clap::Clap, derive_ahk::Ahk)]
|
#[derive(clap::Clap, derive_ahk::AhkFunction)]
|
||||||
pub struct $name {
|
pub struct $name {
|
||||||
/// Target index (zero-indexed)
|
/// Target index (zero-indexed)
|
||||||
target: usize,
|
target: usize,
|
||||||
@@ -104,7 +113,7 @@ macro_rules! gen_workspace_subcommand_args {
|
|||||||
( $( $name:ident: $(#[enum] $(@$arg_enum:tt)?)? $value:ty ),+ ) => (
|
( $( $name:ident: $(#[enum] $(@$arg_enum:tt)?)? $value:ty ),+ ) => (
|
||||||
paste! {
|
paste! {
|
||||||
$(
|
$(
|
||||||
#[derive(clap::Clap, derive_ahk::Ahk)]
|
#[derive(clap::Clap, derive_ahk::AhkFunction)]
|
||||||
pub struct [<Workspace $name>] {
|
pub struct [<Workspace $name>] {
|
||||||
/// Monitor index (zero-indexed)
|
/// Monitor index (zero-indexed)
|
||||||
monitor: usize,
|
monitor: usize,
|
||||||
@@ -130,7 +139,7 @@ gen_workspace_subcommand_args! {
|
|||||||
Tiling: #[enum] BooleanState
|
Tiling: #[enum] BooleanState
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clap, Ahk)]
|
#[derive(Clap, AhkFunction)]
|
||||||
struct Resize {
|
struct Resize {
|
||||||
#[clap(arg_enum)]
|
#[clap(arg_enum)]
|
||||||
edge: OperationDirection,
|
edge: OperationDirection,
|
||||||
@@ -138,7 +147,7 @@ struct Resize {
|
|||||||
sizing: Sizing,
|
sizing: Sizing,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clap, Ahk)]
|
#[derive(Clap, AhkFunction)]
|
||||||
struct EnsureWorkspaces {
|
struct EnsureWorkspaces {
|
||||||
/// Monitor index (zero-indexed)
|
/// Monitor index (zero-indexed)
|
||||||
monitor: usize,
|
monitor: usize,
|
||||||
@@ -150,7 +159,7 @@ macro_rules! gen_padding_subcommand_args {
|
|||||||
// SubCommand Pattern
|
// SubCommand Pattern
|
||||||
( $( $name:ident ),+ ) => {
|
( $( $name:ident ),+ ) => {
|
||||||
$(
|
$(
|
||||||
#[derive(clap::Clap, derive_ahk::Ahk)]
|
#[derive(clap::Clap, derive_ahk::AhkFunction)]
|
||||||
pub struct $name {
|
pub struct $name {
|
||||||
/// Monitor index (zero-indexed)
|
/// Monitor index (zero-indexed)
|
||||||
monitor: usize,
|
monitor: usize,
|
||||||
@@ -172,7 +181,7 @@ macro_rules! gen_padding_adjustment_subcommand_args {
|
|||||||
// SubCommand Pattern
|
// SubCommand Pattern
|
||||||
( $( $name:ident ),+ ) => {
|
( $( $name:ident ),+ ) => {
|
||||||
$(
|
$(
|
||||||
#[derive(clap::Clap, derive_ahk::Ahk)]
|
#[derive(clap::Clap, derive_ahk::AhkFunction)]
|
||||||
pub struct $name {
|
pub struct $name {
|
||||||
#[clap(arg_enum)]
|
#[clap(arg_enum)]
|
||||||
sizing: Sizing,
|
sizing: Sizing,
|
||||||
@@ -192,7 +201,7 @@ macro_rules! gen_application_target_subcommand_args {
|
|||||||
// SubCommand Pattern
|
// SubCommand Pattern
|
||||||
( $( $name:ident ),+ ) => {
|
( $( $name:ident ),+ ) => {
|
||||||
$(
|
$(
|
||||||
#[derive(clap::Clap, derive_ahk::Ahk)]
|
#[derive(clap::Clap, derive_ahk::AhkFunction)]
|
||||||
pub struct $name {
|
pub struct $name {
|
||||||
#[clap(arg_enum)]
|
#[clap(arg_enum)]
|
||||||
identifier: ApplicationIdentifier,
|
identifier: ApplicationIdentifier,
|
||||||
@@ -209,7 +218,7 @@ gen_application_target_subcommand_args! {
|
|||||||
IdentifyTrayApplication
|
IdentifyTrayApplication
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clap, Ahk)]
|
#[derive(Clap, AhkFunction)]
|
||||||
struct WorkspaceRule {
|
struct WorkspaceRule {
|
||||||
#[clap(arg_enum)]
|
#[clap(arg_enum)]
|
||||||
identifier: ApplicationIdentifier,
|
identifier: ApplicationIdentifier,
|
||||||
@@ -228,7 +237,7 @@ struct Opts {
|
|||||||
subcmd: SubCommand,
|
subcmd: SubCommand,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clap, Ahk)]
|
#[derive(Clap, AhkLibrary)]
|
||||||
enum SubCommand {
|
enum SubCommand {
|
||||||
/// Start komorebi.exe as a background process
|
/// Start komorebi.exe as a background process
|
||||||
Start,
|
Start,
|
||||||
|
|||||||
Reference in New Issue
Block a user