]> git.r.bdr.sh - rbdr/lyricli/blob - src/sources/apple_music.rs
Run format
[rbdr/lyricli] / src / sources / apple_music.rs
1 use std::ffi::CStr;
2 use std::io::Result;
3
4 use cocoa::{
5 base::{id, nil},
6 foundation::NSString,
7 };
8 use objc::{
9 class, msg_send,
10 runtime::{Class, Object},
11 sel, sel_impl,
12 };
13 use objc_id::Id;
14
15 use crate::Track;
16
17 use super::LyricsSource;
18
19 pub struct AppleMusic;
20
21 impl AppleMusic {
22 pub fn new() -> Self {
23 AppleMusic
24 }
25 }
26
27 impl LyricsSource for AppleMusic {
28 fn name(&self) -> String {
29 "apple_music".to_string()
30 }
31
32 fn current_track(&self) -> Option<Track> {
33 unsafe {
34 let app: Id<Object> = {
35 let cls = class!(SBApplication);
36 let bundle_identifier = NSString::alloc(nil).init_str("com.apple.Music");
37
38 let workspace_class = Class::get("NSWorkspace").unwrap();
39 let shared_workspace: id = msg_send![workspace_class, sharedWorkspace];
40 let app_url: id = msg_send![shared_workspace, URLForApplicationWithBundleIdentifier:bundle_identifier];
41
42 if app_url != nil {
43 let app: *mut Object =
44 msg_send![cls, applicationWithBundleIdentifier:bundle_identifier];
45 Id::from_ptr(app)
46 } else {
47 return None;
48 }
49 };
50
51 if msg_send![app, isRunning] {
52 let current_track: *mut Object = msg_send![app, currentTrack];
53 if !current_track.is_null() {
54 let name_raw: *mut Object = msg_send![current_track, name];
55 let artist_raw: *mut Object = msg_send![current_track, artist];
56
57 let name_ptr: *const i8 = msg_send![name_raw, UTF8String];
58 let artist_ptr: *const i8 = msg_send![artist_raw, UTF8String];
59
60 let name = CStr::from_ptr(name_ptr).to_string_lossy().into_owned();
61 let artist = CStr::from_ptr(artist_ptr).to_string_lossy().into_owned();
62
63 return Some(Track { name, artist });
64 }
65 }
66 }
67 None
68 }
69
70 fn disable(&self) -> Result<()> {
71 Ok(())
72 }
73
74 fn enable(&self) -> Result<()> {
75 Ok(())
76 }
77
78 fn reset(&self) -> Result<()> {
79 Ok(())
80 }
81 }