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 ) ]
9912pub 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> {
11225impl < ' 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