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}