libobs_wrapper\utils/
path.rs

1use std::{
2    env,
3    path::{Path, PathBuf},
4};
5
6use super::ObsString;
7
8/// Builds into an `ObsString` that represents a path used
9/// by libobs.
10///
11/// Note that only this path only supports UTF-8 for the
12/// entire absolute path because libobs only supports
13/// UTF-8.
14#[derive(Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord)]
15pub struct ObsPath {
16    path: PathBuf,
17}
18
19impl ObsPath {
20    /// Creates a new `ObsPath` strictly using the path
21    /// `path_str` without any modifications.
22    ///
23    /// If you want to create a relative path, use
24    /// `ObsPath::from_relative`.
25    pub fn new(path_str: &str) -> Self {
26        Self {
27            path: Path::new(path_str).into(),
28        }
29    }
30
31    /// Creates a new `ObsPath` with `path_str`
32    /// appended to the path of the directory which the
33    /// executable file is in.
34    ///
35    /// If you want to create an absolute path, use
36    /// `ObsPath::new`.
37    pub fn from_relative(path_str: &str) -> Self {
38        let mut relative_path = env::current_exe().unwrap();
39
40        relative_path.pop();
41
42        let obs_path = Self {
43            path: relative_path,
44        };
45
46        let path_str = path_str.trim_matches('/');
47
48        obs_path.push(path_str)
49    }
50
51    /// Modifies the path to point to the path
52    /// `path_str` appended to the current path which
53    /// `ObsPath` is pointing to.
54    pub fn push(mut self, value: &str) -> Self {
55        let split = value.split(['/', '\\'].as_ref());
56
57        for item in split {
58            if !item.is_empty() {
59                self.path.push(item);
60            }
61        }
62
63        self
64    }
65
66    /// Modifies the path to point to its current
67    /// parent. This is analogous to `Obs::push(".")`.
68    pub fn pop(mut self) -> Self {
69        self.path.pop();
70        self
71    }
72
73    /// Consumes the `ObsPath` to create a new
74    /// immutable ObsString that encodes a UTF-8
75    /// C-type string which describes the path that
76    /// the `ObsPath` is pointing to.
77    ///
78    /// Note that this function is lossy in that
79    /// any non-Unicode data is completely removed
80    /// from the string. This is because libobs
81    /// does not support non-Unicode characters in
82    /// its path.
83    pub fn build(self) -> ObsString {
84        let mut bytes = self.path.display().to_string().replace("\\", "/");
85
86        if self.path.is_dir() {
87            bytes += "/";
88        }
89        let obs_string = ObsString::from(bytes.as_str());
90
91        drop(self);
92        obs_string
93    }
94}
95
96impl From<ObsPath> for ObsString {
97    fn from(val: ObsPath) -> Self {
98        val.build()
99    }
100}
101
102impl From<ObsPath> for PathBuf {
103    fn from(val: ObsPath) -> Self {
104        val.path
105    }
106}