Skip to content

Commit 6453fbd

Browse files
committed
Start working on command
1 parent 4384424 commit 6453fbd

File tree

2 files changed

+160
-0
lines changed

2 files changed

+160
-0
lines changed

wslplugins-rs/src/api/command.rs

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
use std::{convert::TryFrom, fmt::Display, net::TcpStream};
2+
use thiserror::Error;
3+
use windows::core::GUID;
4+
5+
use super::super::api::Result as ApiResult;
6+
use crate::{CoreDistributionInformation, WSLContext, WSLSessionInformation};
7+
8+
#[derive(Debug, Clone, Copy)]
9+
pub enum DistributionID {
10+
System,
11+
User(GUID),
12+
}
13+
14+
#[derive(Debug, Error)]
15+
#[error("Cannot convert System distribution to GUID.")]
16+
pub struct ConversionError;
17+
18+
impl TryFrom<DistributionID> for GUID {
19+
type Error = ConversionError;
20+
21+
fn try_from(value: DistributionID) -> Result<Self, Self::Error> {
22+
match value {
23+
DistributionID::User(id) => Ok(id),
24+
DistributionID::System => Err(ConversionError),
25+
}
26+
}
27+
}
28+
29+
impl From<GUID> for DistributionID {
30+
fn from(value: GUID) -> Self {
31+
Self::User(value)
32+
}
33+
}
34+
35+
impl<T: CoreDistributionInformation> From<T> for DistributionID {
36+
fn from(value: T) -> Self {
37+
(*value.id()).into()
38+
}
39+
}
40+
41+
impl From<Option<GUID>> for DistributionID {
42+
fn from(value: Option<GUID>) -> Self {
43+
match value {
44+
Some(id) => Self::User(id),
45+
None => Self::System,
46+
}
47+
}
48+
}
49+
50+
impl From<DistributionID> for Option<GUID> {
51+
fn from(value: DistributionID) -> Self {
52+
match value {
53+
DistributionID::System => None,
54+
DistributionID::User(id) => Some(id),
55+
}
56+
}
57+
}
58+
59+
impl Display for DistributionID {
60+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61+
match self {
62+
DistributionID::System => f.write_str("System"),
63+
DistributionID::User(id) => std::fmt::Debug::fmt(id, f),
64+
}
65+
}
66+
}
67+
68+
#[derive(Clone)]
69+
pub struct Command<'a> {
70+
context: &'static WSLContext,
71+
args: Vec<&'a str>,
72+
path: &'a str,
73+
distribution_id: DistributionID,
74+
session: &'a WSLSessionInformation<'a>,
75+
}
76+
77+
impl<'a> Command<'a> {
78+
pub fn new(
79+
context: &'static WSLContext,
80+
session: &'a WSLSessionInformation<'a>,
81+
program: &'a str,
82+
) -> Self {
83+
Self {
84+
context,
85+
args: vec![program],
86+
path: program,
87+
distribution_id: DistributionID::System,
88+
session,
89+
}
90+
}
91+
92+
pub fn get_path(&self) -> &'a str {
93+
self.path
94+
}
95+
96+
pub fn arg0(&mut self, arg0: &'a str) -> &mut Self {
97+
self.args[0] = arg0;
98+
self
99+
}
100+
101+
pub fn get_arg0(&self) -> &str {
102+
self.args[0]
103+
}
104+
105+
pub fn is_standard_arg_0(&self) -> bool {
106+
self.path == self.get_arg0()
107+
}
108+
109+
pub fn reset_arg0(&mut self) -> &mut Self {
110+
self.args[0] = self.path;
111+
self
112+
}
113+
114+
pub fn arg(&mut self, arg: &'a str) -> &mut Self {
115+
self.args.push(arg);
116+
self
117+
}
118+
119+
pub fn args<I: IntoIterator<Item = &'a str>>(&mut self, args: I) -> &mut Self {
120+
self.args.extend(args);
121+
self
122+
}
123+
124+
pub fn get_args(&self) -> impl ExactSizeIterator<Item = &str> {
125+
self.args[1..].iter().copied()
126+
}
127+
128+
pub fn distribution_id(&mut self, distribution_id: DistributionID) -> &mut Self {
129+
self.distribution_id = distribution_id;
130+
self
131+
}
132+
133+
pub fn reset_distribution_id(&mut self) -> &mut Self {
134+
self.distribution_id = DistributionID::System;
135+
self
136+
}
137+
138+
pub fn get_distribution_id(&self) -> DistributionID {
139+
self.distribution_id
140+
}
141+
142+
pub fn execute(&mut self) -> ApiResult<TcpStream> {
143+
let stream = match self.distribution_id {
144+
DistributionID::System => {
145+
self.context
146+
.api
147+
.execute_binary(self.session, self.path, self.args.as_slice())?
148+
}
149+
DistributionID::User(id) => self.context.api.execute_binary_in_distribution(
150+
self.session,
151+
&id,
152+
self.path,
153+
self.args.as_slice(),
154+
)?,
155+
};
156+
Ok(stream)
157+
}
158+
}

wslplugins-rs/src/api/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,7 @@ pub use errors::Result;
2424

2525
/// The `utils` module provides utility functions and helpers for working with the WSL Plugin API.
2626
///
27+
mod command;
2728
/// These utilities simplify common tasks, such as version checking or string manipulation.
2829
pub mod utils;
30+
pub use command::Command;

0 commit comments

Comments
 (0)