wslplugins_rs/
wsl_offline_distribution_information.rs1use crate::{
7 api::{errors::require_update_error::Result, utils::check_capability_result_from_context},
8 core_wsl_distribution_information::CoreWSLDistributionInformation,
9 utils::opt_wide_str,
10 UserDistributionID, WSLContext, WSLVersionCapability,
11};
12use std::{
13 ffi::OsString,
14 fmt::{self, Debug, Display},
15 hash::{Hash, Hasher},
16 os::windows::ffi::OsStringExt as _,
17 ptr,
18};
19use windows_core::PCWSTR;
20
21#[repr(transparent)]
26pub struct WSLOfflineDistributionInformation(wslpluginapi_sys::WslOfflineDistributionInformation);
27
28impl From<WSLOfflineDistributionInformation>
29 for wslpluginapi_sys::WslOfflineDistributionInformation
30{
31 #[inline]
32 fn from(value: WSLOfflineDistributionInformation) -> Self {
33 value.0
34 }
35}
36
37impl From<wslpluginapi_sys::WslOfflineDistributionInformation>
38 for WSLOfflineDistributionInformation
39{
40 #[inline]
41 fn from(value: wslpluginapi_sys::WslOfflineDistributionInformation) -> Self {
42 Self(value)
43 }
44}
45
46impl AsRef<wslpluginapi_sys::WslOfflineDistributionInformation>
47 for WSLOfflineDistributionInformation
48{
49 #[inline]
50 fn as_ref(&self) -> &wslpluginapi_sys::WslOfflineDistributionInformation {
51 &self.0
52 }
53}
54
55impl AsRef<WSLOfflineDistributionInformation>
56 for wslpluginapi_sys::WslOfflineDistributionInformation
57{
58 #[inline]
59 fn as_ref(&self) -> &WSLOfflineDistributionInformation {
60 unsafe { &*ptr::from_ref::<Self>(self).cast::<WSLOfflineDistributionInformation>() }
62 }
63}
64
65impl CoreWSLDistributionInformation for WSLOfflineDistributionInformation {
66 #[inline]
67 fn id(&self) -> UserDistributionID {
68 self.0.Id.into()
69 }
70
71 #[inline]
73 fn name(&self) -> OsString {
74 unsafe { OsString::from_wide(PCWSTR::from_raw(self.0.Name).as_wide()) }
76 }
77
78 #[inline]
84 fn package_family_name(&self) -> Option<OsString> {
85 opt_wide_str(self.0.PackageFamilyName)
86 }
87
88 #[inline]
92 fn flavor(&self) -> Result<Option<OsString>> {
93 check_capability_result_from_context(
94 WSLContext::get_current(),
95 WSLVersionCapability::DistributionFlavor,
96 )?;
97 Ok(opt_wide_str(self.0.Flavor))
98 }
99
100 #[inline]
104 fn version(&self) -> Result<Option<OsString>> {
105 check_capability_result_from_context(
106 WSLContext::get_current(),
107 WSLVersionCapability::DistributionVersion,
108 )?;
109 Ok(opt_wide_str(self.0.Version))
110 }
111}
112
113impl<T> PartialEq<T> for WSLOfflineDistributionInformation
114where
115 T: CoreWSLDistributionInformation,
116{
117 #[inline]
119 fn eq(&self, other: &T) -> bool {
120 self.id() == other.id()
121 }
122}
123
124impl Hash for WSLOfflineDistributionInformation {
125 #[inline]
127 fn hash<H: Hasher>(&self, state: &mut H) {
128 self.id().hash(state);
129 }
130}
131
132impl Display for WSLOfflineDistributionInformation {
133 #[inline]
134 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135 unsafe {
137 write!(
138 f,
139 "{} {{{}}}",
140 PCWSTR::from_raw(self.0.Name).display(),
141 self.id()
142 )
143 }
144 }
145}
146
147impl Debug for WSLOfflineDistributionInformation {
148 #[inline]
149 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
150 let mut dbg = f.debug_struct(stringify!(WSLOfflineDistributionInformation));
151 dbg.field("name", &self.name())
152 .field("id", &self.id())
153 .field("package_family_name", &self.package_family_name());
154 let mut exhaustive = true;
155 if let Ok(flavor) = self.flavor() {
156 dbg.field("flavor", &flavor);
157 } else {
158 exhaustive = false;
159 }
160 if let Ok(version) = self.version() {
161 dbg.field("version", &version);
162 } else {
163 exhaustive = false;
164 }
165 if exhaustive {
166 dbg.finish()
167 } else {
168 dbg.finish_non_exhaustive()
169 }
170 }
171}
172
173#[cfg(test)]
174mod tests {
175 use super::*;
176 use crate::utils::test_transparence;
177
178 #[test]
179 fn test_layouts() {
180 test_transparence::<
181 wslpluginapi_sys::WslOfflineDistributionInformation,
182 WSLOfflineDistributionInformation,
183 >();
184 }
185}