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
use crate::imp::prelude::*;
use std::{env, fs, io};
use zip::{result::ZipError, ZipArchive};

pub struct Driver {
    path: PathBuf
}

impl Driver {
    const ZIP: &'static [u8] = include_bytes!(concat!(env!("OUT_DIR"), "/driver.zip"));
    const PLATFORM: &'static str = include_str!(concat!(env!("OUT_DIR"), "/platform"));

    pub fn install() -> io::Result<Self> {
        let this = Self::new(Self::default_dest());
        if !this.path.is_dir() {
            this.prepare()?;
        }
        Ok(this)
    }

    /// Without prepare
    pub fn new<P: Into<PathBuf>>(path: P) -> Self { Self { path: path.into() } }
    ///
    pub fn prepare(&self) -> Result<(), ZipError> {
        fs::create_dir_all(&self.path)?;
        let mut a = ZipArchive::new(io::Cursor::new(Self::ZIP))?;
        a.extract(&self.path)
    }

    pub fn default_dest() -> PathBuf {
        let tmp: PathBuf = dirs::cache_dir().unwrap_or_else(env::temp_dir);
        let dir: PathBuf = tmp.join("ms-playwright/playwright-rust/driver");
        dir
    }

    pub fn platform(&self) -> Platform {
        match Self::PLATFORM {
            "linux" => Platform::Linux,
            "mac" => Platform::Mac,
            "win32" => Platform::Win32,
            "win32_x64" => Platform::Win32x64,
            _ => unreachable!()
        }
    }

    pub fn executable(&self) -> PathBuf {
        match self.platform() {
            Platform::Linux => self.path.join("playwright.sh"),
            Platform::Mac => self.path.join("playwright.sh"),
            Platform::Win32 => self.path.join("playwright.cmd"),
            Platform::Win32x64 => self.path.join("playwright.cmd")
        }
    }
}

#[derive(Debug, Clone, Copy)]
pub enum Platform {
    Linux,
    Win32,
    Win32x64,
    Mac
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn install() { let _driver = Driver::install().unwrap(); }
}