stable_osstring_encoding/
lib.rs1#![warn(missing_docs, clippy::all)]
2#![doc = include_str!("../readme.md")]
3
4
5
6#[cfg(not(any(unix, windows)))]
7compile_error!(
8 "This crate currently only supports Windows and Unix (Linux and Macos). Adding support for your platform is likely very easy, please consider opening an issue for it in \"stable-osstring-encoding\"'s issue tracker."
9);
10
11
12
13use std::{
14 borrow::Cow,
15 ffi::OsString,
16 path::{Path, PathBuf},
17};
18
19
20
21#[cfg(unix)]
23pub mod impl_unix;
24#[cfg(windows)]
26pub mod impl_windows;
27
28
29
30#[cfg(unix)]
32pub type EncodingWidth = u8;
33#[cfg(windows)]
35pub type EncodingWidth = u16;
36
37pub type StableOsString = Vec<EncodingWidth>;
39
40
41
42pub trait ToStableEncoding {
44 fn to_stable_encoding(&self) -> StableOsString;
46}
47
48pub trait IntoStableEncoding {
50 fn into_stable_encoding(self) -> StableOsString;
52}
53
54pub trait FromStableEncoding {
56 unsafe fn from_stable_encoding<'a>(encoded: impl Into<Cow<'a, [EncodingWidth]>>) -> Self;
64}
65
66
67
68impl ToStableEncoding for Path {
69 fn to_stable_encoding(&self) -> StableOsString {
70 self.as_os_str().to_stable_encoding()
71 }
72}
73
74impl ToStableEncoding for PathBuf {
75 fn to_stable_encoding(&self) -> StableOsString {
76 self.as_os_str().to_stable_encoding()
77 }
78}
79
80impl IntoStableEncoding for PathBuf {
81 fn into_stable_encoding(self) -> StableOsString {
82 self.into_os_string().to_stable_encoding()
83 }
84}
85
86impl FromStableEncoding for PathBuf {
87 unsafe fn from_stable_encoding<'a>(encoded: impl Into<Cow<'a, [EncodingWidth]>>) -> Self {
88 unsafe { PathBuf::from(OsString::from_stable_encoding(encoded)) }
89 }
90}
91
92impl<'a, T> IntoStableEncoding for Cow<'a, T>
93where
94 T: ToStableEncoding + ToOwned,
95 <T as ToOwned>::Owned: IntoStableEncoding,
96{
97 fn into_stable_encoding(self) -> StableOsString {
98 match self {
99 Cow::Borrowed(v) => v.to_stable_encoding(),
100 Cow::Owned(v) => v.into_stable_encoding(),
101 }
102 }
103}
104
105
106
107#[cfg(test)]
108mod test {
109 use crate::{FromStableEncoding, IntoStableEncoding, ToStableEncoding};
110 use std::{ffi::OsString, path::PathBuf};
111
112 #[test]
113 fn basics() {
114 let start = OsString::from("test");
115 let as_stable_1 = start.to_stable_encoding();
116 let as_stable_2 = start.into_stable_encoding();
117 assert_eq!(as_stable_1, as_stable_2);
118
119 let as_stable_1 = &*as_stable_1; let as_os_string_1 = unsafe { OsString::from_stable_encoding(as_stable_1) };
122 let as_os_string_2 = unsafe { OsString::from_stable_encoding(as_stable_2) };
123 assert_eq!(as_os_string_1, as_os_string_2);
124
125 let as_str = as_os_string_1.to_str();
126 assert_eq!(as_str, Some("test"));
127 }
128
129 #[test]
130 fn path_buf() {
131 let start = PathBuf::from(OsString::from("test"));
132 let as_stable_1 = start.to_stable_encoding();
133 let as_stable_2 = start.into_stable_encoding();
134 assert_eq!(as_stable_1, as_stable_2);
135
136 let as_stable_1 = &*as_stable_1; let as_os_string_1 = unsafe { PathBuf::from_stable_encoding(as_stable_1) };
139 let as_os_string_2 = unsafe { PathBuf::from_stable_encoding(as_stable_2) };
140 assert_eq!(as_os_string_1, as_os_string_2);
141
142 let as_str = as_os_string_1.to_str();
143 assert_eq!(as_str, Some("test"));
144 }
145}