reactive_graph_plugin_service_api/
plugin_paths.rs1use std::env::consts::DLL_EXTENSION;
2use std::ffi::OsStr;
3use std::path::Path;
4use std::path::PathBuf;
5use std::time::SystemTime;
6use std::time::UNIX_EPOCH;
7
8fn get_timestamp() -> u64 {
9 SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs()
10}
11
12pub fn get_deploy_folder(path: &Path) -> Option<PathBuf> {
13 path.parent().and_then(|path| path.parent()).map(|path| path.join("deploy"))
14}
15
16pub fn get_deploy_path(path: &Path) -> Option<PathBuf> {
18 file_prefix(path).and_then(|file_prefix| {
19 path.parent()
20 .and_then(|path| path.parent())
21 .map(|path| path.join("deploy").join(file_prefix).with_extension(DLL_EXTENSION))
22 })
23}
24
25pub fn get_install_path(path: &Path) -> Option<PathBuf> {
27 file_prefix(path).and_then(|file_prefix| {
28 path.parent().and_then(|path| path.parent()).map(|path| {
29 path.join("installed")
30 .join(file_prefix)
31 .with_extension(format!("{}.{}", get_timestamp(), DLL_EXTENSION))
32 })
33 })
34}
35
36pub fn get_stem(path: &Path) -> Option<String> {
37 file_prefix(path).and_then(|stem| Some(stem.to_str()?.to_string()))
38}
39
40pub fn file_prefix(path: &Path) -> Option<&OsStr> {
42 path.file_name().map(split_file_at_dot).map(|(before, _after)| before)
43}
44
45fn split_file_at_dot(file: &OsStr) -> (&OsStr, Option<&OsStr>) {
47 let slice = os_str_as_u8_slice(file);
48 if slice == b".." {
49 return (file, None);
50 }
51
52 let i = match slice[1..].iter().position(|b| *b == b'.') {
57 Some(i) => i + 1,
58 None => return (file, None),
59 };
60 let before = &slice[..i];
61 let after = &slice[i + 1..];
62 unsafe { (u8_slice_as_os_str(before), Some(u8_slice_as_os_str(after))) }
63}
64
65fn os_str_as_u8_slice(s: &OsStr) -> &[u8] {
67 unsafe { &*(s as *const OsStr as *const [u8]) }
68}
69
70unsafe fn u8_slice_as_os_str(s: &[u8]) -> &OsStr {
72 unsafe { &*(s as *const [u8] as *const OsStr) }
74}