wslplugins_rs/
wsl_distribution_information.rs1#[cfg(doc)]
17use crate::api::errors::require_update_error::Error;
18use crate::api::{
19 errors::require_update_error::Result, utils::check_capability_result_from_context,
20};
21use crate::core_wsl_distribution_information::CoreWSLDistributionInformation;
22use crate::utils::opt_wide_str;
23use crate::{UserDistributionID, WSLContext, WSLVersionCapability};
24use std::ffi::OsString;
25use std::fmt::{self, Debug, Display};
26use std::hash::{Hash, Hasher};
27use std::os::windows::ffi::OsStringExt as _;
28use std::ptr;
29use windows_core::PCWSTR;
30
31#[repr(transparent)]
36pub struct WSLDistributionInformation(wslpluginapi_sys::WSLDistributionInformation);
37
38impl AsRef<WSLDistributionInformation> for wslpluginapi_sys::WSLDistributionInformation {
39 #[inline]
40 fn as_ref(&self) -> &WSLDistributionInformation {
41 unsafe { &*ptr::from_ref::<Self>(self).cast::<WSLDistributionInformation>() }
43 }
44}
45
46impl From<WSLDistributionInformation> for wslpluginapi_sys::WSLDistributionInformation {
47 #[inline]
48 fn from(value: WSLDistributionInformation) -> Self {
49 value.0
50 }
51}
52
53impl AsRef<wslpluginapi_sys::WSLDistributionInformation> for WSLDistributionInformation {
54 #[inline]
55 fn as_ref(&self) -> &wslpluginapi_sys::WSLDistributionInformation {
56 &self.0
57 }
58}
59
60impl From<wslpluginapi_sys::WSLDistributionInformation> for WSLDistributionInformation {
61 #[inline]
62 fn from(value: wslpluginapi_sys::WSLDistributionInformation) -> Self {
63 Self(value)
64 }
65}
66
67impl WSLDistributionInformation {
68 #[inline]
78 pub fn init_pid(&self) -> Result<u32> {
79 check_capability_result_from_context(
80 WSLContext::get_current(),
81 WSLVersionCapability::DistributionInitPid,
82 )?;
83 Ok(self.0.InitPid)
84 }
85
86 #[inline]
92 #[must_use]
93 pub const fn pid_namespace(&self) -> u64 {
94 self.0.PidNamespace
95 }
96}
97
98impl CoreWSLDistributionInformation for WSLDistributionInformation {
99 #[inline]
100 fn id(&self) -> UserDistributionID {
101 self.0.Id.into()
102 }
103
104 #[inline]
105 fn name(&self) -> OsString {
106 unsafe { OsString::from_wide(PCWSTR::from_raw(self.0.Name).as_wide()) }
108 }
109
110 #[inline]
111 fn package_family_name(&self) -> Option<OsString> {
112 opt_wide_str(self.0.PackageFamilyName)
113 }
114
115 #[inline]
119 fn flavor(&self) -> Result<Option<OsString>> {
120 check_capability_result_from_context(
121 WSLContext::get_current(),
122 WSLVersionCapability::DistributionFlavor,
123 )?;
124 Ok(opt_wide_str(self.0.Flavor))
125 }
126
127 #[inline]
131 fn version(&self) -> Result<Option<OsString>> {
132 check_capability_result_from_context(
133 WSLContext::get_current(),
134 WSLVersionCapability::DistributionVersion,
135 )?;
136 Ok(opt_wide_str(self.0.Version))
137 }
138}
139
140impl<T> PartialEq<T> for WSLDistributionInformation
141where
142 T: CoreWSLDistributionInformation,
143{
144 #[inline]
146 fn eq(&self, other: &T) -> bool {
147 self.id() == other.id()
148 }
149}
150
151impl Hash for WSLDistributionInformation {
152 #[inline]
154 fn hash<H: Hasher>(&self, state: &mut H) {
155 self.id().hash(state);
156 }
157}
158
159impl Display for WSLDistributionInformation {
160 #[inline]
161 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
162 unsafe {
164 write!(
165 f,
166 "{} {{{}}}",
167 PCWSTR::from_raw(self.0.Name).display(),
168 self.id()
169 )
170 }
171 }
172}
173
174impl Debug for WSLDistributionInformation {
175 #[inline]
176 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
177 let mut dbg = f.debug_struct(stringify!(WSLDistributionInformation));
178 dbg.field("name", &self.name())
179 .field("id", &self.id())
180 .field("package_family_name", &self.package_family_name())
181 .field("pid_namespace", &self.pid_namespace());
182 let mut exhaustive = true;
183
184 if let Ok(pid) = self.init_pid() {
185 dbg.field("init_pid", &pid);
186 } else {
187 exhaustive = false;
188 }
189 if let Ok(flavor) = self.flavor() {
190 dbg.field("flavor", &flavor);
191 } else {
192 exhaustive = false;
193 }
194 if let Ok(version) = self.version() {
195 dbg.field("version", &version);
196 } else {
197 exhaustive = false;
198 }
199
200 if exhaustive {
201 dbg.finish()
202 } else {
203 dbg.finish_non_exhaustive()
204 }
205 }
206}
207
208#[cfg(test)]
209mod tests {
210 use super::*;
211 use crate::utils::test_transparence;
212
213 #[test]
214 fn test_layouts() {
215 test_transparence::<wslpluginapi_sys::WSLDistributionInformation, WSLDistributionInformation>(
216 );
217 }
218}