Skip to main content

git_policy_cli/
path_bytes.rs

1//! What:
2//!  Exact repository path bytes as the operating system takes them,
3//!  and as text for messages.
4//! Why:
5//!  Git allows any bytes in a file name.
6//!  The commit path keeps a path as `Vec<u8>` from Git's listing to Git's next argument,
7//!  so a name that is not UTF-8 reaches Git unchanged;
8//!  only a message for a person shows the text with replacement characters.
9//!
10//! In TS you'd write (pseudocode):
11//! ```ts
12//! // const argument = Buffer.from(bytes); const shown = bytes.toString('utf8');
13//! ```
14
15use std::ffi::OsString;
16
17/// What:
18///  Raw path bytes as an operating-system string for a command line or a file name.
19///  `&[u8]` borrows the bytes;
20///  the result owns a copy.
21/// Why:
22///   A Git path is bytes,
23///  and only the platform decides how to pass them on:
24///  Unix takes them as they are,
25///  other platforms have text names, so the text with replacement characters is the closest name.
26///
27/// In TS you'd write (pseudocode):
28/// ```ts
29/// Buffer.from(bytes)
30/// ```
31pub fn os_from_path_bytes(bytes: &[u8]) -> OsString {
32    #[cfg(unix)]
33    {
34        /// The Unix conversion from raw bytes.
35        use std::os::unix::ffi::OsStringExt;
36        return OsString::from_vec(bytes.to_vec());
37    }
38    // UNTESTED ON WINDOWS: no gate compiles or runs this branch (the crate does not build for Windows; README, Requirements).
39    #[cfg(not(unix))]
40    {
41        return OsString::from(String::from_utf8_lossy(bytes).into_owned());
42    }
43}
44
45/// What:
46///  The readable text of path bytes for a message,
47///  with each invalid sequence replaced by U+FFFD.
48/// Why:
49///   Messages are text,
50///  and the exact bytes travel in the field next to them.
51///
52/// In TS you'd write (pseudocode):
53/// ```ts
54/// bytes.toString('utf8')
55/// ```
56pub fn path_message_text(bytes: &[u8]) -> String {
57    // `.into_owned()` copies the borrowed text only when no replacement was needed.
58    return String::from_utf8_lossy(bytes).into_owned();
59}
60
61/// Conversion controls stay out of the release executable.
62#[cfg(test)]
63#[path = "path_bytes_tests.rs"]
64mod tests;