Skip to content

Commit 0b416fc

Browse files
committed
A lot of improvements + real usage on the plugin
1 parent 2f87cfc commit 0b416fc

File tree

6 files changed

+175
-131
lines changed

6 files changed

+175
-131
lines changed

plugin/src/lib.rs

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use log_instrument::instrument;
66
use plugin::{Result, WSLPluginV1};
77
use std::{env, io::Read};
88
use windows::{
9-
core::{Error as WinError, Result as WinResult, GUID},
9+
core::{Error as WinError, Result as WinResult},
1010
Win32::Foundation::E_FAIL,
1111
};
1212
use wslplugins_rs::wsl_user_configuration::bitflags::WSLUserConfigurationFlags;
@@ -58,12 +58,12 @@ impl WSLPluginV1 for Plugin {
5858
) -> Result<()> {
5959
let flags: WSLUserConfigurationFlags = user_settings.custom_configuration_flags().into();
6060
info!("User configuration {:?}", flags);
61-
62-
let ver_args = ["/bin/cat", "/proc/version"];
6361
match self
6462
.context
6563
.api
66-
.execute_binary(session, ver_args[0], &ver_args)
64+
.new_command(session, "/bin/cat")
65+
.arg("/proc/version")
66+
.execute()
6767
{
6868
Ok(mut stream) => {
6969
let mut buf = String::new();
@@ -81,7 +81,7 @@ impl WSLPluginV1 for Plugin {
8181
)
8282
}
8383
};
84-
self.log_os_release(session, None);
84+
self.log_os_release(session, DistributionID::System);
8585
Ok(())
8686
}
8787

@@ -101,7 +101,7 @@ impl WSLPluginV1 for Plugin {
101101
// Use unknow if init_pid not available
102102
distribution.init_pid().map(|res| res.to_string()).unwrap_or("Unknow".to_string())
103103
);
104-
self.log_os_release(session, Some(distribution.id()));
104+
self.log_os_release(session, DistributionID::User(distribution.id()));
105105
Ok(())
106106
}
107107

@@ -132,21 +132,15 @@ impl WSLPluginV1 for Plugin {
132132
}
133133

134134
impl Plugin {
135-
fn log_os_release(&self, session: &WSLSessionInformation, distro_id: Option<GUID>) {
136-
let args: [&str; 2] = ["/bin/cat", "/etc/os-release"];
137-
let tcp_stream: std::result::Result<std::net::TcpStream, api::Error> = match distro_id {
138-
Some(dist_id) => self
139-
.context
140-
.api
141-
.execute_binary_in_distribution(session, dist_id, args[0], &args),
142-
None => self
143-
.context
144-
.api
145-
.execute_binary(session, args[0], &args)
146-
.map_err(Into::into),
147-
};
148-
let result = tcp_stream;
149-
match result {
135+
fn log_os_release(&self, session: &WSLSessionInformation, distro_id: DistributionID) {
136+
match self
137+
.context
138+
.api
139+
.new_command(session, "/bin/cat")
140+
.arg("/etc/os-release")
141+
.distribution_id(distro_id)
142+
.execute()
143+
{
150144
Ok(stream) => match OsRelease::from_reader(stream) {
151145
Ok(release) => {
152146
if let Some(version) = release.version() {

wslplugins-rs/src/api/api_v1.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
extern crate wslplugins_sys;
22
#[cfg(doc)]
33
use super::Error;
4-
use super::Result;
4+
use super::{Result, WSLCommand};
55
use crate::api::errors::require_update_error::Result as UpReqResult;
66
use crate::utils::{cstring_from_str, encode_wide_null_terminated};
77
use crate::wsl_session_information::WSLSessionInformation;
@@ -264,6 +264,30 @@ impl ApiV1 {
264264
};
265265
Ok(stream)
266266
}
267+
/// Creates a new `WSLCommand` instance tied to the current WSL API.
268+
///
269+
/// This method initializes a `WSLCommand` with the provided session and
270+
/// program details. The program is specified as a path that can be converted
271+
/// to a `Utf8UnixPath`.
272+
///
273+
/// # Parameters
274+
/// - `session`: The session information associated with the WSL instance.
275+
/// - `program`: A reference to the path of the program to be executed,
276+
/// represented as an object implementing `AsRef<Utf8UnixPath>`.
277+
///
278+
/// # Returns
279+
/// A new instance of `WSLCommand` configured to execute the specified program
280+
/// within the provided WSL session.
281+
///
282+
/// # Type Parameters
283+
/// - `T`: A type that implements `AsRef<Utf8UnixPath>`.
284+
pub fn new_command<'a, T: AsRef<Utf8UnixPath> + ?Sized>(
285+
&'a self,
286+
session: &'a WSLSessionInformation<'a>,
287+
program: &'a T,
288+
) -> WSLCommand<'a> {
289+
WSLCommand::new(self, session, program)
290+
}
267291

268292
fn check_required_version(&self, version: &WSLVersion) -> UpReqResult<()> {
269293
check_required_version_result(self.version(), version)

wslplugins-rs/src/api/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,5 @@ pub use errors::Result;
2626
///
2727
/// These utilities simplify common tasks, such as version checking or string manipulation.
2828
pub mod utils;
29-
pub mod wsl_command;
29+
mod wsl_command;
3030
pub use wsl_command::WSLCommand;

wslplugins-rs/src/api/wsl_command.rs

Lines changed: 32 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,8 @@
1-
//! # WSL Distribution and WSLCommand Management Module
2-
//!
3-
//! This module provides abstractions for identifying and manipulating WSL
4-
//! distributions and for running commands in those distributions. It builds on the WSL APIs and
5-
//! uses [GUID]s to uniquely identify distributions.
1+
use typed_path::Utf8UnixPath;
62

7-
use std::{convert::TryFrom, fmt::Display, net::TcpStream};
8-
use thiserror::Error;
9-
use windows::core::GUID;
10-
11-
#[cfg(doc)]
12-
use super::super::api::Error as ApiError;
13-
use super::super::api::Result as ApiResult;
14-
use crate::{CoreDistributionInformation, WSLContext, WSLSessionInformation};
15-
16-
/// Represents a distribution identifier in WSL.
17-
///
18-
/// This can either be the system-level distribution or a user-specific distribution
19-
/// identified by a GUID.
20-
#[derive(Debug, Clone, Copy)]
21-
pub enum DistributionID {
22-
/// Represents the system-level distribution.
23-
System,
24-
/// Represents a user-specific distribution identified by a GUID.
25-
User(GUID),
26-
}
27-
28-
/// Error type for conversion failures between `DistributionID` and GUID.
29-
#[derive(Debug, Error)]
30-
#[error("Cannot convert System distribution to GUID.")]
31-
pub struct ConversionError;
32-
33-
impl TryFrom<DistributionID> for GUID {
34-
type Error = ConversionError;
35-
36-
/// Attempts to convert a `DistributionID` into a GUID.
37-
///
38-
/// # Errors
39-
/// Returns `ConversionError` if the `DistributionID` is `System`.
40-
fn try_from(value: DistributionID) -> Result<Self, Self::Error> {
41-
match value {
42-
DistributionID::User(id) => Ok(id),
43-
DistributionID::System => Err(ConversionError),
44-
}
45-
}
46-
}
47-
48-
impl From<GUID> for DistributionID {
49-
/// Converts a GUID into a `DistributionID`.
50-
fn from(value: GUID) -> Self {
51-
Self::User(value)
52-
}
53-
}
54-
55-
impl<T: CoreDistributionInformation> From<T> for DistributionID {
56-
/// Converts a type implementing `CoreDistributionInformation` into a `DistributionID`.
57-
fn from(value: T) -> Self {
58-
(*value.id()).into()
59-
}
60-
}
61-
62-
impl From<Option<GUID>> for DistributionID {
63-
/// Converts an `Option<GUID>` into a `DistributionID`, defaulting to `System` if `None`.
64-
fn from(value: Option<GUID>) -> Self {
65-
match value {
66-
Some(id) => Self::User(id),
67-
None => Self::System,
68-
}
69-
}
70-
}
71-
72-
impl From<DistributionID> for Option<GUID> {
73-
/// Converts a `DistributionID` into an `Option<GUID>`.
74-
fn from(value: DistributionID) -> Self {
75-
match value {
76-
DistributionID::System => None,
77-
DistributionID::User(id) => Some(id),
78-
}
79-
}
80-
}
81-
82-
impl Display for DistributionID {
83-
/// Formats the `DistributionID` for display.
84-
///
85-
/// Displays "System" for the system-level distribution, or the GUID for a user-specific distribution.
86-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87-
match self {
88-
DistributionID::System => f.write_str("System"),
89-
DistributionID::User(id) => std::fmt::Debug::fmt(id, f),
90-
}
91-
}
92-
}
3+
use super::super::api::{ApiV1, Result as ApiResult};
4+
use crate::{DistributionID, WSLSessionInformation};
5+
use std::net::TcpStream;
936

947
/// Represents a command to be executed in WSL.
958
///
@@ -98,11 +11,11 @@ impl Display for DistributionID {
9811
#[derive(Clone)]
9912
pub struct WSLCommand<'a> {
10013
/// The WSL context associated with the command.
101-
context: &'static WSLContext,
14+
api: &'a ApiV1<'a>,
10215
/// Arguments for the command.
10316
args: Vec<&'a str>,
10417
/// Path to the program being executed.
105-
path: &'a str,
18+
path: &'a Utf8UnixPath,
10619
/// The distribution ID under which the command is executed.
10720
distribution_id: DistributionID,
10821
/// Session information for the current WSL session.
@@ -112,26 +25,38 @@ pub struct WSLCommand<'a> {
11225
impl<'a> WSLCommand<'a> {
11326
/// Creates a new `WSLCommand` instance.
11427
///
28+
/// This function initializes a `WSLCommand` with the necessary details to
29+
/// execute a program in a WSL instance.
30+
///
11531
/// # Parameters
116-
/// - `context`: The WSL context.
117-
/// - `session`: The session information for the WSL instance.
118-
/// - `program`: The path to the program to be executed.
119-
pub fn new(
120-
context: &'static WSLContext,
32+
/// - `api`: A reference to the WSL API version 1.
33+
/// - `session`: The session information associated with the WSL instance.
34+
/// - `program`: A reference to the path of the program to be executed,
35+
/// represented as an object implementing `AsRef<Utf8UnixPath>`.
36+
///
37+
/// # Returns
38+
/// A new `WSLCommand` instance.
39+
///
40+
/// # Type Parameters
41+
/// - `T`: A type that implements `AsRef<Utf8UnixPath>`.
42+
pub(crate) fn new<T: AsRef<Utf8UnixPath> + ?Sized>(
43+
api: &'a ApiV1<'a>,
12144
session: &'a WSLSessionInformation<'a>,
122-
program: &'a str,
45+
program: &'a T,
12346
) -> Self {
47+
let my_program = program.as_ref();
48+
let program_str = my_program.as_str();
12449
Self {
125-
context,
126-
args: vec![program],
127-
path: program,
50+
api,
51+
args: vec![program_str],
52+
path: &my_program,
12853
distribution_id: DistributionID::System,
12954
session,
13055
}
13156
}
13257

13358
/// Returns the path of the command.
134-
pub fn get_path(&self) -> &'a str {
59+
pub fn get_path(&self) -> &'a Utf8UnixPath {
13560
self.path
13661
}
13762

@@ -156,7 +81,7 @@ impl<'a> WSLCommand<'a> {
15681

15782
/// Resets the first argument to the path of the command.
15883
pub fn reset_arg0(&mut self) -> &mut Self {
159-
self.args[0] = self.path;
84+
self.args[0] = self.path.as_str();
16085
self
16186
}
16287

@@ -233,13 +158,12 @@ impl<'a> WSLCommand<'a> {
233158
pub fn execute(&mut self) -> ApiResult<TcpStream> {
234159
let stream = match self.distribution_id {
235160
DistributionID::System => {
236-
self.context
237-
.api
161+
self.api
238162
.execute_binary(self.session, self.path, self.args.as_slice())?
239163
}
240-
DistributionID::User(id) => self.context.api.execute_binary_in_distribution(
164+
DistributionID::User(id) => self.api.execute_binary_in_distribution(
241165
self.session,
242-
&id,
166+
id,
243167
self.path,
244168
self.args.as_slice(),
245169
)?,

0 commit comments

Comments
 (0)