Skip to content
Merged
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
22 changes: 11 additions & 11 deletions wslplugins-macro-core/src/generator/c_funcs_tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ pub(super) fn get_c_func_tokens(hook: Hooks) -> Result<Option<TokenStream>> {
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 {
Expand All @@ -33,7 +33,7 @@ pub(super) fn get_c_func_tokens(hook: Hooks) -> Result<Option<TokenStream>> {
) -> ::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
}
Expand All @@ -48,8 +48,8 @@ pub(super) fn get_c_func_tokens(hook: Hooks) -> Result<Option<TokenStream>> {
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 {
Expand All @@ -66,8 +66,8 @@ pub(super) fn get_c_func_tokens(hook: Hooks) -> Result<Option<TokenStream>> {
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
Expand All @@ -83,8 +83,8 @@ pub(super) fn get_c_func_tokens(hook: Hooks) -> Result<Option<TokenStream>> {
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
Expand All @@ -100,8 +100,8 @@ pub(super) fn get_c_func_tokens(hook: Hooks) -> Result<Option<TokenStream>> {
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
Expand Down
43 changes: 36 additions & 7 deletions wslplugins-rs/src/api/api_v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<ApiV1> for WSLPluginAPIV1 {
fn from(value: ApiV1) -> Self {
value.0
}
}

impl ApiV1<'_> {
impl From<WSLPluginAPIV1> for ApiV1 {
fn from(value: WSLPluginAPIV1) -> Self {
ApiV1(value)
}
}

impl AsRef<WSLPluginAPIV1> for ApiV1 {
fn as_ref(&self) -> &WSLPluginAPIV1 {
&self.0
}
}

impl AsRef<ApiV1> 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.
Expand Down Expand Up @@ -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::<WSLPluginAPIV1, ApiV1>();
}
}
60 changes: 43 additions & 17 deletions wslplugins-rs/src/distribution_information.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<DistributionInformation> for wslplugins_sys::WSLDistributionInformation {
fn as_ref(&self) -> &DistributionInformation {
unsafe {
&*(self as *const wslplugins_sys::WSLDistributionInformation
as *const DistributionInformation)
}
}
}

impl From<DistributionInformation> for wslplugins_sys::WSLDistributionInformation {
fn from(value: DistributionInformation) -> Self {
value.0
}
}

impl AsRef<wslplugins_sys::WSLDistributionInformation> for DistributionInformation {
fn as_ref(&self) -> &wslplugins_sys::WSLDistributionInformation {
&self.0
}
}

impl From<wslplugins_sys::WSLDistributionInformation> 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
Expand Down Expand Up @@ -74,7 +89,7 @@ impl DistributionInformation<'_> {
}
}

impl CoreDistributionInformation for DistributionInformation<'_> {
impl CoreDistributionInformation for DistributionInformation {
/// Retrieves the unique ID of the distribution.
///
/// # Returns
Expand Down Expand Up @@ -108,7 +123,7 @@ impl CoreDistributionInformation for DistributionInformation<'_> {
}
}

impl<T> PartialEq<T> for DistributionInformation<'_>
impl<T> PartialEq<T> for DistributionInformation
where
T: CoreDistributionInformation,
{
Expand All @@ -118,14 +133,14 @@ where
}
}

impl Hash for DistributionInformation<'_> {
impl Hash for DistributionInformation {
/// Computes a hash based on the distribution's ID.
fn hash<H: std::hash::Hasher>(&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.
Expand All @@ -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:
Expand All @@ -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::<wslplugins_sys::WSLDistributionInformation, DistributionInformation>();
}
}
66 changes: 45 additions & 21 deletions wslplugins-rs/src/offline_distribution_information.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<OfflineDistributionInformation> for wslplugins_sys::WslOfflineDistributionInformation {
fn from(value: OfflineDistributionInformation) -> Self {
value.0
}
}

impl From<wslplugins_sys::WslOfflineDistributionInformation> for OfflineDistributionInformation {
fn from(value: wslplugins_sys::WslOfflineDistributionInformation) -> Self {
OfflineDistributionInformation(value)
}
}

impl AsRef<wslplugins_sys::WslOfflineDistributionInformation> for OfflineDistributionInformation {
fn as_ref(&self) -> &wslplugins_sys::WslOfflineDistributionInformation {
&self.0
}
}

impl CoreDistributionInformation for OfflineDistributionInformation<'_> {
impl AsRef<OfflineDistributionInformation> 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
Expand Down Expand Up @@ -65,7 +75,7 @@ impl CoreDistributionInformation for OfflineDistributionInformation<'_> {
}
}

impl<T> PartialEq<T> for OfflineDistributionInformation<'_>
impl<T> PartialEq<T> for OfflineDistributionInformation
where
T: CoreDistributionInformation,
{
Expand All @@ -75,14 +85,14 @@ where
}
}

impl Hash for OfflineDistributionInformation<'_> {
impl Hash for OfflineDistributionInformation {
/// Computes a hash based on the distribution's ID.
fn hash<H: std::hash::Hasher>(&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.
Expand All @@ -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.
Expand All @@ -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,
>();
}
}
4 changes: 2 additions & 2 deletions wslplugins-rs/src/plugin/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use windows::{
};
use wslplugins_sys::WSLPluginAPIV1;

use crate::{api::ApiV1, WSLContext};
use crate::WSLContext;

#[cfg(doc)]
use super::Error;
Expand Down Expand Up @@ -50,7 +50,7 @@ pub fn create_plugin_with_required_version<T: WSLPluginV1>(
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 {
Expand Down
6 changes: 6 additions & 0 deletions wslplugins-rs/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T, U>() {
assert_eq!(align_of::<T>(), align_of::<U>());
assert_eq!(size_of::<T>(), size_of::<U>());
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
4 changes: 2 additions & 2 deletions wslplugins-rs/src/wsl_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ static CURRENT_CONTEXT: OnceLock<WSLContext> = 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 {
Expand Down Expand Up @@ -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()
}
Expand Down
Loading