use super::super::api::{ApiV1, Result as ApiResult};
use crate::{DistributionID, SessionID};
use core::clone::Clone;
use std::{borrow::Cow, iter::once, net::TcpStream};
use typed_path::Utf8UnixPath;
mod into_cow_utf8_unix_path;
pub use into_cow_utf8_unix_path::IntoCowUtf8UnixPath;
pub use prepared_wsl_command::PreparedWSLCommand;
mod wsl_command_execution;
pub use wsl_command_execution::WSLCommandExecution;
#[cfg(feature = "smallvec")]
use smallvec::SmallVec;
#[cfg(doc)]
use super::super::api::Error as ApiError;
mod prepared_wsl_command;
#[cfg(not(feature = "smallvec"))]
type ArgVec<'a> = Vec<Cow<'a, str>>;
#[cfg(feature = "smallvec")]
type ArgVec<'a> = SmallVec<[Cow<'a, str>; 8]>;
#[doc(alias = "ExecuteBinary")]
#[doc(alias = "ExecuteBinaryInDistribution")]
#[derive(Clone, Debug)]
pub struct WSLCommand<'a> {
api: &'a ApiV1,
session_id: SessionID,
distribution_id: DistributionID,
path: Cow<'a, Utf8UnixPath>,
arg0: Option<Cow<'a, str>>,
args: ArgVec<'a>,
}
impl<'a> WSLCommand<'a> {
pub(crate) fn new<P: IntoCowUtf8UnixPath<'a>>(
api: &'a ApiV1,
session_id: SessionID,
program: P,
) -> Self {
Self {
api,
arg0: None,
args: ArgVec::new(),
path: program.into_cow_utf8_unix_path(),
distribution_id: DistributionID::System,
session_id,
}
}
#[inline]
#[must_use]
pub fn get_path(&self) -> &Utf8UnixPath {
self.path.as_ref()
}
#[inline]
#[must_use]
pub fn get_arg0(&self) -> &str {
self.arg0.as_deref().unwrap_or(self.path.as_str())
}
#[inline]
#[must_use]
pub const fn is_standard_arg_0(&self) -> bool {
self.arg0.is_none()
}
#[inline]
pub fn reset_arg0(&mut self) -> &mut Self {
self.arg0 = None;
self
}
#[inline]
pub fn arg0<T: Into<Cow<'a, str>>>(&mut self, arg0: T) -> &mut Self {
self.arg0 = Some(arg0.into());
self
}
#[inline]
#[must_use]
pub fn with_arg0<T: Into<Cow<'a, str>>>(mut self, arg0: T) -> Self {
self.arg0 = Some(arg0.into());
self
}
#[inline]
pub fn arg<T: Into<Cow<'a, str>>>(&mut self, arg: T) -> &mut Self {
self.args.push(arg.into());
self
}
#[inline]
#[must_use]
pub fn with_arg<T: Into<Cow<'a, str>>>(mut self, arg: T) -> Self {
self.args.push(arg.into());
self
}
#[inline]
pub fn args<I>(&mut self, args: I) -> &mut Self
where
I: IntoIterator,
I::Item: Into<Cow<'a, str>>,
{
self.args.extend(args.into_iter().map(Into::into));
self
}
#[inline]
#[must_use]
pub fn with_args<I>(mut self, args: I) -> Self
where
I: IntoIterator,
I::Item: Into<Cow<'a, str>>,
{
self.args.extend(args.into_iter().map(Into::into));
self
}
#[inline]
#[must_use]
pub fn get_args(&self) -> impl ExactSizeIterator<Item = &str> {
self.args.iter().map(AsRef::as_ref)
}
#[inline]
pub fn argv(&self) -> impl Iterator<Item = &str> {
once(self.get_arg0()).chain(self.args.iter().map(AsRef::as_ref))
}
#[inline]
pub fn clear_args(&mut self) -> &mut Self {
self.args.clear();
self
}
#[inline]
pub fn truncate_args(&mut self, i: usize) -> &mut Self {
self.args.truncate(i);
self
}
#[inline]
#[must_use]
#[allow(clippy::missing_const_for_fn, reason = "Useless const")]
pub fn distribution_id(&mut self, distribution_id: DistributionID) -> &mut Self {
self.distribution_id = distribution_id;
self
}
#[inline]
#[must_use]
#[allow(clippy::missing_const_for_fn, reason = "Useless const")]
pub fn with_distribution_id(mut self, distribution_id: DistributionID) -> Self {
self.distribution_id = distribution_id;
self
}
#[inline]
#[allow(clippy::missing_const_for_fn, reason = "Useless const")]
pub fn reset_distribution_id(&mut self) -> &mut Self {
self.distribution_id = DistributionID::System;
self
}
#[inline]
#[must_use]
pub const fn get_distribution_id(&self) -> DistributionID {
self.distribution_id
}
#[inline]
#[must_use]
pub fn prepare(&self) -> PreparedWSLCommand<'a> {
PreparedWSLCommand::from(self)
}
}
impl WSLCommandExecution for WSLCommand<'_> {
#[inline]
fn execute(&self) -> ApiResult<TcpStream> {
self.prepare().execute()
}
}