Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,53 @@ description = "A Rust framework for developing WSL plugins using safe and idioma

[patch.crates-io]
wslpluginapi-sys = { version = "0.1.0-rc.1", git = "https://github.com/mveril/wslpluginapi-sys.git", branch = "develop" }


[workspace.lints.rust]
unused = "warn"
future_incompatible = "deny"

[workspace.lints.clippy]
all = { level = "warn", priority = -1 }
pedantic = { level = "warn", priority = -1 }
nursery = { level = "warn", priority = -1 }
cargo = {level = "warn", priority = -1}
# Enable some restriction
needless_pass_by_value = "warn"
implicit_clone = "warn"
unnecessary_wraps = "warn"
missing_const_for_fn = "warn"
missing_inline_in_public_items = "warn"
unnecessary_safety_doc = "deny"

# ---- Strong DENY (CI-breaking, catch critical bugs) ----
unwrap_used = "deny" # Avoid panics in production.
expect_used = "deny" # Same as unwrap, no `.expect`.
panic = "deny" # No panic! in library code.
todo = "deny" # No todo! in shipped code.
print_stdout = "deny" # Use logging, not println.
print_stderr = "deny" # Use logging, not eprintln.
dbg_macro = "deny" # No dbg! in release builds.
mem_forget = "deny" # Prevent memory leaks.
await_holding_lock = "deny" # Prevent async deadlocks with held locks.
exit = "deny" # Libraries must not kill the process.

# ---- Useful WARN (signal, but not blocking) ----
undocumented_unsafe_blocks = "warn" # Every unsafe block must be justified with SAFETY.
missing_assert_message = "warn" # Clear messages for all asserts.
integer_division = "warn" # Be explicit about truncating integer division.
indexing_slicing = "warn" # Can panic if index is wrong.
float_arithmetic = "warn" # Flag nondeterministic floating arithmetic.
mutable_key_type = "warn" # Prevent mutable keys in maps (subtle bugs).
manual_non_exhaustive = "warn" # Use #[non_exhaustive] instead of manual tricks.
wrong_self_convention = "warn" # Enforce idiomatic naming for as_/to_/into_ methods.
rc_mutex = "warn"
use_debug = "warn"

[workspace.lints.rustdoc]
all = "warn"
broken_intra_doc_links = "forbid"
private_intra_doc_links = "deny"
invalid_rust_codeblocks = "deny"
bare_urls = "warn"
missing_crate_level_docs = "warn"
6 changes: 6 additions & 0 deletions wslplugins-macro-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ version.workspace = true
license.workspace = true
repository.workspace = true
edition = "2021"
description = "internal core implementation of for wslplugins-macro"
keywords = ["wsl", "plugin", "windows", "linux", "internal"]
categories = ["os::windows-apis", "api-bindings", "virtualization"]

[dependencies]
syn = { version = "*", features = ["full", "extra-traits"] }
Expand All @@ -17,3 +20,6 @@ strum = { version = "0.26.3", features = ["derive"] }
wslpluginapi-sys = { workspace = true, features = ["hooks-field-names"] }
quote = "*"
struct-field-names-as-array = "*"

[lints]
workspace = true
2 changes: 2 additions & 0 deletions wslplugins-macro-core/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# wslplugins-macro-core
This package is a dependency of `wslplugins-macro` and provide the core of the macro logic it not intended to be installed manually
5 changes: 3 additions & 2 deletions wslplugins-macro-core/build.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::{env, fs::File, io::Write, path::PathBuf};
use struct_field_names_as_array::FieldNamesAsSlice;
#![allow(missing_docs)]
use std::{env, fs::File, io::Write as _, path::PathBuf};
use struct_field_names_as_array::FieldNamesAsSlice as _;
use wslpluginapi_sys::WSLPluginHooksV1;

fn main() -> Result<(), Box<dyn std::error::Error>> {
Expand Down
17 changes: 1 addition & 16 deletions wslplugins-macro-core/src/generator/c_funcs_tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,22 +69,7 @@ pub(super) fn get_c_func_tokens(hook: Hooks) -> Result<Option<TokenStream>> {
}).unwrap_or(::wslplugins_rs::sys::windows_sys::Win32::Foundation::E_FAIL)
}
}),
Hooks::OnDistributionRegistered => Some(quote! {
extern "C" fn #c_method_ident(
session: *const ::wslplugins_rs::sys::WSLSessionInformation,
distribution: *const ::wslplugins_rs::sys::WSLOfflineDistributionInformation,
) -> ::wslplugins_rs::sys::windows_sys::core::HRESULT {
let session_ptr = unsafe { &*session };
let distribution_ptr = unsafe { &*distribution };
PLUGIN.get().map(|plugin|{
::wslplugins_rs::windows_core::HRESULT::from(plugin.#trait_method_ident(
session_ptr.as_ref(),
distribution_ptr.as_ref(),
)).0
}).unwrap_or(::wslplugins_rs::sys::windows_sys::Win32::Foundation)
}
}),
Hooks::OnDistributionUnregistered => Some(quote! {
Hooks::OnDistributionRegistered | Hooks::OnDistributionUnregistered => Some(quote! {
extern "C" fn #c_method_ident(
session: *const ::wslplugins_rs::sys::WSLSessionInformation,
distribution: *const ::wslplugins_rs::sys::WSLOfflineDistributionInformation,
Expand Down
6 changes: 3 additions & 3 deletions wslplugins-macro-core/src/generator/hook_field_mapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ fn generate_hook_fns(hooks: &[Hooks]) -> Result<Vec<TokenStream>> {
}

// Create a static version of the type for plugin management
fn create_static_type(imp: &ParsedImpl) -> Result<Type> {
fn create_static_type(imp: &ParsedImpl) -> Type {
let mut static_type = imp.target_type.as_ref().clone();
if let Some(lifetime) = utils::get_path_lifetime(&imp.trait_) {
utils::replace_lifetime_in_type(
Expand All @@ -41,7 +41,7 @@ fn create_static_type(imp: &ParsedImpl) -> Result<Type> {
&Lifetime::new("'static", Span::call_site()),
);
}
Ok(static_type)
static_type
}

// Prepare hooks by mapping them to their respective fields in the hook structure
Expand Down Expand Up @@ -83,7 +83,7 @@ fn hook_field_mapping(hooks_struct_name: &Ident, hook: Hooks) -> Result<TokenStr

// Generate the plugin entry function with hook management and initialization
fn generate_entry_point(imp: &ParsedImpl, version: &RequiredVersion) -> Result<TokenStream> {
let static_plugin_type = create_static_type(imp)?;
let static_plugin_type = create_static_type(imp);
let hooks_ref_name = format_ident!("hooks_ref");
let hook_set = prepare_hooks(&hooks_ref_name, &imp.hooks)?;
let RequiredVersion {
Expand Down
2 changes: 1 addition & 1 deletion wslplugins-macro-core/src/generator/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
mod c_funcs_tokens;
mod hook_field_mapping;
mod utils;
pub(crate) use hook_field_mapping::generate;
pub use hook_field_mapping::generate;
5 changes: 4 additions & 1 deletion wslplugins-macro-core/src/generator/utils.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use syn::*;
use syn::{
GenericArgument, Lifetime, Path, PathArguments, Type, TypeBareFn, TypePath, TypeReference,
TypeTuple,
};

pub(super) fn replace_lifetime_in_type(
ty: &mut Type,
Expand Down
14 changes: 7 additions & 7 deletions wslplugins-macro-core/src/hooks.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
use heck::ToSnakeCase;
use strum::IntoEnumIterator;
use heck::ToSnakeCase as _;
use strum::IntoEnumIterator as _;
include!(concat!(env!("OUT_DIR"), "/hooks.rs"));

impl Hooks {
pub fn get_c_method_name(&self) -> String {
pub(crate) fn get_c_method_name(self) -> String {
self.to_string().to_snake_case()
}

pub fn get_hook_field_name(&self) -> String {
pub(crate) fn get_hook_field_name(self) -> String {
self.to_string()
}

pub fn get_trait_method_name(&self) -> String {
pub(crate) fn get_trait_method_name(self) -> String {
self.to_string().to_snake_case()
}

pub fn from_trait_method_name(trait_method_name: impl AsRef<str>) -> Option<Hooks> {
Hooks::iter().find(|hook| hook.get_trait_method_name() == trait_method_name.as_ref())
pub(crate) fn from_trait_method_name(trait_method_name: impl AsRef<str>) -> Option<Self> {
Self::iter().find(|hook| hook.get_trait_method_name() == trait_method_name.as_ref())
}
}

Expand Down
9 changes: 7 additions & 2 deletions wslplugins-macro-core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
#![allow(rustdoc::missing_doc)]
#![allow(clippy::missing_errors_doc)]
#![allow(clippy::missing_panics_doc)]
#![allow(clippy::panic)]
#![allow(clippy::panic_in_result_fn)]
mod generator;
mod hooks;
mod parser;
Expand All @@ -9,8 +14,8 @@ use quote::quote;
use syn::{parse2, Result};

use crate::parser::{ParsedImpl, RequiredVersion};

pub fn wsl_plugin_v1(attr: TokenStream, item: TokenStream) -> Result<TokenStream> {
#[inline]
pub fn wsl_plugin_v1(attr: TokenStream, item: &TokenStream) -> Result<TokenStream> {
let parsed_impl_result = parse2::<ParsedImpl>(item.clone());
let required_version_result = parse2::<RequiredVersion>(attr);
let (parsed_impl, required_version) =
Expand Down
8 changes: 4 additions & 4 deletions wslplugins-macro-core/src/parser/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub(crate) mod parsed_impl;
pub(crate) mod required_version;
pub(crate) use parsed_impl::ParsedImpl;
pub(crate) use required_version::RequiredVersion;
pub mod parsed_impl;
pub mod required_version;
pub use parsed_impl::ParsedImpl;
pub use required_version::RequiredVersion;
18 changes: 7 additions & 11 deletions wslplugins-macro-core/src/parser/parsed_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,13 @@ pub struct ParsedImpl {
}

impl Parse for ParsedImpl {
fn parse(input: ParseStream) -> Result<Self> {
fn parse(input: ParseStream<'_>) -> Result<Self> {
let plugin_impl: ItemImpl = input.parse()?;
let p =
plugin_impl
.trait_
.as_ref()
.map(|(_, path, _)| path)
.ok_or(syn::Error::new_spanned(
plugin_impl.impl_token,
"Expected a trait.",
))?;
let p = plugin_impl
.trait_
.as_ref()
.map(|(_, path, _)| path)
.ok_or_else(|| syn::Error::new_spanned(plugin_impl.impl_token, "Expected a trait."))?;
let hook_vec: Vec<Hooks> = plugin_impl
.items
.iter()
Expand All @@ -31,7 +27,7 @@ impl Parse for ParsedImpl {
})
.collect();

Ok(ParsedImpl {
Ok(Self {
target_type: plugin_impl.self_ty.clone(),
hooks: hook_vec.into_boxed_slice(),
trait_: p.clone(),
Expand Down
10 changes: 4 additions & 6 deletions wslplugins-macro-core/src/parser/required_version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub struct RequiredVersion {
pub revision: u32,
}
impl Parse for RequiredVersion {
fn parse(input: ParseStream) -> Result<Self> {
fn parse(input: ParseStream<'_>) -> Result<Self> {
// Result of parsing the major version to u32
let major_lit = input.parse::<LitInt>()?;
// Result of parsing the coma version to u32
Expand All @@ -21,7 +21,7 @@ impl Parse for RequiredVersion {
let minor_lit = input.parse::<LitInt>()?;
// Parse the revision if it exists
let revision_lit = if input.peek(Token![,]) {
input.parse::<Token![,]>().unwrap();
input.parse::<Token![,]>()?;
Some(input.parse::<LitInt>()?)
} else {
None
Expand All @@ -33,11 +33,9 @@ impl Parse for RequiredVersion {
}?;
let major_result = major_lit.base10_parse::<u32>();
let minor_result = minor_lit.base10_parse::<u32>();
let revision_result = revision_lit
.map(|lit| lit.base10_parse::<u32>())
.unwrap_or(Ok(0));
let revision_result = revision_lit.map_or(Ok(0), |lit| lit.base10_parse::<u32>());
acc_syn_result!(major_result, minor_result, revision_result).map(
|(major, minor, revision)| RequiredVersion {
|(major, minor, revision)| Self {
major,
minor,
revision,
Expand Down
5 changes: 5 additions & 0 deletions wslplugins-macro/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ version.workspace = true
license.workspace = true
repository.workspace = true
edition = "2021"
description = "macro for wslplugins-rs"
keywords = ["wsl", "plugin", "windows", "linux", "internal"]
categories = ["os::windows-apis", "api-bindings", "virtualization"]

[lib]
proc-macro = true
Expand All @@ -14,3 +17,5 @@ syn = "*"
quote = "*"
proc-macro2 = "*"
wslplugins-macro-core = { path = "../wslplugins-macro-core" }
[lints]
workspace = true
2 changes: 2 additions & 0 deletions wslplugins-macro/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# wslplugins-macro-core
This package is an optional dependency of `wslplugins-rs` and provide macro for it's not intended to be installed manually
13 changes: 11 additions & 2 deletions wslplugins-macro/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
#![allow(missing_docs)]
use proc_macro::TokenStream;

/// Attribute macro for WSL plugin V1.
/// This macro should be used on impl block of `WSLPluginV1` in order to register the plugin that implement this interface
/// # Example
/// ``` rust, ignore
/// #[wsl_plugin_v1]
/// impl WSLPluginV1 for MyPlugin {
/// // Implementation details
/// }
/// ```
#[proc_macro_attribute]
pub fn wsl_plugin_v1(attr: TokenStream, item: TokenStream) -> TokenStream {
wslplugins_macro_core::wsl_plugin_v1(attr.into(), item.into())
wslplugins_macro_core::wsl_plugin_v1(attr.into(), &item.into())
.unwrap_or_else(|err| err.to_compile_error())
.into()
}
8 changes: 7 additions & 1 deletion wslplugins-rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ license.workspace = true
repository.workspace = true
description.workspace = true
edition = "2021"

keywords = ["wsl", "plugin", "windows", "linux"]
categories = ["os::windows-apis", "api-bindings", "virtualization"]
readme.workspace = true

[dependencies]
windows-core = "0.61.2"
Expand All @@ -21,6 +23,7 @@ widestring = { version = "1", features = ["alloc"] }
wslplugins-macro = { path = "../wslplugins-macro", optional = true }
wslpluginapi-sys.workspace = true


[dependencies.semver]
version = ">0.1"
optional = true
Expand All @@ -33,3 +36,6 @@ macro = ["dep:wslplugins-macro", "sys"]
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]

[lints]
workspace = true
Loading
Loading