reactive_graph_plugin_service_impl/
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_path(path: &Path) -> Option<PathBuf> {
14 file_prefix(path).and_then(|file_prefix| {
15 path.parent()
16 .and_then(|path| path.parent())
17 .map(|path| path.join("deploy").join(file_prefix).with_extension(DLL_EXTENSION))
18 })
19}
20
21pub fn get_install_path(path: &Path) -> Option<PathBuf> {
23 file_prefix(path).and_then(|file_prefix| {
24 path.parent().and_then(|path| path.parent()).map(|path| {
25 path.join("installed")
26 .join(file_prefix)
27 .with_extension(format!("{}.{}", get_timestamp(), DLL_EXTENSION))
28 })
29 })
30}
31
32pub fn get_stem(path: &Path) -> Option<String> {
33 file_prefix(path).and_then(|stem| Some(stem.to_str()?.to_string()))
34}
35
36pub fn file_prefix(path: &Path) -> Option<&OsStr> {
38 path.file_name().map(split_file_at_dot).map(|(before, _after)| before)
39}
40
41fn split_file_at_dot(file: &OsStr) -> (&OsStr, Option<&OsStr>) {
43 let slice = os_str_as_u8_slice(file);
44 if slice == b".." {
45 return (file, None);
46 }
47
48 let i = match slice[1..].iter().position(|b| *b == b'.') {
53 Some(i) => i + 1,
54 None => return (file, None),
55 };
56 let before = &slice[..i];
57 let after = &slice[i + 1..];
58 unsafe { (u8_slice_as_os_str(before), Some(u8_slice_as_os_str(after))) }
59}
60
61fn os_str_as_u8_slice(s: &OsStr) -> &[u8] {
63 unsafe { &*(s as *const OsStr as *const [u8]) }
64}
65
66unsafe fn u8_slice_as_os_str(s: &[u8]) -> &OsStr {
68 unsafe { &*(s as *const [u8] as *const OsStr) }
70}