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
64
65
66
67
68
69
70
71
72
73
use crate::TimeTracker;
use directories::UserDirs;
use std::fs;
use std::fs::OpenOptions;
use std::io::Write;
use std::path::PathBuf;

#[allow(dead_code)]
fn not_supported() {
    println!("Schedule configuration is not supported on your operating system");
}

fn get_plist_file_contents() -> String {
    format!(
        r#"<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>rust.cargo.timetrack</string>
        <key>ProgramArguments</key>
        <array>
            <string>{}/.cargo/bin/timetrack</string>
            <string>track</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
    </dict>
</plist>
"#,
        UserDirs::new().unwrap().home_dir().to_string_lossy()
    ).to_string()
}

fn get_plist_file_path() -> PathBuf {
    UserDirs::new()
        .unwrap()
        .home_dir()
        .join("Library/LaunchAgents/rust.cargo.timetrack.plist")
}

impl<'a> TimeTracker<'a> {
    #[cfg(target_os = "macos")]
    pub fn schedule(&self) {
        let mut f = OpenOptions::new()
            .write(true)
            .truncate(true)
            .create(true)
            .open(get_plist_file_path())
            .expect("Unable to open or create plist file");

        write!(&mut f, "{}", get_plist_file_contents()).expect("Failed to schedule TimeTrack");
        println!("TimeTrack scheduled. Logout/login to start tracking.");
    }

    #[cfg(not(target_os = "macos"))]
    pub fn schedule(&self) {
        not_supported();
    }

    #[cfg(target_os = "macos")]
    pub fn unschedule(&self) {
        match fs::remove_file(get_plist_file_path()) {
            Ok(_) => println!("TimeTrack schedule removed."),
            Err(_) => println!("Failed to remove TimeTrack schedule."),
        }
    }

    #[cfg(not(target_os = "macos"))]
    pub fn unschedule(&self) {
        not_supported();
    }
}