Skip to content

Commit 47a0022

Browse files
committed
Remove Option return values in favor of Result (GitoxideLabs#331)
This composes better with other errors, if necessary.
1 parent d730497 commit 47a0022

File tree

1 file changed

+17
-10
lines changed

1 file changed

+17
-10
lines changed

git-features/src/path.rs

+17-10
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,17 @@ use std::borrow::Cow;
4545
use std::ffi::OsStr;
4646

4747
#[derive(Debug)]
48-
/// The error type returned by [`into_bytes()`] which would otherwise return `OsString`,
49-
/// which is not an error.
48+
/// The error type returned by [`into_bytes()`] and others may suffer from failed conversions from or to bytes.
5049
pub struct Utf8Error;
5150

51+
impl std::fmt::Display for Utf8Error {
52+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53+
f.write_str("Could not convert to UTF8 or from UTF8 due to ill-formed input")
54+
}
55+
}
56+
57+
impl std::error::Error for Utf8Error {}
58+
5259
/// Like [`into_bytes()`], but takes `OsStr` as input for a lossless, but fallible, conversion.
5360
pub fn os_str_into_bytes(path: &OsStr) -> Result<&[u8], Utf8Error> {
5461
let path = into_bytes(Cow::Borrowed(path.as_ref()))?;
@@ -99,19 +106,19 @@ pub fn into_bytes_or_panic_on_windows<'a>(path: impl Into<Cow<'a, Path>>) -> Cow
99106
/// On windows, the input is required to be valid UTF-8, which is guaranteed if we wrote it before. There are some potential
100107
/// git versions and windows installation which produce mal-formed UTF-16 if certain emojies are in the path. It's as rare as
101108
/// it sounds, but possible.
102-
pub fn from_byte_slice(input: &[u8]) -> Option<&Path> {
109+
pub fn from_byte_slice(input: &[u8]) -> Result<&Path, Utf8Error> {
103110
#[cfg(unix)]
104111
let p = {
105112
use std::os::unix::ffi::OsStrExt;
106113
OsStr::from_bytes(input).as_ref()
107114
};
108115
#[cfg(not(unix))]
109-
let p = Path::new(std::str::from_utf8(input).ok()?);
110-
Some(p)
116+
let p = Path::new(std::str::from_utf8(input).map_err(|_| Utf8Error)?);
117+
Ok(p)
111118
}
112119

113120
/// Similar to [`from_byte_slice()`], but takes either borrowed or owned `input`.
114-
pub fn from_bytes<'a>(input: impl Into<Cow<'a, [u8]>>) -> Option<Cow<'a, Path>> {
121+
pub fn from_bytes<'a>(input: impl Into<Cow<'a, [u8]>>) -> Result<Cow<'a, Path>, Utf8Error> {
115122
let input = input.into();
116123
match input {
117124
Cow::Borrowed(input) => from_byte_slice(input).map(Cow::Borrowed),
@@ -121,7 +128,7 @@ pub fn from_bytes<'a>(input: impl Into<Cow<'a, [u8]>>) -> Option<Cow<'a, Path>>
121128

122129
/// Similar to [`from_byte_slice()`], but takes either borrowed or owned `input` as bstr.
123130
#[cfg(feature = "bstr")]
124-
pub fn from_bstr<'a>(input: impl Into<Cow<'a, bstr::BStr>>) -> Option<Cow<'a, Path>> {
131+
pub fn from_bstr<'a>(input: impl Into<Cow<'a, bstr::BStr>>) -> Result<Cow<'a, Path>, Utf8Error> {
125132
let input = input.into();
126133
match input {
127134
Cow::Borrowed(input) => from_byte_slice(input).map(Cow::Borrowed),
@@ -130,16 +137,16 @@ pub fn from_bstr<'a>(input: impl Into<Cow<'a, bstr::BStr>>) -> Option<Cow<'a, Pa
130137
}
131138

132139
/// Similar to [`from_byte_slice()`], but takes and produces owned data.
133-
pub fn from_byte_vec(input: impl Into<Vec<u8>>) -> Option<PathBuf> {
140+
pub fn from_byte_vec(input: impl Into<Vec<u8>>) -> Result<PathBuf, Utf8Error> {
134141
let input = input.into();
135142
#[cfg(unix)]
136143
let p = {
137144
use std::os::unix::ffi::OsStringExt;
138145
std::ffi::OsString::from_vec(input).into()
139146
};
140147
#[cfg(not(unix))]
141-
let p = PathBuf::from(String::from_utf8(input).ok()?);
142-
Some(p)
148+
let p = PathBuf::from(String::from_utf8(input).map_err(|_| Utf8Error)?);
149+
Ok(p)
143150
}
144151

145152
/// Similar to [`from_byte_vec()`], but will panic if there is ill-formed UTF-8 in the `input`.

0 commit comments

Comments
 (0)