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