privacy_sexy/
lib.rs

1/*!
2- privacy-sexy is a data-driven application where it reads the necessary OS-specific logic from
3  yaml files in [`collections`](https://github.com/SubconsciousCompute/privacy-sexy/tree/master/collections)
4- 💡 Best practices
5  - If you repeat yourself, try to utilize [YAML-defined functions](collection::FunctionData)
6  - Always try to add documentation and a way to revert a tweak in [scripts](collection::ScriptData)
7- 📖 Types in code: [`collections.rs`](https://github.com/SubconsciousCompute/privacy-sexy/blob/master/src/collection.rs)
8
9Note: This is a rust port of [privacy.sexy](https://github.com/undergroundwires/privacy.sexy)
10*/
11pub mod collection;
12mod util;
13
14use std::{
15    env, fmt, fs,
16    process::{Command, ExitStatus},
17};
18
19use collection::{CollectionData, CollectionError};
20use serde::{Deserialize, Serialize};
21
22/// Allowed values for OS
23#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
24pub enum OS {
25    /// Apple
26    #[serde(rename = "macos")]
27    MacOs,
28    /// Microsoft
29    #[serde(rename = "windows")]
30    Windows,
31    /// OpenSource 💕
32    #[serde(rename = "linux")]
33    Linux,
34}
35
36impl OS {
37    /**
38    Returns [`OS`] respective to current system
39
40    # Panics
41
42    Panics if current operating system is not supported
43    */
44    pub fn get_system_os() -> Self {
45        match std::env::consts::OS {
46            "macos" => OS::MacOs,
47            "linux" => OS::Linux,
48            "windows" => OS::Windows,
49            _ => panic!("Unsupported OS!"),
50        }
51    }
52}
53
54impl fmt::Display for OS {
55    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
56        match self {
57            OS::MacOs => write!(f, "macos"),
58            OS::Linux => write!(f, "linux"),
59            OS::Windows => write!(f, "windows"),
60        }
61    }
62}
63
64/**
65Main way to get rules in form of [`CollectionData`]
66
67# Errors
68
69Refer to [`CollectionError`]
70*/
71pub fn get_collection(os: OS) -> Result<CollectionData, CollectionError> {
72    CollectionData::from_file(format!("collections/{os}.yaml"))
73}
74
75/**
76Runs the script
77
78# Errors
79
80Returns [`Err`] if it is unable to:
81- write to the temp script file OR
82- change it's permissions (for unix) OR
83- execute the script
84*/
85pub fn run_script(
86    script_string: &str,
87    file_extension: Option<String>,
88) -> Result<ExitStatus, Box<dyn std::error::Error>> {
89    let mut tmp_file = env::temp_dir();
90    tmp_file.push("privacy-sexy");
91    if let Some(ext) = file_extension {
92        tmp_file.set_extension(ext);
93    }
94
95    fs::write(&tmp_file, script_string)?;
96
97    #[cfg(target_family = "unix")]
98    {
99        use std::os::unix::prelude::PermissionsExt;
100        fs::set_permissions(&tmp_file, fs::Permissions::from_mode(0o755))?;
101    }
102
103    Ok(Command::new(tmp_file.to_str().unwrap_or_default()).spawn()?.wait()?)
104}