diff --git a/wslplugins-macro-core/src/generator/c_funcs_tokens.rs b/wslplugins-macro-core/src/generator/c_funcs_tokens.rs index 11a3624..8f97230 100644 --- a/wslplugins-macro-core/src/generator/c_funcs_tokens.rs +++ b/wslplugins-macro-core/src/generator/c_funcs_tokens.rs @@ -18,8 +18,8 @@ pub(super) fn get_c_func_tokens(hook: Hooks) -> Result> { let settings_ptr = unsafe { &*settings }; if let Some(plugin) = PLUGIN.get() { let result = plugin.#trait_method_ident( - &::wslplugins_rs::WSLSessionInformation::from(session_ptr), - &::wslplugins_rs::WSLVmCreationSettings::from(settings_ptr), + session_ptr.as_ref(), + settings_ptr.as_ref(), ); ::wslplugins_rs::plugin::utils::consume_to_win_result(result).into() } else { @@ -33,7 +33,7 @@ pub(super) fn get_c_func_tokens(hook: Hooks) -> Result> { ) -> ::windows::core::HRESULT { let session_ptr = unsafe { &*session }; if let Some(plugin) = PLUGIN.get() { - plugin.#trait_method_ident(&::wslplugins_rs::WSLSessionInformation::from(session_ptr)).into() + plugin.#trait_method_ident(session_ptr.as_ref()).into() } else { ::windows::Win32::Foundation::E_FAIL } @@ -48,8 +48,8 @@ pub(super) fn get_c_func_tokens(hook: Hooks) -> Result> { let distribution_ptr = unsafe { &*distribution }; if let Some(plugin) = PLUGIN.get() { let result = plugin.#trait_method_ident( - &::wslplugins_rs::WSLSessionInformation::from(session_ptr), - &::wslplugins_rs::DistributionInformation::from(distribution_ptr), + session_ptr.as_ref(), + distribution_ptr.as_ref(), ); ::wslplugins_rs::plugin::utils::consume_to_win_result(result).into() } else { @@ -66,8 +66,8 @@ pub(super) fn get_c_func_tokens(hook: Hooks) -> Result> { let distribution_ptr = unsafe { &*distribution }; if let Some(plugin) = PLUGIN.get() { plugin.#trait_method_ident( - &::wslplugins_rs::WSLSessionInformation::from(session_ptr), - &::wslplugins_rs::DistributionInformation::from(distribution_ptr), + session_ptr.as_ref(), + distribution_ptr.as_ref(), ).into() } else { ::windows::Win32::Foundation::E_FAIL @@ -83,8 +83,8 @@ pub(super) fn get_c_func_tokens(hook: Hooks) -> Result> { let distribution_ptr = unsafe { &*distribution }; if let Some(plugin) = PLUGIN.get() { plugin.#trait_method_ident( - &::wslplugins_rs::WSLSessionInformation::from(session_ptr), - &::wslplugins_rs::OfflineDistributionInformation::from(distribution_ptr), + session_ptr.as_ref(), + distribution_ptr.as_ref(), ).into() } else { ::windows::Win32::Foundation::E_FAIL @@ -100,8 +100,8 @@ pub(super) fn get_c_func_tokens(hook: Hooks) -> Result> { let distribution_ptr = unsafe { &*distribution }; if let Some(plugin) = PLUGIN.get() { plugin.#trait_method_ident( - &::wslplugins_rs::WSLSessionInformation::from(session_ptr), - &::wslplugins_rs::OfflineDistributionInformation::from(distribution_ptr), + session_ptr.as_ref(), + distribution_ptr.as_ref(), ).into() } else { ::windows::Win32::Foundation::E_FAIL diff --git a/wslplugins-rs/src/api/api_v1.rs b/wslplugins-rs/src/api/api_v1.rs index dc5a568..2be24bd 100644 --- a/wslplugins-rs/src/api/api_v1.rs +++ b/wslplugins-rs/src/api/api_v1.rs @@ -30,16 +30,34 @@ use super::utils::check_required_version_result; /// Represents a structured interface for interacting with the WSLPluginAPIV1 API. /// This struct encapsulates the methods provided by the WSLPluginAPIV1 API, allowing /// idiomatic interaction with the Windows Subsystem for Linux (WSL). -pub struct ApiV1<'a>(&'a WSLPluginAPIV1); +#[repr(transparent)] +pub struct ApiV1(WSLPluginAPIV1); -/// Converts a raw reference to `WSLPluginAPIV1` into [ApiV1]. -impl<'a> From<&'a WSLPluginAPIV1> for ApiV1<'a> { - fn from(value: &'a WSLPluginAPIV1) -> Self { - Self(value) +impl From for WSLPluginAPIV1 { + fn from(value: ApiV1) -> Self { + value.0 } } -impl ApiV1<'_> { +impl From for ApiV1 { + fn from(value: WSLPluginAPIV1) -> Self { + ApiV1(value) + } +} + +impl AsRef for ApiV1 { + fn as_ref(&self) -> &WSLPluginAPIV1 { + &self.0 + } +} + +impl AsRef for WSLPluginAPIV1 { + fn as_ref(&self) -> &ApiV1 { + unsafe { &*(self as *const WSLPluginAPIV1 as *const ApiV1) } + } +} + +impl ApiV1 { /// Returns the current version of the WSL API being used. /// /// This is useful for checking compatibility with specific API features. @@ -252,10 +270,21 @@ impl ApiV1<'_> { } } -impl Debug for ApiV1<'_> { +impl Debug for ApiV1 { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("ApiV1") .field("version", self.version()) .finish() } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::utils::test_transparence; + + #[test] + fn test_layouts() { + test_transparence::(); + } +} diff --git a/wslplugins-rs/src/distribution_information.rs b/wslplugins-rs/src/distribution_information.rs index 281d306..101b7e2 100644 --- a/wslplugins-rs/src/distribution_information.rs +++ b/wslplugins-rs/src/distribution_information.rs @@ -31,22 +31,37 @@ use wslplugins_sys::WSLVersion; /// /// This struct wraps the `WSLDistributionInformation` from the WSL Plugin API and provides /// safe, idiomatic Rust access to its fields. -pub struct DistributionInformation<'a>(&'a wslplugins_sys::WSLDistributionInformation); +#[repr(transparent)] +pub struct DistributionInformation(wslplugins_sys::WSLDistributionInformation); -impl<'a> From<&'a wslplugins_sys::WSLDistributionInformation> for DistributionInformation<'a> { - /// Creates a `DistributionInformation` instance from a reference to the raw WSL Plugin API structure. - /// - /// # Arguments - /// - `ptr`: A reference to a `WSLDistributionInformation` instance. - /// - /// # Returns - /// A wrapped `DistributionInformation` instance. - fn from(ptr: &'a wslplugins_sys::WSLDistributionInformation) -> Self { - Self(ptr) +impl AsRef for wslplugins_sys::WSLDistributionInformation { + fn as_ref(&self) -> &DistributionInformation { + unsafe { + &*(self as *const wslplugins_sys::WSLDistributionInformation + as *const DistributionInformation) + } + } +} + +impl From for wslplugins_sys::WSLDistributionInformation { + fn from(value: DistributionInformation) -> Self { + value.0 + } +} + +impl AsRef for DistributionInformation { + fn as_ref(&self) -> &wslplugins_sys::WSLDistributionInformation { + &self.0 + } +} + +impl From for DistributionInformation { + fn from(value: wslplugins_sys::WSLDistributionInformation) -> Self { + DistributionInformation(value) } } -impl DistributionInformation<'_> { +impl DistributionInformation { /// Retrieves the PID of the init process. /// /// This requires API version 2.0.5 or higher. If the current API version does not meet @@ -74,7 +89,7 @@ impl DistributionInformation<'_> { } } -impl CoreDistributionInformation for DistributionInformation<'_> { +impl CoreDistributionInformation for DistributionInformation { /// Retrieves the unique ID of the distribution. /// /// # Returns @@ -108,7 +123,7 @@ impl CoreDistributionInformation for DistributionInformation<'_> { } } -impl PartialEq for DistributionInformation<'_> +impl PartialEq for DistributionInformation where T: CoreDistributionInformation, { @@ -118,14 +133,14 @@ where } } -impl Hash for DistributionInformation<'_> { +impl Hash for DistributionInformation { /// Computes a hash based on the distribution's ID. fn hash(&self, state: &mut H) { self.id().hash(state); } } -impl Display for DistributionInformation<'_> { +impl Display for DistributionInformation { /// Formats the distribution information for display. /// /// The output includes the distribution's name and ID. @@ -134,7 +149,7 @@ impl Display for DistributionInformation<'_> { } } -impl Debug for DistributionInformation<'_> { +impl Debug for DistributionInformation { /// Formats the distribution information for debugging. /// /// The output includes: @@ -156,3 +171,14 @@ impl Debug for DistributionInformation<'_> { } } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::utils::test_transparence; + + #[test] + fn test_layouts() { + test_transparence::(); + } +} diff --git a/wslplugins-rs/src/offline_distribution_information.rs b/wslplugins-rs/src/offline_distribution_information.rs index d3cde04..58278c8 100644 --- a/wslplugins-rs/src/offline_distribution_information.rs +++ b/wslplugins-rs/src/offline_distribution_information.rs @@ -17,27 +17,37 @@ use windows::core::GUID; /// /// This struct allows access to the details of an offline WSL distribution, including /// its ID, name, and optional package family name. -/// -/// # Lifetime Parameters -/// - `'a`: The lifetime of the referenced `WslOfflineDistributionInformation` instance. -pub struct OfflineDistributionInformation<'a>( - &'a wslplugins_sys::WslOfflineDistributionInformation, -); +#[repr(transparent)] +pub struct OfflineDistributionInformation(wslplugins_sys::WslOfflineDistributionInformation); -impl<'a> OfflineDistributionInformation<'a> { - /// Creates a new `OfflineDistributionInformation` instance from a raw pointer. - /// - /// # Arguments - /// - `ptr`: A reference to a `WslOfflineDistributionInformation` instance. - /// - /// # Returns - /// A safe wrapper around the provided pointer. - pub fn from(ptr: &'a wslplugins_sys::WslOfflineDistributionInformation) -> Self { - Self(ptr) +impl From for wslplugins_sys::WslOfflineDistributionInformation { + fn from(value: OfflineDistributionInformation) -> Self { + value.0 + } +} + +impl From for OfflineDistributionInformation { + fn from(value: wslplugins_sys::WslOfflineDistributionInformation) -> Self { + OfflineDistributionInformation(value) + } +} + +impl AsRef for OfflineDistributionInformation { + fn as_ref(&self) -> &wslplugins_sys::WslOfflineDistributionInformation { + &self.0 } } -impl CoreDistributionInformation for OfflineDistributionInformation<'_> { +impl AsRef for wslplugins_sys::WslOfflineDistributionInformation { + fn as_ref(&self) -> &OfflineDistributionInformation { + unsafe { + &*(self as *const wslplugins_sys::WslOfflineDistributionInformation + as *const OfflineDistributionInformation) + } + } +} + +impl CoreDistributionInformation for OfflineDistributionInformation { /// Retrieves the [GUID] of the offline distribution. fn id(&self) -> GUID { self.0.Id @@ -65,7 +75,7 @@ impl CoreDistributionInformation for OfflineDistributionInformation<'_> { } } -impl PartialEq for OfflineDistributionInformation<'_> +impl PartialEq for OfflineDistributionInformation where T: CoreDistributionInformation, { @@ -75,14 +85,14 @@ where } } -impl Hash for OfflineDistributionInformation<'_> { +impl Hash for OfflineDistributionInformation { /// Computes a hash based on the distribution's ID. fn hash(&self, state: &mut H) { self.id().hash(state); } } -impl Display for OfflineDistributionInformation<'_> { +impl Display for OfflineDistributionInformation { /// Formats the offline distribution information for display. /// /// The output includes the distribution's name and ID. @@ -91,7 +101,7 @@ impl Display for OfflineDistributionInformation<'_> { } } -impl Debug for OfflineDistributionInformation<'_> { +impl Debug for OfflineDistributionInformation { /// Formats the offline distribution information for debugging. /// /// The output includes the distribution's name, ID, and package family name. @@ -103,3 +113,17 @@ impl Debug for OfflineDistributionInformation<'_> { .finish() } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::utils::test_transparence; + + #[test] + fn test_layouts() { + test_transparence::< + wslplugins_sys::WslOfflineDistributionInformation, + OfflineDistributionInformation, + >(); + } +} diff --git a/wslplugins-rs/src/plugin/utils.rs b/wslplugins-rs/src/plugin/utils.rs index 3e9257a..f34da12 100644 --- a/wslplugins-rs/src/plugin/utils.rs +++ b/wslplugins-rs/src/plugin/utils.rs @@ -9,7 +9,7 @@ use windows::{ }; use wslplugins_sys::WSLPluginAPIV1; -use crate::{api::ApiV1, WSLContext}; +use crate::WSLContext; #[cfg(doc)] use super::Error; @@ -50,7 +50,7 @@ pub fn create_plugin_with_required_version( wslplugins_sys::require_version(required_major, required_minor, required_revision, api) .ok()?; } - if let Some(context) = WSLContext::init(ApiV1::from(api)) { + if let Some(context) = WSLContext::init(api.as_ref()) { let plugin = T::try_new(context)?; Ok(plugin) } else { diff --git a/wslplugins-rs/src/utils.rs b/wslplugins-rs/src/utils.rs index 5a4572b..96ffa4a 100644 --- a/wslplugins-rs/src/utils.rs +++ b/wslplugins-rs/src/utils.rs @@ -20,6 +20,12 @@ pub fn cstring_from_str(input: &str) -> CString { unsafe { CString::from_vec_unchecked(filtered_input) } } +#[cfg(test)] +pub(crate) fn test_transparence() { + assert_eq!(align_of::(), align_of::()); + assert_eq!(size_of::(), size_of::()); +} + #[cfg(test)] mod tests { use super::*; diff --git a/wslplugins-rs/src/wsl_context.rs b/wslplugins-rs/src/wsl_context.rs index f908a38..6880da4 100644 --- a/wslplugins-rs/src/wsl_context.rs +++ b/wslplugins-rs/src/wsl_context.rs @@ -16,7 +16,7 @@ static CURRENT_CONTEXT: OnceLock = OnceLock::new(); /// throughout the plugin's lifecycle. pub struct WSLContext { /// The API interface used for interacting with the WSL plugin API. - pub api: ApiV1<'static>, + pub api: &'static ApiV1, } impl WSLContext { @@ -59,7 +59,7 @@ impl WSLContext { /// # Returns /// - `Some(&'static WSLContext)`: If the context was successfully initialized. /// - `None`: If the context has already been initialized. - pub fn init(api: ApiV1<'static>) -> Option<&'static Self> { + pub fn init(api: &'static ApiV1) -> Option<&'static Self> { CURRENT_CONTEXT.set(WSLContext { api }).ok()?; CURRENT_CONTEXT.get() } diff --git a/wslplugins-rs/src/wsl_session_information.rs b/wslplugins-rs/src/wsl_session_information.rs index 654bde5..4c71432 100644 --- a/wslplugins-rs/src/wsl_session_information.rs +++ b/wslplugins-rs/src/wsl_session_information.rs @@ -13,12 +13,9 @@ use windows::Win32::Security::PSID; /// /// This struct wraps the `WSLSessionInformation` provided by the WSL Plugin API and /// provides safe, idiomatic access to its fields. -/// -/// # Lifetime Parameters -/// - `'a`: The lifetime of the referenced `WSLSessionInformation` instance. -pub struct WSLSessionInformation<'a>(&'a wslplugins_sys::WSLSessionInformation); +pub struct WSLSessionInformation(wslplugins_sys::WSLSessionInformation); -impl WSLSessionInformation<'_> { +impl WSLSessionInformation { /// Retrieves the session ID. /// /// # Returns @@ -44,20 +41,33 @@ impl WSLSessionInformation<'_> { } } -impl<'a> From<&'a wslplugins_sys::WSLSessionInformation> for WSLSessionInformation<'a> { - /// Creates a `WSLSessionInformation` instance from a reference to `WSLSessionInformation` from the API. - /// - /// # Arguments - /// - `ptr`: A reference to a `WSLSessionInformation` instance. - /// - /// # Returns - /// A safe wrapper around the provided pointer. - fn from(ptr: &'a wslplugins_sys::WSLSessionInformation) -> Self { - Self(ptr) +impl From for WSLSessionInformation { + fn from(value: wslplugins_sys::WSLSessionInformation) -> Self { + WSLSessionInformation(value) } } -impl hash::Hash for WSLSessionInformation<'_> { +impl From for wslplugins_sys::WSLSessionInformation { + fn from(value: WSLSessionInformation) -> Self { + value.0 + } +} + +impl AsRef for wslplugins_sys::WSLSessionInformation { + fn as_ref(&self) -> &WSLSessionInformation { + unsafe { + &*(self as *const wslplugins_sys::WSLSessionInformation as *const WSLSessionInformation) + } + } +} + +impl AsRef for WSLSessionInformation { + fn as_ref(&self) -> &wslplugins_sys::WSLSessionInformation { + &self.0 + } +} + +impl hash::Hash for WSLSessionInformation { /// Computes a hash based on the session ID. /// /// # Arguments @@ -67,7 +77,7 @@ impl hash::Hash for WSLSessionInformation<'_> { } } -impl PartialEq for WSLSessionInformation<'_> { +impl PartialEq for WSLSessionInformation { /// Compares two `WSLSessionInformation` instances for equality based on their session IDs. /// /// # Arguments @@ -81,7 +91,7 @@ impl PartialEq for WSLSessionInformation<'_> { } // Manually implements Debug for `WSLSessionInformation`. -impl fmt::Debug for WSLSessionInformation<'_> { +impl fmt::Debug for WSLSessionInformation { /// Formats the session information for debugging. /// /// The output includes the session ID, user token, and user SID. @@ -93,3 +103,15 @@ impl fmt::Debug for WSLSessionInformation<'_> { .finish() } } + +#[cfg(test)] +mod tests { + use crate::utils::test_transparence; + + use super::WSLSessionInformation; + + #[test] + fn test_layouts() { + test_transparence::(); + } +} diff --git a/wslplugins-rs/src/wsl_vm_creation_settings.rs b/wslplugins-rs/src/wsl_vm_creation_settings.rs index 34c080b..8e44ec4 100644 --- a/wslplugins-rs/src/wsl_vm_creation_settings.rs +++ b/wslplugins-rs/src/wsl_vm_creation_settings.rs @@ -12,25 +12,35 @@ use crate::WSLUserConfiguration; /// /// This struct wraps the `WSLVmCreationSettings` structure from the WSL Plugin API, providing /// safe and idiomatic Rust access to its fields. -/// -/// # Lifetime Parameters -/// - `'a`: The lifetime of the referenced `WSLVmCreationSettings` instance. -pub struct WSLVmCreationSettings<'a>(&'a wslplugins_sys::WSLVmCreationSettings); +pub struct WSLVmCreationSettings(wslplugins_sys::WSLVmCreationSettings); -impl<'a> From<&'a wslplugins_sys::WSLVmCreationSettings> for WSLVmCreationSettings<'a> { - /// Creates a `WSLVmCreationSettings` instance from a reference to the raw WSL Plugin API structure. - /// - /// # Arguments - /// - `value`: A reference to a `WSLVmCreationSettings` instance from the WSL Plugin API. - /// - /// # Returns - /// A wrapped `WSLVmCreationSettings` instance. - fn from(value: &'a wslplugins_sys::WSLVmCreationSettings) -> Self { +impl From for WSLVmCreationSettings { + fn from(value: wslplugins_sys::WSLVmCreationSettings) -> Self { WSLVmCreationSettings(value) } } -impl WSLVmCreationSettings<'_> { +impl From for wslplugins_sys::WSLVmCreationSettings { + fn from(value: WSLVmCreationSettings) -> Self { + value.0 + } +} + +impl AsRef for WSLVmCreationSettings { + fn as_ref(&self) -> &wslplugins_sys::WSLVmCreationSettings { + &self.0 + } +} + +impl AsRef for wslplugins_sys::WSLVmCreationSettings { + fn as_ref(&self) -> &WSLVmCreationSettings { + unsafe { + &*(self as *const wslplugins_sys::WSLVmCreationSettings as *const WSLVmCreationSettings) + } + } +} + +impl WSLVmCreationSettings { /// Retrieves the custom configuration flags for the VM. /// /// # Returns @@ -45,7 +55,7 @@ impl WSLVmCreationSettings<'_> { } } -impl Debug for WSLVmCreationSettings<'_> { +impl Debug for WSLVmCreationSettings { /// Formats the VM creation settings for debugging. /// /// The debug output includes the custom configuration flags. @@ -58,3 +68,15 @@ impl Debug for WSLVmCreationSettings<'_> { .finish() } } + +#[cfg(test)] +mod tests { + use crate::utils::test_transparence; + + use super::WSLVmCreationSettings; + + #[test] + fn test_layouts() { + test_transparence::(); + } +}