1#![allow(non_snake_case)]
6#![allow(non_camel_case_types)]
7
8use std::sync::Arc;
9
10pub mod iter;
11pub mod types;
12use types::*;
13
14use crate::sys::*;
16
17use windows::core::BSTR;
18use windows::core::HRESULT;
19use windows::core::Interface;
20use windows::Win32::Media::Multimedia::NS_E_PROPERTY_NOT_FOUND;
21
22use windows::Win32::System::Com::{CoInitializeEx, CoCreateInstance, CLSCTX_ALL, COINIT_MULTITHREADED};
23use windows::Win32::System::Com::{VARIANT_0, VARIANT_0_0, VARIANT_0_0_0};
24
25type DATE = f64; type LONG = i32;
27
28use widestring::ucstring::U16CString;
29use num_traits::FromPrimitive;
30
31
32
33mod private {
34 use super::*;
38
39 pub trait ComObjectWrapper {
40 type WrappedType: Interface;
41
42 fn from_com_object(com_object: Self::WrappedType, iTunes: Arc<iTunes>) -> Self;
43 fn com_object(&self) -> &Self::WrappedType;
44 fn iTunes(&self) -> Arc<iTunes>;
45 }
46}
47use private::ComObjectWrapper;
48
49pub trait ITunesRelatedObject: private::ComObjectWrapper {
50 fn iTunes_instance(&self) -> Arc<iTunes> {
52 self.iTunes()
53 }
54}
55
56macro_rules! com_wrapper_struct {
57 ($(#[$attr:meta])* $struct_name:ident) => {
58 ::paste::paste! {
59 com_wrapper_struct!($(#[$attr])* $struct_name as [<IIT $struct_name>]);
60 }
61 };
62 ($(#[$attr:meta])* $struct_name:ident as $com_type:ident) => {
63 $(#[$attr])*
64 pub struct $struct_name {
65 com_object: crate::sys::$com_type,
66 iTunes: Arc<iTunes>,
68 }
69
70 impl private::ComObjectWrapper for $struct_name {
71 type WrappedType = $com_type;
72
73 fn from_com_object(com_object: crate::sys::$com_type, iTunes: Arc<iTunes>) -> Self {
74 Self {
75 com_object, iTunes
76 }
77 }
78
79 fn com_object(&self) -> &crate::sys::$com_type {
80 &self.com_object
81 }
82
83 fn iTunes(&self) -> Arc<iTunes> {
84 Arc::clone(&self.iTunes)
85 }
86 }
87
88 impl ITunesRelatedObject for $struct_name {}
89 }
90}
91
92macro_rules! str_to_bstr {
93 ($string_name:ident, $bstr_name:ident) => {
94 let wide = U16CString::from_str_truncate($string_name);
95 let $bstr_name = BSTR::from_wide(wide.as_slice())?;
96 }
97}
98
99macro_rules! no_args {
100 ($(#[$attr:meta])* $vis:vis $func_name:ident) => {
101 no_args!($(#[$attr])* $vis $func_name as <Self as ComObjectWrapper>::WrappedType);
102 };
103 ($(#[$attr:meta])* $vis:vis $func_name:ident as $inherited_type:ty) => {
104 $(#[$attr])*
105 $vis fn $func_name(&self) -> windows::core::Result<()> {
106 let inherited_obj = self.com_object().cast::<$inherited_type>()?;
107 let result: HRESULT = unsafe{ inherited_obj.$func_name() };
108 result.ok()
109 }
110 };
111}
112
113macro_rules! get_bstr {
114 ($(#[$attr:meta])* $vis:vis $func_name:ident) => {
115 get_bstr!($(#[$attr])* $vis $func_name as <Self as ComObjectWrapper>::WrappedType);
116 };
117 ($(#[$attr:meta])* $vis:vis $func_name:ident as $inherited_type:ty) => {
118 $(#[$attr])*
119 $vis fn $func_name(&self) -> windows::core::Result<String> {
120 let mut bstr = BSTR::default();
121 let inherited_obj = self.com_object().cast::<$inherited_type>()?;
122 let result = unsafe{ inherited_obj.$func_name(&mut bstr) };
123 result.ok()?;
124
125 let v: Vec<u16> = bstr.as_wide().to_vec();
126 Ok(U16CString::from_vec_truncate(v).to_string_lossy())
127 }
128 }
129}
130
131macro_rules! internal_set_bstr {
132 ($(#[$attr:meta])* $vis:vis $func_name:ident ( $key:ident ) as $inherited_type:ty) => {
133 $(#[$attr])*
134 $vis fn $func_name(&self, $key: &str) -> windows::core::Result<()> {
135 str_to_bstr!($key, bstr);
136 let inherited_obj = self.com_object().cast::<$inherited_type>()?;
137 let result = unsafe{ inherited_obj.$func_name(bstr) };
138 result.ok()
139 }
140 };
141}
142
143macro_rules! set_bstr {
144 ($(#[$attr:meta])* $vis:vis $key:ident) => {
145 set_bstr!($(#[$attr])* $vis $key as <Self as ComObjectWrapper>::WrappedType);
146 };
147 ($(#[$attr:meta])* $vis:vis $key:ident as $inherited_type:ty) => {
148 ::paste::paste! {
149 internal_set_bstr!($(#[$attr])* $vis [<set_ $key>] ( $key ) as $inherited_type);
150 }
151 };
152 ($(#[$attr:meta])* $vis:vis $key:ident, no_set_prefix) => {
153 internal_set_bstr!($(#[$attr])* $vis $key ($key) as <Self as ComObjectWrapper>::WrappedType);
154 };
155}
156
157macro_rules! get_long {
158 ($(#[$attr:meta])* $vis:vis $func_name:ident) => {
159 get_long!($(#[$attr])* $vis $func_name as <Self as ComObjectWrapper>::WrappedType);
160 };
161 ($(#[$attr:meta])* $vis:vis $func_name:ident as $inherited_type:ty) => {
162 $(#[$attr])*
163 $vis fn $func_name(&self) -> windows::core::Result<LONG> {
164 let mut value: LONG = 0;
165 let inherited_obj = self.com_object().cast::<$inherited_type>()?;
166 let result = unsafe{ inherited_obj.$func_name(&mut value as *mut LONG) };
167 result.ok()?;
168
169 Ok(value)
170 }
171 };
172}
173
174macro_rules! get_rating {
175 ($(#[$attr:meta])* $vis:vis $func_name:ident) => {
176 get_rating!($(#[$attr])* $vis $func_name as <Self as ComObjectWrapper>::WrappedType);
177 };
178 ($(#[$attr:meta])* $vis:vis $func_name:ident as $inherited_type:ty) => {
179 $(#[$attr])*
180 $vis fn $func_name(&self) -> windows::core::Result<Rating> {
181 let mut value: LONG = 0;
182 let inherited_obj = self.com_object().cast::<$inherited_type>()?;
183 let result = unsafe{ inherited_obj.$func_name(&mut value as *mut LONG) };
184 result.ok()?;
185
186 Ok(value.into())
187 }
188 };
189}
190
191
192macro_rules! internal_set_long {
193 ($(#[$attr:meta])* $vis:vis $func_name:ident ( $key:ident ) as $inherited_type:ty) => {
194 $(#[$attr])*
195 $vis fn $func_name(&self, $key: LONG) -> windows::core::Result<()> {
196 let inherited_obj = self.com_object().cast::<$inherited_type>()?;
197 let result = unsafe{ inherited_obj.$func_name($key) };
198 result.ok()
199 }
200 };
201}
202
203macro_rules! set_long {
204 ($(#[$attr:meta])* $vis:vis $key:ident) => {
205 ::paste::paste! {
206 set_long!($(#[$attr])* $vis $key as <Self as ComObjectWrapper>::WrappedType);
207 }
208 };
209 ($(#[$attr:meta])* $vis:vis $key:ident as $inherited_type:ty) => {
210 ::paste::paste! {
211 internal_set_long!($(#[$attr])* $vis [<set_ $key>] ($key) as $inherited_type);
212 }
213 };
214 ($(#[$attr:meta])* $vis:vis $key:ident, no_set_prefix) => {
215 ::paste::paste! {
216 internal_set_long!($(#[$attr])* $vis $key ($key) as <Self as ComObjectWrapper>::WrappedType);
217 }
218 };
219}
220
221macro_rules! set_rating {
222 ($(#[$attr:meta])* $vis:vis $key:ident) => {
223 ::paste::paste! {
224 set_rating!($(#[$attr])* $vis $key as <Self as ComObjectWrapper>::WrappedType);
225 }
226 };
227 ($(#[$attr:meta])* $vis:vis $key:ident as $inherited_type:ty) => {
228 ::paste::paste! {
229 $(#[$attr])*
230 $vis fn [<set_ $key>](&self, $key: Rating) -> windows::core::Result<()> {
231 let long_rating = $key.into();
232 let inherited_obj = self.com_object().cast::<$inherited_type>()?;
233 let result = unsafe{ inherited_obj.[<set_ $key>](long_rating) };
234 result.ok()
235 }
236 }
237 };
238}
239
240macro_rules! set_playlist {
241 ($(#[$attr:meta])* $vis:vis $func_name:ident ( $arg:ident )) => {
242 ::paste::paste! {
243 $(#[$attr])*
244 $vis fn [<set_ $func_name>](&self, $arg: &Playlist) -> windows::core::Result<()> {
245 let vplaylist = $arg.as_variant();
246 let result = unsafe{ self.com_object.[<set_ $func_name>](vplaylist.as_raw() as *const VARIANT) };
247 result.ok()
248 }
249 }
250 };
251}
252
253macro_rules! get_f64 {
254 ($(#[$attr:meta])* $vis:vis $func_name:ident, $float_name:ty) => {
255 get_f64!($(#[$attr])* $vis $func_name, $float_name as <Self as ComObjectWrapper>::WrappedType);
256 };
257 ($(#[$attr:meta])* $vis:vis $func_name:ident, $float_name:ty as $inherited_type:ty) => {
258 $(#[$attr])*
259 $vis fn $func_name(&self) -> windows::core::Result<$float_name> {
260 let mut value: f64 = 0.0;
261 let inherited_obj = self.com_object().cast::<$inherited_type>()?;
262 let result = unsafe{ inherited_obj.$func_name(&mut value) };
263 result.ok()?;
264
265 Ok(value)
266 }
267 };
268}
269
270macro_rules! set_f64 {
271 ($(#[$attr:meta])* $vis:vis $key:ident, $float_name:ty) => {
272 set_f64!($(#[$attr])* $vis $key, $float_name as <Self as ComObjectWrapper>::WrappedType);
273 };
274 ($(#[$attr:meta])* $vis:vis $key:ident, $float_name:ty as $inherited_type:ty) => {
275 ::paste::paste! {
276 $(#[$attr])*
277 $vis fn [<set _$key>](&self, $key: $float_name) -> windows::core::Result<()> {
278 let inherited_obj = self.com_object().cast::<$inherited_type>()?;
279 let result = unsafe{ inherited_obj.[<set _$key>]($key) };
280 result.ok()
281 }
282 }
283 }
284}
285
286macro_rules! get_double {
287 ($(#[$attr:meta])* $vis:vis $key:ident) => {
288 get_f64!($(#[$attr])* $vis $key, f64);
289 };
290 ($(#[$attr:meta])* $vis:vis $key:ident as $inherited_type:ty) => {
291 get_f64!($(#[$attr])* $vis $key, f64 as $inherited_type);
292 }
293}
294
295macro_rules! set_double {
296 ($(#[$attr:meta])* $vis:vis $key:ident) => {
297 set_f64!($(#[$attr])* $vis $key, f64);
298 }
299}
300
301macro_rules! get_date {
302 ($(#[$attr:meta])* $vis:vis $key:ident) => {
303 get_f64!($(#[$attr])* $vis $key, DATE);
304 };
305 ($(#[$attr:meta])* $vis:vis $key:ident as $inherited_type:ty) => {
306 get_f64!($(#[$attr])* $vis $key, DATE as $inherited_type);
307 };
308}
309
310macro_rules! set_date {
311 ($(#[$attr:meta])* $vis:vis $key:ident) => {
312 set_f64!($(#[$attr])* $vis $key, DATE);
313 };
314 ($(#[$attr:meta])* $vis:vis $key:ident as $inherited_type:ty) => {
315 set_f64!($(#[$attr])* $vis $key, DATE as $inherited_type);
316 };
317}
318
319macro_rules! get_bool {
320 ($(#[$attr:meta])* $vis:vis $func_name:ident) => {
321 get_bool!($(#[$attr])* $vis $func_name as <Self as ComObjectWrapper>::WrappedType);
322 };
323 ($(#[$attr:meta])* $vis:vis $func_name:ident as $inherited_type:ty) => {
324 ::paste::paste! {
325 $(#[$attr])*
326 $vis fn [<is _$func_name>](&self) -> windows::core::Result<bool> {
327 let mut value = crate::sys::FALSE;
328 let inherited_obj = self.com_object().cast::<$inherited_type>()?;
329 let result = unsafe{ inherited_obj.$func_name(&mut value) };
330 result.ok()?;
331
332 Ok(value.as_bool())
333 }
334 }
335 };
336}
337
338
339
340macro_rules! internal_set_bool {
341 ($(#[$attr:meta])* $vis:vis $func_name:ident ( $key:ident ) as $inherited_type:ty) => {
342 $(#[$attr])*
343 $vis fn $func_name(&self, $key: bool) -> windows::core::Result<()> {
344 let variant_bool = match $key {
345 true => crate::sys::TRUE,
346 false => crate::sys::FALSE,
347 };
348 let inherited_obj = self.com_object().cast::<$inherited_type>()?;
349 let result = unsafe{ inherited_obj.$func_name(variant_bool) };
350 result.ok()
351 }
352 };
353}
354
355macro_rules! set_bool {
356 ($(#[$attr:meta])* $vis:vis $key:ident) => {
357 set_bool!($(#[$attr])* $vis $key as <Self as ComObjectWrapper>::WrappedType);
358 };
359 ($(#[$attr:meta])* $vis:vis $key:ident as $inherited_type:ty) => {
360 ::paste::paste! {
361 internal_set_bool!($(#[$attr])* $vis [<set_ $key>] ( $key ) as $inherited_type);
362 }
363 };
364 ($(#[$attr:meta])* $vis:vis $key:ident, no_set_prefix) => {
365 internal_set_bool!($(#[$attr])* $vis $key ($key) as <Self as ComObjectWrapper>::WrappedType);
366 }
367}
368
369
370macro_rules! get_enum {
371 ($(#[$attr:meta])* $vis:vis $fn_name:ident -> $enum_type:ty) => {
372 get_enum!($(#[$attr])* $vis $fn_name -> $enum_type as <Self as ComObjectWrapper>::WrappedType);
373 };
374 ($(#[$attr:meta])* $vis:vis $fn_name:ident -> $enum_type:ty as $inherited_type:ty) => {
375 $(#[$attr])*
376 $vis fn $fn_name(&self) -> windows::core::Result<$enum_type> {
377 let mut value: $enum_type = FromPrimitive::from_i32(0).unwrap();
378 let inherited_obj = self.com_object().cast::<$inherited_type>()?;
379 let result = unsafe{ inherited_obj.$fn_name(&mut value as *mut _) };
380 result.ok()?;
381 Ok(value)
382 }
383 };
384}
385
386macro_rules! set_enum {
387 ($(#[$attr:meta])* $vis:vis $fn_name:ident, $enum_type:ty) => {
388 set_enum!($(#[$attr])* $vis $fn_name, $enum_type as <Self as ComObjectWrapper>::WrappedType);
389 };
390 ($(#[$attr:meta])* $vis:vis $fn_name:ident, $enum_type:ty as $inherited_type:ty) => {
391 ::paste::paste! {
392 $(#[$attr])*
393 $vis fn [<set _$fn_name>](&self, value: $enum_type) -> windows::core::Result<()> {
394 let inherited_obj = self.com_object().cast::<$inherited_type>()?;
395 let result = unsafe{ inherited_obj.[<set _$fn_name>](value) };
396 result.ok()
397 }
398 }
399 };
400}
401
402macro_rules! create_wrapped_object {
403 ($obj_type:ty, $out_obj:ident, $iTunes:ident) => {
404 match $out_obj {
405 None => Err(windows::core::Error::new(
406 NS_E_PROPERTY_NOT_FOUND, windows::h!("Item not found").clone(),
408 )),
409 Some(com_object) => Ok(
410 <$obj_type>::from_com_object(com_object, $iTunes)
411 )
412 }
413 };
414}
415
416macro_rules! get_object {
417 ($(#[$attr:meta])* $vis:vis $fn_name:ident -> $obj_type:ty) => {
418 get_object!($(#[$attr])* $vis $fn_name -> $obj_type as <Self as ComObjectWrapper>::WrappedType);
419 };
420 ($(#[$attr:meta])* $vis:vis $fn_name:ident -> $obj_type:ty as $inherited_type:ty) => {
421 $(#[$attr])*
422 $vis fn $fn_name(&self) -> windows::core::Result<$obj_type> {
423 let mut out_obj = None;
424 let inherited_obj = self.com_object().cast::<$inherited_type>()?;
425 let result = unsafe{ inherited_obj.$fn_name(&mut out_obj as *mut _) };
426 result.ok()?;
427
428 let iTunes_arc = self.iTunes();
429 create_wrapped_object!($obj_type, out_obj, iTunes_arc)
430 }
431 };
432}
433
434macro_rules! get_object_from_str {
435 ($(#[$attr:meta])* $vis:vis $fn_name:ident ( $arg_name:ident ) -> $obj_type:ty) => {
436 get_object_from_str!($(#[$attr])* $vis $fn_name($arg_name) -> $obj_type as <Self as ComObjectWrapper>::WrappedType);
437 };
438 ($(#[$attr:meta])* $vis:vis $fn_name:ident ( $arg_name:ident ) -> $obj_type:ty as $inherited_type:ty) => {
439 $(#[$attr])*
440 $vis fn $fn_name(&self, $arg_name: &str) -> windows::core::Result<$obj_type> {
441 str_to_bstr!($arg_name, bstr);
442 let inherited_obj = self.com_object().cast::<$inherited_type>()?;
443
444 let mut out_obj = None;
445 let result = unsafe{ inherited_obj.$fn_name(bstr, &mut out_obj as *mut _) };
446 result.ok()?;
447
448 let iTunes_arc = self.iTunes();
449 create_wrapped_object!($obj_type, out_obj, iTunes_arc)
450 }
451 };
452}
453
454macro_rules! get_object_from_variant {
455 ($(#[$attr:meta])* $vis:vis $fn_name:ident ( $arg_name:ident ) -> $obj_type:ty) => {
456 get_object_from_variant!($(#[$attr])* $vis $fn_name($arg_name) -> $obj_type as <Self as ComObjectWrapper>::WrappedType);
457 };
458 ($(#[$attr:meta])* $vis:vis $fn_name:ident ( $arg_name:ident ) -> $obj_type:ty as $inherited_type:ty) => {
459 $(#[$attr])*
460 $vis fn $fn_name<T>(&self, $arg_name:&Variant<T>) -> windows::core::Result<$obj_type> {
461 let inherited_obj = self.com_object().cast::<$inherited_type>()?;
462
463 let mut out_obj = None;
464 let result = unsafe{ inherited_obj.$fn_name($arg_name.as_raw() as *const VARIANT, &mut out_obj as *mut _) };
465 result.ok()?;
466
467 let iTunes_arc = self.iTunes();
468 create_wrapped_object!($obj_type, out_obj, iTunes_arc)
469 }
470 };
471}
472
473macro_rules! get_object_from_long {
474 ($(#[$attr:meta])* $vis:vis $fn_name:ident ( $arg_name:ident ) -> $obj_type:ty) => {
475 get_object_from_long!($(#[$attr])* $vis $fn_name($arg_name) -> $obj_type as <Self as ComObjectWrapper>::WrappedType);
476 };
477 ($(#[$attr:meta])* $vis:vis $fn_name:ident ( $arg_name:ident ) -> $obj_type:ty as $inherited_type:ty) => {
478 $(#[$attr])*
479 $vis fn $fn_name(&self, $arg_name:LONG) -> windows::core::Result<$obj_type> {
480 let inherited_obj = self.com_object().cast::<$inherited_type>()?;
481
482 let mut out_obj = None;
483 let result = unsafe{ inherited_obj.$fn_name($arg_name, &mut out_obj as *mut _) };
484 result.ok()?;
485
486 let iTunes_arc = self.iTunes();
487 create_wrapped_object!($obj_type, out_obj, iTunes_arc)
488 }
489 };
490}
491
492macro_rules! set_object {
493 ($(#[$attr:meta])* $vis:vis $fn_name:ident, $obj_type:ty) => {
494 ::paste::paste! {
495 $(#[$attr])*
496 $vis fn [<set _$fn_name>](&self, data: $obj_type) -> windows::core::Result<()> {
497 let object_to_set = data.com_object();
498 let result = unsafe{ self.com_object.[<set _$fn_name>](object_to_set as *const _) };
499 result.ok()
500 }
501 }
502 }
503}
504
505macro_rules! item_by_name {
506 ($(#[$attr:meta])* $vis:vis $obj_type:ty) => {
507 $(#[$attr])*
508 $vis fn ItemByName(&self, name: &str) -> windows::core::Result<$obj_type> {
509 str_to_bstr!(name, bstr);
510
511 let mut out_obj = None;
512 let result = unsafe{ self.com_object.ItemByName(bstr, &mut out_obj as *mut _) };
513 result.ok()?;
514
515 let iTunes_arc = self.iTunes();
516 create_wrapped_object!($obj_type, out_obj, iTunes_arc)
517 }
518 }
519}
520
521macro_rules! item_by_persistent_id {
522 ($(#[$attr:meta])* $vis:vis $obj_type:ty) => {
523 $(#[$attr])*
524 $vis fn ItemByPersistentID(&self, id: PersistentId) -> windows::core::Result<$obj_type> {
525 let b = id.to_le_bytes();
526 let id_low = i32::from_le_bytes(b[..4].try_into().unwrap());
527 let id_high = i32::from_le_bytes(b[4..].try_into().unwrap());
528
529 let mut out_obj = None;
530 let result = unsafe{ self.com_object.ItemByPersistentID(id_high, id_low, &mut out_obj as *mut _) };
531 result.ok()?;
532
533 let iTunes_arc = self.iTunes();
534 create_wrapped_object!($obj_type, out_obj, iTunes_arc)
535 }
536 }
537}
538
539
540pub trait Iterable {
541 type Item;
542
543 fn Count(&self) -> windows::core::Result<LONG>;
545 fn item(&self, index: LONG) -> windows::core::Result<<Self as Iterable>::Item>;
547}
548
549macro_rules! iterator {
550 ($obj_type:ty, $item_type:ident) => {
551 impl $obj_type {
552 pub fn iter(&self) -> windows::core::Result<iter::Iterator<$obj_type, $item_type>> {
553 iter::Iterator::new(&self)
554 }
555 }
556
557 impl Iterable for $obj_type {
558 type Item = $item_type;
559
560 get_long!(Count);
561
562 fn item(&self, index: LONG) -> windows::core::Result<<Self as Iterable>::Item> {
564 let mut out_obj = None;
565 let result = unsafe{ self.com_object.Item(index, &mut out_obj as *mut _) };
566 result.ok()?;
567
568 let iTunes_arc = self.iTunes();
569 create_wrapped_object!($item_type, out_obj, iTunes_arc)
570 }
571
572 }
580 }
581}
582
583
584
585#[derive(Debug, Eq, PartialEq)]
587pub struct ObjectIDs {
588 pub sourceID: LONG,
589 pub playlistID: LONG,
590 pub trackID: LONG,
591 pub databaseID: LONG,
592}
593
594pub trait IITObjectWrapper: private::ComObjectWrapper {
596 fn GetITObjectIDs(&self) -> windows::core::Result<ObjectIDs> {
601 let mut sourceID: LONG = 0;
602 let mut playlistID: LONG = 0;
603 let mut trackID: LONG = 0;
604 let mut databaseID: LONG = 0;
605 let iitobject = self.com_object().cast::<IITObject>().unwrap();
606 let result = unsafe{ iitobject.GetITObjectIDs(
607 &mut sourceID as *mut LONG,
608 &mut playlistID as *mut LONG,
609 &mut trackID as *mut LONG,
610 &mut databaseID as *mut LONG,
611 ) };
612 result.ok()?;
613
614 Ok(ObjectIDs{
615 sourceID,
616 playlistID,
617 trackID,
618 databaseID,
619 })
620 }
621
622 fn as_variant(&self) -> Variant<Self::WrappedType> {
626 let idispatch = self.com_object().cast::<windows::Win32::System::Com::IDispatch>().unwrap(); Variant::new(VARIANT{
630 Anonymous: VARIANT_0 {
631 Anonymous: std::mem::ManuallyDrop::new(VARIANT_0_0 {
632 vt: windows::Win32::System::Com::VT_DISPATCH,
633 Anonymous: VARIANT_0_0_0 {
634 pdispVal: std::mem::ManuallyDrop::new(Some(idispatch)),
635 },
636 ..Default::default()
637 })
638 }
639 })
640 }
641
642 fn persistent_id(&self) -> windows::core::Result<PersistentId> {
644 self.iTunes().GetITObjectPersistentID(&self.as_variant())
645 }
646
647 get_bstr!(
648 Name as IITObject);
650
651 set_bstr!(
652 Name as IITObject);
654
655 get_long!(
656 Index as IITObject);
658
659 get_long!(
660 sourceID as IITObject);
662
663 get_long!(
664 playlistID as IITObject);
666
667 get_long!(
668 trackID as IITObject);
670
671 get_long!(
672 TrackDatabaseID as IITObject);
674}
675
676pub enum PossibleIITObject {
678 Source(Source),
679 Playlist(Playlist),
680 Track(Track),
681}
682
683impl PossibleIITObject {
684 fn from_com_object(com_object: IITObject, iTunes: Arc<iTunes>) -> windows::core::Result<PossibleIITObject> {
685 if let Ok(source) = com_object.cast::<IITSource>() {
686 Ok(PossibleIITObject::Source(Source::from_com_object(source, iTunes)))
687 } else if let Ok(playlist) = com_object.cast::<IITPlaylist>() {
688 Ok(PossibleIITObject::Playlist(Playlist::from_com_object(playlist, iTunes)))
689 } else if let Ok(track) = com_object.cast::<IITTrack>() {
690 Ok(PossibleIITObject::Track(Track::from_com_object(track, iTunes)))
691 } else {
692 Err(windows::core::Error::new(
693 NS_E_PROPERTY_NOT_FOUND, windows::h!("Item not found").clone(),
695 ))
696 }
697 }
698
699 pub fn as_source(&self) -> Option<&Source> {
700 match self {
701 PossibleIITObject::Source(s) => Some(s),
702 _ => None
703 }
704 }
705
706 pub fn as_playlist(&self) -> Option<&Playlist> {
707 match self {
708 PossibleIITObject::Playlist(p) => Some(p),
709 _ => None
710 }
711 }
712
713 pub fn as_track(&self) -> Option<&Track> {
714 match self {
715 PossibleIITObject::Track(t) => Some(t),
716 _ => None
717 }
718 }
719}
720
721
722com_wrapper_struct!(
723 Source);
725
726impl IITObjectWrapper for Source {}
727
728impl Source {
729 get_enum!(
730 pub Kind -> ITSourceKind);
732
733 get_double!(
734 pub Capacity);
736
737 get_double!(
738 pub FreeSpace);
740
741 get_object!(
742 pub Playlists -> PlaylistCollection);
744}
745
746com_wrapper_struct!(
747 PlaylistCollection);
749
750impl PlaylistCollection {
751 item_by_name!(
752 pub Playlist);
754
755 item_by_persistent_id!(
756 pub Playlist);
758}
759
760iterator!(PlaylistCollection, Playlist);
761
762
763pub trait IITPlaylistWrapper: private::ComObjectWrapper {
765 fn as_user_playlist(&self) -> Option<UserPlaylist> {
767 let com_user_pl = self.com_object().cast::<IITUserPlaylist>().ok()?;
768 let iTunes = self.iTunes();
769 Some(UserPlaylist::from_com_object(com_user_pl, iTunes))
770 }
771
772 no_args!(
773 Delete as IITPlaylist);
775
776 no_args!(
777 PlayFirstTrack as IITPlaylist);
779
780 fn Print(&self, showPrintDialog: bool, printKind: ITPlaylistPrintKind, theme: String) -> windows::core::Result<()> {
782 let show = if showPrintDialog { TRUE } else { FALSE };
783 str_to_bstr!(theme, theme);
784
785 let inherited_obj = self.com_object().cast::<IITPlaylist>()?;
786 let result = unsafe{ inherited_obj.Print(show, printKind, theme) };
787 result.ok()
788 }
789
790 fn Search(&self, searchText: String, searchFields: ITPlaylistSearchField) -> windows::core::Result<TrackCollection> {
792 str_to_bstr!(searchText, searchText);
793
794 let mut out_obj = None;
795 let inherited_obj = self.com_object().cast::<IITPlaylist>()?;
796 let result = unsafe{ inherited_obj.Search(searchText, searchFields, &mut out_obj as *mut _) };
797 result.ok()?;
798
799 let iTunes_arc = self.iTunes();
800 create_wrapped_object!(TrackCollection, out_obj, iTunes_arc)
801 }
802
803 get_enum!(
804 Kind -> ITPlaylistKind as IITPlaylist);
806
807 get_object!(
808 Source -> Source as IITPlaylist);
810
811 get_long!(
812 Duration as IITPlaylist);
814
815 get_bool!(
816 Shuffle as IITPlaylist);
818
819 set_bool!(
820 Shuffle as IITPlaylist);
822
823 get_double!(
824 Size as IITPlaylist);
826
827 get_enum!(
828 SongRepeat -> ITPlaylistRepeatMode as IITPlaylist);
830
831 set_enum!(
832 SongRepeat, ITPlaylistRepeatMode as IITPlaylist);
834
835 get_bstr!(
836 Time as IITPlaylist);
838
839 get_bool!(
840 Visible as IITPlaylist);
842
843 get_object!(
844 Tracks -> TrackCollection as IITPlaylist);
846}
847
848com_wrapper_struct!(
849 Playlist);
851
852impl IITObjectWrapper for Playlist {}
853
854impl IITPlaylistWrapper for Playlist {}
855
856
857com_wrapper_struct!(
858 TrackCollection);
860
861impl TrackCollection {
862 get_object_from_long!(
863 pub ItemByPlayOrder(Index) -> Track);
865
866 item_by_name!(
867 pub Track);
869
870 item_by_persistent_id!(
871 pub Track);
873}
874
875iterator!(TrackCollection, Track);
876
877pub trait IITTrackWrapper: private::ComObjectWrapper {
879 no_args!(
880 Delete as IITTrack);
882
883 no_args!(
884 Play as IITTrack);
886
887 get_object_from_str!(
888 AddArtworkFromFile(filePath) -> Artwork as IITTrack);
890
891 get_enum!(
892 Kind -> ITTrackKind as IITTrack);
894
895 get_object!(
896 Playlist -> Playlist as IITTrack);
898
899 get_bstr!(
900 Album as IITTrack);
902
903 set_bstr!(
904 Album as IITTrack);
906
907 get_bstr!(
908 Artist as IITTrack);
910
911 set_bstr!(
912 Artist as IITTrack);
914
915 get_long!(
916 BitRate as IITTrack);
918
919 get_long!(
920 BPM as IITTrack);
922
923 set_long!(
924 BPM as IITTrack);
926
927 get_bstr!(
928 Comment as IITTrack);
930
931 set_bstr!(
932 Comment as IITTrack);
934
935 get_bool!(
936 Compilation as IITTrack);
938
939 set_bool!(
940 Compilation as IITTrack);
942
943 get_bstr!(
944 Composer as IITTrack);
946
947 set_bstr!(
948 Composer as IITTrack);
950
951 get_date!(
952 DateAdded as IITTrack);
954
955 get_long!(
956 DiscCount as IITTrack);
958
959 set_long!(
960 DiscCount as IITTrack);
962
963 get_long!(
964 DiscNumber as IITTrack);
966
967 set_long!(
968 DiscNumber as IITTrack);
970
971 get_long!(
972 Duration as IITTrack);
974
975 get_bool!(
976 Enabled as IITTrack);
978
979 set_bool!(
980 Enabled as IITTrack);
982
983 get_bstr!(
984 EQ as IITTrack);
986
987 set_bstr!(
988 EQ as IITTrack);
990
991 set_long!(
992 Finish as IITTrack);
994
995 get_long!(
996 Finish as IITTrack);
998
999 get_bstr!(
1000 Genre as IITTrack);
1002
1003 set_bstr!(
1004 Genre as IITTrack);
1006
1007 get_bstr!(
1008 Grouping as IITTrack);
1010
1011 set_bstr!(
1012 Grouping as IITTrack);
1014
1015 get_bstr!(
1016 KindAsString as IITTrack);
1018
1019 get_date!(
1020 ModificationDate as IITTrack);
1022
1023 get_long!(
1024 PlayedCount as IITTrack);
1026
1027 set_long!(
1028 PlayedCount as IITTrack);
1030
1031 get_date!(
1032 PlayedDate as IITTrack);
1034
1035 set_date!(
1036 PlayedDate as IITTrack);
1038
1039 get_long!(
1040 PlayOrderIndex as IITTrack);
1042
1043 get_rating!(
1044 Rating as IITTrack);
1046
1047 set_rating!(
1048 Rating as IITTrack);
1050
1051 get_long!(
1052 SampleRate as IITTrack);
1054
1055 get_long!(
1056 Size as IITTrack);
1058
1059 get_long!(
1060 Start as IITTrack);
1062
1063 set_long!(
1064 Start as IITTrack);
1066
1067 get_bstr!(
1068 Time as IITTrack);
1070
1071 get_long!(
1072 TrackCount as IITTrack);
1074
1075 set_long!(
1076 TrackCount as IITTrack);
1078
1079 get_long!(
1080 TrackNumber as IITTrack);
1082
1083 set_long!(
1084 TrackNumber as IITTrack);
1086
1087 get_long!(
1088 VolumeAdjustment as IITTrack);
1090
1091 set_long!(
1092 VolumeAdjustment as IITTrack);
1094
1095 get_long!(
1096 Year as IITTrack);
1098
1099 set_long!(
1100 Year as IITTrack);
1102
1103 get_object!(
1104 Artwork -> ArtworkCollection as IITTrack);
1106}
1107
1108com_wrapper_struct!(
1109 Track);
1111
1112impl IITObjectWrapper for Track {}
1113
1114impl IITTrackWrapper for Track {}
1115
1116impl Track {
1117 pub fn as_file_or_cd_track(&self) -> Option<FileOrCDTrack> {
1119 let foct = self.com_object.cast::<IITFileOrCDTrack>().ok()?;
1120 let iTunes_arc = self.iTunes();
1121 Some(FileOrCDTrack::from_com_object(foct, iTunes_arc))
1122 }
1123}
1124
1125com_wrapper_struct!(
1126 Artwork);
1128
1129impl Artwork {
1130 no_args!(
1131 pub Delete);
1133
1134 set_bstr!(
1135 pub SetArtworkFromFile, no_set_prefix);
1137
1138 set_bstr!(
1139 pub SaveArtworkToFile, no_set_prefix);
1141
1142 get_enum!(
1143 pub Format -> ITArtworkFormat);
1145
1146 get_bool!(
1147 pub IsDownloadedArtwork);
1149
1150 get_bstr!(
1151 pub Description);
1153
1154 set_bstr!(
1155 pub Description);
1157}
1158
1159com_wrapper_struct!(
1160 ArtworkCollection);
1162
1163impl ArtworkCollection {}
1164
1165iterator!(ArtworkCollection, Artwork);
1166
1167com_wrapper_struct!(
1168 SourceCollection);
1170
1171impl SourceCollection {
1172 item_by_name!(
1173 pub Source);
1175
1176 item_by_persistent_id!(
1177 pub Source);
1179}
1180
1181iterator!(SourceCollection, Source);
1182
1183com_wrapper_struct!(
1184 Encoder);
1186
1187impl Encoder {
1188 get_bstr!(
1189 pub Name);
1191
1192 get_bstr!(
1193 pub Format);
1195}
1196
1197com_wrapper_struct!(
1198 EncoderCollection);
1200
1201impl EncoderCollection {
1202 item_by_name!(
1203 pub Encoder);
1205}
1206
1207iterator!(EncoderCollection, Encoder);
1208
1209com_wrapper_struct!(
1210 EQPreset);
1212
1213impl EQPreset {
1214 get_bstr!(
1215 pub Name);
1217
1218 get_bool!(
1219 pub Modifiable);
1221
1222 get_double!(
1223 pub Preamp);
1225
1226 set_double!(
1227 pub Preamp);
1229
1230 get_double!(
1231 pub Band1);
1233
1234 set_double!(
1235 pub Band1);
1237
1238 get_double!(
1239 pub Band2);
1241
1242 set_double!(
1243 pub Band2);
1245
1246 get_double!(
1247 pub Band3);
1249
1250 set_double!(
1251 pub Band3);
1253
1254 get_double!(
1255 pub Band4);
1257
1258 set_double!(
1259 pub Band4);
1261
1262 get_double!(
1263 pub Band5);
1265
1266 set_double!(
1267 pub Band5);
1269
1270 get_double!(
1271 pub Band6);
1273
1274 set_double!(
1275 pub Band6);
1277
1278 get_double!(
1279 pub Band7);
1281
1282 set_double!(
1283 pub Band7);
1285
1286 get_double!(
1287 pub Band8);
1289
1290 set_double!(
1291 pub Band8);
1293
1294 get_double!(
1295 pub Band9);
1297
1298 set_double!(
1299 pub Band9);
1301
1302 get_double!(
1303 pub Band10);
1305
1306 set_double!(
1307 pub Band10);
1309
1310 internal_set_bool!(
1311 pub Delete(updateAllTracks) as <Self as ComObjectWrapper>::WrappedType);
1313
1314 pub fn Rename(&self, newName: String, updateAllTracks: bool) -> windows::core::Result<()> {
1316 str_to_bstr!(newName, bstr);
1317 let var_bool = if updateAllTracks { TRUE } else { FALSE };
1318 let result = unsafe { self.com_object.Rename(bstr, var_bool) };
1319 result.ok()
1320 }
1321}
1322
1323com_wrapper_struct!(
1324 EQPresetCollection);
1326
1327impl EQPresetCollection {
1328 item_by_name!(
1329 pub EQPreset);
1331}
1332
1333iterator!(EQPresetCollection, EQPreset);
1334
1335com_wrapper_struct!(
1336 OperationStatus);
1338
1339impl OperationStatus {
1340 get_bool!(
1341 pub InProgress);
1343
1344 get_object!(
1345 pub Tracks -> TrackCollection);
1347}
1348
1349#[derive(Debug)]
1351pub struct ConversionStatus {
1352 pub trackName: String,
1353 pub progressValue: LONG,
1354 pub maxProgressValue: LONG,
1355}
1356
1357com_wrapper_struct!(
1358 ConvertOperationStatus);
1360
1361impl ConvertOperationStatus {
1362 pub fn GetConversionStatus(&self) -> windows::core::Result<ConversionStatus> {
1364 let mut bstr = BSTR::default();
1365 let mut progressValue = 0;
1366 let mut maxProgressValue = 0;
1367 let result = unsafe{ self.com_object.GetConversionStatus(&mut bstr, &mut progressValue as *mut LONG, &mut maxProgressValue as *mut LONG) };
1368 result.ok()?;
1369
1370 let v: Vec<u16> = bstr.as_wide().to_vec();
1371 let trackName = U16CString::from_vec_truncate(v).to_string_lossy();
1372
1373 Ok(ConversionStatus{ trackName, progressValue, maxProgressValue })
1374 }
1375
1376 no_args!(
1377 pub StopConversion);
1379
1380 get_bstr!(
1381 pub trackName);
1383
1384 get_long!(
1385 pub progressValue);
1387
1388 get_long!(
1389 pub maxProgressValue);
1391}
1392
1393com_wrapper_struct!(
1394 LibraryPlaylist);
1396
1397impl IITObjectWrapper for LibraryPlaylist {}
1398
1399impl IITPlaylistWrapper for LibraryPlaylist {}
1400
1401impl LibraryPlaylist {
1402 get_object_from_str!(
1403 pub AddFile(filePath) -> OperationStatus);
1405
1406 get_object_from_variant!(
1407 pub AddFiles(filePaths) -> OperationStatus);
1409
1410 get_object_from_str!(
1411 pub AddURL(URL) -> URLTrack);
1413
1414 get_object_from_variant!(
1415 pub AddTrack(iTrackToAdd) -> Track);
1417}
1418
1419com_wrapper_struct!(
1420 URLTrack);
1422
1423impl IITObjectWrapper for URLTrack {}
1424
1425impl IITTrackWrapper for URLTrack {}
1426
1427impl URLTrack {
1428 get_bstr!(
1429 pub URL);
1431
1432 set_bstr!(
1433 pub URL);
1435
1436 get_bool!(
1437 pub Podcast);
1439
1440 no_args!(
1441 pub UpdatePodcastFeed);
1443
1444 no_args!(
1445 pub DownloadPodcastEpisode);
1447
1448 get_bstr!(
1449 pub Category);
1451
1452 set_bstr!(
1453 pub Category);
1455
1456 get_bstr!(
1457 pub Description);
1459
1460 set_bstr!(
1461 pub Description);
1463
1464 get_bstr!(
1465 pub LongDescription);
1467
1468 set_bstr!(
1469 pub LongDescription);
1471
1472 no_args!(
1473 pub Reveal);
1475
1476 get_rating!(
1477 pub AlbumRating);
1479
1480 set_rating!(
1481 pub AlbumRating);
1483
1484 get_enum!(
1485 pub AlbumRatingKind -> ITRatingKind);
1487
1488 get_enum!(
1489 pub ratingKind -> ITRatingKind);
1491
1492 get_object!(
1493 pub Playlists -> PlaylistCollection);
1495}
1496
1497com_wrapper_struct!(
1498 UserPlaylist);
1500
1501impl IITObjectWrapper for UserPlaylist {}
1502
1503impl IITPlaylistWrapper for UserPlaylist {}
1504
1505impl UserPlaylist {
1506 get_object_from_str!(
1507 pub AddFile(filePath) -> OperationStatus);
1509
1510 get_object_from_variant!(
1511 pub AddFiles(filePaths) -> OperationStatus);
1513
1514 get_object_from_str!(
1515 pub AddURL(URL) -> URLTrack);
1517
1518 get_object_from_variant!(
1519 pub AddTrack(iTrackToAdd) -> Track);
1521
1522 get_bool!(
1523 pub Shared);
1525
1526 set_bool!(
1527 pub Shared);
1529
1530 get_bool!(
1531 pub Smart);
1533
1534 get_enum!(
1535 pub SpecialKind -> ITUserPlaylistSpecialKind);
1537
1538 get_object!(
1539 pub Parent -> UserPlaylist);
1541
1542 get_object_from_str!(
1543 pub CreatePlaylist(playlistName) -> Playlist);
1545
1546 get_object_from_str!(
1547 pub CreateFolder(folderName) -> Playlist);
1549
1550 set_playlist!(
1551 pub Parent(iParentPlayList));
1553
1554 no_args!(
1555 pub Reveal);
1557}
1558
1559com_wrapper_struct!(
1560 Visual);
1562
1563impl Visual {
1564 get_bstr!(
1565 pub Name);
1567}
1568
1569com_wrapper_struct!(
1570 VisualCollection);
1572
1573impl VisualCollection {
1574 item_by_name!(
1575 pub Visual);
1577}
1578
1579iterator!(VisualCollection, Visual);
1580
1581com_wrapper_struct!(
1582 Window);
1584
1585impl Window {
1586 get_bstr!(
1587 pub Name);
1589
1590 get_enum!(
1591 pub Kind -> ITWindowKind);
1593
1594 get_bool!(
1595 pub Visible);
1597
1598 set_bool!(
1599 pub Visible);
1601
1602 get_bool!(
1603 pub Resizable);
1605
1606 get_bool!(
1607 pub Minimized);
1609
1610 set_bool!(
1611 pub Minimized);
1613
1614 get_bool!(
1615 pub Maximizable);
1617
1618 get_bool!(
1619 pub Maximized);
1621
1622 set_bool!(
1623 pub Maximized);
1625
1626 get_bool!(
1627 pub Zoomable);
1629
1630 get_bool!(
1631 pub Zoomed);
1633
1634 set_bool!(
1635 pub Zoomed);
1637
1638 get_long!(
1639 pub Top);
1641
1642 set_long!(
1643 pub Top);
1645
1646 get_long!(
1647 pub Left);
1649
1650 set_long!(
1651 pub Left);
1653
1654 get_long!(
1655 pub Bottom);
1657
1658 set_long!(
1659 pub Bottom);
1661
1662 get_long!(
1663 pub Right);
1665
1666 set_long!(
1667 pub Right);
1669
1670 get_long!(
1671 pub Width);
1673
1674 set_long!(
1675 pub Width);
1677
1678 get_long!(
1679 pub Height);
1681
1682 set_long!(
1683 pub Height);
1685}
1686
1687com_wrapper_struct!(
1688 BrowserWindow);
1690
1691impl BrowserWindow {
1692 get_bool!(
1693 pub MiniPlayer);
1695
1696 set_bool!(
1697 pub MiniPlayer);
1699
1700 get_object!(
1701 pub SelectedTracks -> TrackCollection);
1703
1704 get_object!(
1705 pub SelectedPlaylist -> Playlist);
1707
1708 set_playlist!(
1709 pub SelectedPlaylist(iPlaylist));
1711}
1712
1713com_wrapper_struct!(
1714 WindowCollection);
1716
1717impl WindowCollection {
1718 item_by_name!(
1719 pub Window);
1721}
1722
1723iterator!(WindowCollection, Window);
1724
1725#[derive(Debug, Eq, PartialEq)]
1727pub struct PlayerButtonState {
1728 pub previousEnabled: bool,
1729 pub playPauseStopState: ITPlayButtonState,
1730 pub nextEnabled: bool,
1731}
1732
1733pub struct iTunes {
1735 com_object: crate::sys::IiTunes,
1736}
1737
1738impl private::ComObjectWrapper for iTunes {
1739 type WrappedType = crate::sys::IiTunes;
1740
1741 fn from_com_object(_com_object: crate::sys::IiTunes, _iTunes: Arc<iTunes>) -> Self {
1742 panic!("This function is not supposed to be called");
1744 }
1745
1746 fn com_object(&self) -> &crate::sys::IiTunes {
1747 &self.com_object
1748 }
1749
1750 fn iTunes(&self) -> Arc<iTunes> {
1751 Arc::new(Self{
1752 com_object: self.com_object.clone()
1753 })
1754 }
1755}
1756
1757impl iTunes {
1758 pub fn new() -> windows::core::Result<Self> {
1764 unsafe {
1765 CoInitializeEx(None, COINIT_MULTITHREADED)?;
1770 }
1771
1772 Ok(Self {
1773 com_object: unsafe { CoCreateInstance(&crate::sys::ITUNES_APP_COM_GUID, None, CLSCTX_ALL)? },
1774 })
1775 }
1776
1777 no_args!(
1778 pub BackTrack);
1780
1781 no_args!(
1782 pub FastForward);
1784
1785 no_args!(
1786 pub NextTrack);
1788
1789 no_args!(
1790 pub Pause);
1792
1793 no_args!(
1794 pub Play);
1796
1797 set_bstr!(
1798 pub PlayFile, no_set_prefix);
1800
1801 no_args!(
1802 pub PlayPause);
1804
1805 no_args!(
1806 pub PreviousTrack);
1808
1809 no_args!(
1810 pub Resume);
1812
1813 no_args!(
1814 pub Rewind);
1816
1817 no_args!(
1818 pub Stop);
1820
1821 get_object_from_str!(
1822 pub ConvertFile(filePath) -> OperationStatus);
1824
1825 get_object_from_variant!(
1826 pub ConvertFiles(filePaths) -> OperationStatus);
1828
1829 get_object_from_variant!(
1830 pub ConvertTrack(iTrackToConvert) -> OperationStatus);
1832
1833 get_object_from_variant!(
1834 pub ConvertTracks(iTracksToConvert) -> OperationStatus);
1836
1837 pub fn CheckVersion(&self, majorVersion: LONG, minorVersion: LONG) -> windows::core::Result<bool> {
1839 let mut bool_result = FALSE;
1840 let result = unsafe{ self.com_object.CheckVersion(majorVersion, minorVersion, &mut bool_result) };
1841 result.ok()?;
1842 Ok(bool_result.as_bool())
1843 }
1844
1845 pub fn GetITObjectByID(&self, ids: ObjectIDs) -> windows::core::Result<PossibleIITObject> {
1847 let mut out_obj: Option<IITObject> = None;
1848 let result = unsafe{ self.com_object.GetITObjectByID(
1849 ids.sourceID,
1850 ids.playlistID,
1851 ids.trackID,
1852 ids.databaseID,
1853 &mut out_obj as *mut _
1854 ) };
1855 result.ok()?;
1856
1857 match out_obj {
1858 None => Err(windows::core::Error::new(
1859 NS_E_PROPERTY_NOT_FOUND, windows::h!("Item not found").clone(),
1861 )),
1862 Some(obj) => {
1863 let iTunes_arc = self.iTunes();
1864 PossibleIITObject::from_com_object(obj, iTunes_arc)
1865 },
1866 }
1867 }
1868
1869 get_object_from_str!(
1870 pub CreatePlaylist(playlistName) -> Playlist);
1872
1873 set_bstr!(
1874 pub OpenURL, no_set_prefix);
1876
1877 no_args!(
1878 pub GotoMusicStoreHomePage);
1880
1881 no_args!(
1882 pub UpdateIPod);
1884
1885 no_args!(
1892 pub Quit);
1894
1895 get_object!(
1896 pub Sources -> SourceCollection);
1898
1899 get_object!(
1900 pub Encoders -> EncoderCollection);
1902
1903 get_object!(
1904 pub EQPresets -> EQPresetCollection);
1906
1907 get_object!(
1908 pub Visuals -> VisualCollection);
1910
1911 get_object!(
1912 pub Windows -> WindowCollection);
1914
1915 get_long!(
1916 pub SoundVolume);
1918
1919 set_long!(
1920 pub SoundVolume);
1922
1923 get_bool!(
1924 pub Mute);
1926
1927 set_bool!(
1928 pub Mute);
1930
1931 get_enum!(
1932 pub PlayerState -> ITPlayerState);
1934
1935 get_long!(
1936 pub PlayerPosition);
1938
1939 set_long!(
1940 pub PlayerPosition);
1942
1943 get_object!(
1944 pub CurrentEncoder -> Encoder);
1946
1947 set_object!(
1948 pub CurrentEncoder, Encoder);
1950
1951 get_bool!(
1952 pub VisualsEnabled);
1954
1955 set_bool!(
1956 pub VisualsEnabled);
1958
1959 get_bool!(
1960 pub FullScreenVisuals);
1962
1963 set_bool!(
1964 pub FullScreenVisuals);
1966
1967 get_enum!(
1968 pub VisualSize -> ITVisualSize);
1970
1971 set_enum!(
1972 pub VisualSize, ITVisualSize);
1974
1975 get_object!(
1976 pub CurrentVisual -> Visual);
1978
1979 set_object!(
1980 pub CurrentVisual, Visual);
1982
1983 get_bool!(
1984 pub EQEnabled);
1986
1987 set_bool!(
1988 pub EQEnabled);
1990
1991 get_object!(
1992 pub CurrentEQPreset -> EQPreset);
1994
1995 set_object!(
1996 pub CurrentEQPreset, EQPreset);
1998
1999 get_bstr!(
2000 pub CurrentStreamTitle);
2002
2003 get_bstr!(
2004 pub set_CurrentStreamURL);
2006
2007 get_object!(
2008 pub BrowserWindow -> BrowserWindow);
2010
2011 get_object!(
2012 pub EQWindow -> Window);
2014
2015 get_object!(
2016 pub LibrarySource -> Source);
2018
2019 get_object!(
2020 pub LibraryPlaylist -> LibraryPlaylist);
2022
2023 get_object!(
2024 pub CurrentTrack -> Track);
2026
2027 get_object!(
2028 pub CurrentPlaylist -> Playlist);
2030
2031 get_object!(
2032 pub SelectedTracks -> TrackCollection);
2034
2035 get_bstr!(
2036 pub Version);
2038
2039 set_long!(
2040 pub SetOptions, no_set_prefix);
2043
2044 get_object_from_str!(
2045 pub ConvertFile2(filePath) -> ConvertOperationStatus);
2047
2048 get_object_from_variant!(
2049 pub ConvertFiles2(filePaths) -> ConvertOperationStatus);
2051
2052 get_object_from_variant!(
2053 pub ConvertTrack2(iTrackToConvert) -> ConvertOperationStatus);
2055
2056 get_object_from_variant!(
2057 pub ConvertTracks2(iTracksToConvert) -> ConvertOperationStatus);
2059
2060 get_bool!(
2061 pub AppCommandMessageProcessingEnabled);
2063
2064 set_bool!(
2065 pub AppCommandMessageProcessingEnabled);
2067
2068 get_bool!(
2069 pub ForceToForegroundOnDialog);
2071
2072 set_bool!(
2073 pub ForceToForegroundOnDialog);
2075
2076 get_object_from_str!(
2077 pub CreateEQPreset(eqPresetName) -> EQPreset);
2079
2080 pub fn CreatePlaylistInSource(&self, playlistName: &str, source: &Source) -> windows::core::Result<Playlist> {
2082 str_to_bstr!(playlistName, bstr);
2083 let vsource = source.as_variant();
2084 let mut out_playlist = None;
2085 let result = unsafe{ self.com_object.CreatePlaylistInSource(bstr, vsource.as_raw() as *const VARIANT, &mut out_playlist as *mut _) };
2086 result.ok()?;
2087
2088 let iTunes_arc = self.iTunes();
2089 create_wrapped_object!(Playlist, out_playlist, iTunes_arc)
2090 }
2091
2092 pub fn GetPlayerButtonsState(&self) -> windows::core::Result<PlayerButtonState> {
2094 let mut previousEnabled = FALSE;
2095 let mut playPauseStopState = ITPlayButtonState::ITPlayButtonStatePlayDisabled;
2096 let mut nextEnabled = FALSE;
2097 let result = unsafe{ self.com_object.GetPlayerButtonsState(&mut previousEnabled, &mut playPauseStopState, &mut nextEnabled) };
2098 result.ok()?;
2099 Ok(PlayerButtonState{
2100 previousEnabled: previousEnabled.as_bool(),
2101 playPauseStopState,
2102 nextEnabled: nextEnabled.as_bool(),
2103 })
2104 }
2105
2106 pub fn PlayerButtonClicked(&self, playerButton: ITPlayerButton, playerButtonModifierKeys: LONG) -> windows::core::Result<()> {
2108 let result = unsafe{ self.com_object.PlayerButtonClicked(playerButton, playerButtonModifierKeys) };
2109 result.ok()
2110 }
2111
2112 pub fn CanSetShuffle(&self, iPlaylist: &Playlist) -> windows::core::Result<bool> {
2114 let vplaylist = iPlaylist.as_variant();
2115 let mut out_bool = FALSE;
2116 let result = unsafe{ self.com_object.CanSetShuffle(vplaylist.as_raw() as *const VARIANT, &mut out_bool) };
2117 result.ok()?;
2118 Ok(out_bool.as_bool())
2119 }
2120
2121 pub fn CanSetSongRepeat(&self, iPlaylist: &Playlist) -> windows::core::Result<bool> {
2123 let vplaylist = iPlaylist.as_variant();
2124 let mut out_bool = FALSE;
2125 let result = unsafe{ self.com_object.CanSetSongRepeat(vplaylist.as_raw() as *const VARIANT, &mut out_bool) };
2126 result.ok()?;
2127 Ok(out_bool.as_bool())
2128 }
2129
2130 get_object!(
2131 pub ConvertOperationStatus -> ConvertOperationStatus);
2133
2134 set_bstr!(
2135 pub SubscribeToPodcast, no_set_prefix);
2137
2138 no_args!(
2139 pub UpdatePodcastFeeds);
2141
2142 get_object_from_str!(
2143 pub CreateFolder(folderName) -> Playlist);
2145
2146 pub fn CreateFolderInSource(&self, folderName: &str, iSource: &Source) -> windows::core::Result<Playlist> {
2148 str_to_bstr!(folderName, bstr);
2149 let vsource = iSource.as_variant();
2150 let mut out_playlist = None;
2151 let result = unsafe{ self.com_object.CreateFolderInSource(bstr, vsource.as_raw() as *const VARIANT, &mut out_playlist as *mut _) };
2152 result.ok()?;
2153
2154 let iTunes_arc = self.iTunes();
2155 create_wrapped_object!(Playlist, out_playlist, iTunes_arc)
2156 }
2157
2158 get_bool!(
2159 pub SoundVolumeControlEnabled);
2161
2162 get_bstr!(
2163 pub LibraryXMLPath);
2165
2166 pub fn GetITObjectPersistentID<T>(&self, iObject: &Variant<T>) -> windows::core::Result<PersistentId> {
2170 let mut highID: LONG = 0;
2171 let mut lowID: LONG = 0;
2172 let result = unsafe{ self.com_object.GetITObjectPersistentIDs(iObject.as_raw() as *const VARIANT, &mut highID, &mut lowID) };
2173 result.ok()?;
2174
2175 let bytes = [lowID.to_le_bytes(), highID.to_le_bytes()].concat();
2176 Ok(PersistentId::from_le_bytes(bytes.try_into().unwrap())) }
2178
2179 get_long!(
2180 pub PlayerPositionMS);
2182
2183 set_long!(
2184 pub PlayerPositionMS);
2186}
2187
2188com_wrapper_struct!(
2197 AudioCDPlaylist);
2199
2200impl IITObjectWrapper for AudioCDPlaylist {}
2201
2202impl IITPlaylistWrapper for AudioCDPlaylist {}
2203
2204impl AudioCDPlaylist {
2205 get_bstr!(
2206 pub Artist);
2208
2209 get_bool!(
2210 pub Compilation);
2212
2213 get_bstr!(
2214 pub Composer);
2216
2217 get_long!(
2218 pub DiscCount);
2220
2221 get_long!(
2222 pub DiscNumber);
2224
2225 get_bstr!(
2226 pub Genre);
2228
2229 get_long!(
2230 pub Year);
2232
2233 no_args!(
2234 pub Reveal);
2236}
2237
2238com_wrapper_struct!(
2239 IPodSource);
2241
2242impl IITObjectWrapper for IPodSource {}
2243
2244impl IPodSource {
2245 no_args!(
2246 pub UpdateIPod);
2248
2249 no_args!(
2250 pub EjectIPod);
2252
2253 get_bstr!(
2254 pub SoftwareVersion);
2256}
2257
2258com_wrapper_struct!(
2259 FileOrCDTrack);
2261
2262impl IITObjectWrapper for FileOrCDTrack {}
2263
2264impl IITTrackWrapper for FileOrCDTrack {}
2265
2266impl FileOrCDTrack {
2267 get_bstr!(
2268 pub Location);
2270
2271 no_args!(
2272 pub UpdateInfoFromFile);
2274
2275 get_bool!(
2276 pub Podcast);
2278
2279 no_args!(
2280 pub UpdatePodcastFeed);
2282
2283 get_bool!(
2284 pub RememberBookmark);
2286
2287 set_bool!(
2288 pub RememberBookmark);
2290
2291 get_bool!(
2292 pub ExcludeFromShuffle);
2294
2295 set_bool!(
2296 pub ExcludeFromShuffle);
2298
2299 get_bstr!(
2300 pub Lyrics);
2302
2303 set_bstr!(
2304 pub Lyrics);
2306
2307 get_bstr!(
2308 pub Category);
2310
2311 set_bstr!(
2312 pub Category);
2314
2315 get_bstr!(
2316 pub Description);
2318
2319 set_bstr!(
2320 pub Description);
2322
2323 get_bstr!(
2324 pub LongDescription);
2326
2327 set_bstr!(
2328 pub LongDescription);
2330
2331 get_long!(
2332 pub BookmarkTime);
2334
2335 set_long!(
2336 pub BookmarkTime);
2338
2339 get_enum!(
2340 pub VideoKind -> ITVideoKind);
2342
2343 set_enum!(
2344 pub VideoKind, ITVideoKind);
2346
2347 get_long!(
2348 pub SkippedCount);
2350
2351 set_long!(
2352 pub SkippedCount);
2354
2355 get_date!(
2356 pub SkippedDate);
2358
2359 set_date!(
2360 pub SkippedDate);
2362
2363 get_bool!(
2364 pub PartOfGaplessAlbum);
2366
2367 set_bool!(
2368 pub PartOfGaplessAlbum);
2370
2371 get_bstr!(
2372 pub AlbumArtist);
2374
2375 set_bstr!(
2376 pub AlbumArtist);
2378
2379 get_bstr!(
2380 pub Show);
2382
2383 set_bstr!(
2384 pub Show);
2386
2387 get_long!(
2388 pub SeasonNumber);
2390
2391 set_long!(
2392 pub SeasonNumber);
2394
2395 get_bstr!(
2396 pub EpisodeID);
2398
2399 set_bstr!(
2400 pub EpisodeID);
2402
2403 get_long!(
2404 pub EpisodeNumber);
2406
2407 set_long!(
2408 pub EpisodeNumber);
2410
2411 pub fn Size(&self) -> windows::core::Result<i64> {
2413 let mut highSize = 0;
2414 let mut lowSize = 0;
2415 let result = unsafe{ self.com_object.Size64High(&mut highSize) };
2416 result.ok()?;
2417 let result = unsafe{ self.com_object.Size64Low(&mut lowSize) };
2418 result.ok()?;
2419
2420 let bytes = [lowSize.to_le_bytes(), highSize.to_le_bytes()].concat();
2421 Ok(i64::from_le_bytes(bytes.try_into().unwrap())) }
2423
2424 get_bool!(
2425 pub Unplayed);
2427
2428 set_bool!(
2429 pub Unplayed);
2431
2432 get_bstr!(
2433 pub SortAlbum);
2435
2436 set_bstr!(
2437 pub SortAlbum);
2439
2440 get_bstr!(
2441 pub SortAlbumArtist);
2443
2444 set_bstr!(
2445 pub SortAlbumArtist);
2447
2448 get_bstr!(
2449 pub SortArtist);
2451
2452 set_bstr!(
2453 pub SortArtist);
2455
2456 get_bstr!(
2457 pub SortComposer);
2459
2460 set_bstr!(
2461 pub SortComposer);
2463
2464 get_bstr!(
2465 pub SortName);
2467
2468 set_bstr!(
2469 pub SortName);
2471
2472 get_bstr!(
2473 pub SortShow);
2475
2476 set_bstr!(
2477 pub SortShow);
2479
2480 no_args!(
2481 pub Reveal);
2483
2484 get_rating!(
2485 pub AlbumRating);
2487
2488 set_rating!(
2489 pub AlbumRating);
2491
2492 get_enum!(
2493 pub AlbumRatingKind -> ITRatingKind);
2495
2496 get_enum!(
2497 pub ratingKind -> ITRatingKind);
2499
2500 get_object!(
2501 pub Playlists -> PlaylistCollection);
2503
2504 set_bstr!(
2505 pub Location);
2507
2508 get_date!(
2509 pub ReleaseDate);
2511}
2512
2513com_wrapper_struct!(
2514 PlaylistWindow);
2516
2517impl PlaylistWindow {
2518 get_object!(
2519 pub SelectedTracks -> TrackCollection);
2521
2522 get_object!(
2523 pub Playlist -> Playlist);
2525}