aboutsummaryrefslogtreecommitdiff
path: root/src/sources/spotify.rs
blob: cd37491d4d171a19dd31c6360683e17dc281691b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use std::io::Result;

use objc2::{
    msg_send,
    rc::{Retained, autoreleasepool},
    runtime::AnyObject,
};
use objc2_foundation::NSString;
use objc2_scripting_bridge::SBApplication;

use crate::Track;

use super::LyricsSource;

pub struct Spotify;

impl Spotify {
    pub fn new() -> Self {
        Spotify
    }
}

impl LyricsSource for Spotify {
    fn name(&self) -> String {
        "spotify".to_string()
    }

    fn current_track(&self) -> Option<Track> {
        unsafe {
            let bundle_identifier = NSString::from_str("com.spotify.Client");
            let app = SBApplication::applicationWithBundleIdentifier(&bundle_identifier);
            if let Some(app) = app
                && app.isRunning()
            {
                let current_track: Option<Retained<AnyObject>> = msg_send![&app, currentTrack];
                if let Some(current_track) = current_track {
                    let name_raw: Option<Retained<NSString>> = msg_send![&current_track, name];
                    let artist_raw: Option<Retained<NSString>> = msg_send![&current_track, artist];

                    if let (Some(name_raw), Some(artist_raw)) = (name_raw, artist_raw) {
                        let name = autoreleasepool(|pool| name_raw.to_str(pool).to_string());
                        let artist = autoreleasepool(|pool| artist_raw.to_str(pool).to_string());

                        return Some(Track { name, artist });
                    }
                }
            }
        }
        None
    }

    fn disable(&self) -> Result<()> {
        Ok(())
    }

    fn enable(&self) -> Result<()> {
        Ok(())
    }

    fn reset(&self) -> Result<()> {
        Ok(())
    }
}