Handle non-utf8 input file with better error
diff --git a/gen/src/error.rs b/gen/src/error.rs
index f140577..b269286 100644
--- a/gen/src/error.rs
+++ b/gen/src/error.rs
@@ -8,8 +8,9 @@
use std::fmt::{self, Display};
use std::io::{self, Write};
use std::ops::Range;
-use std::path::Path;
+use std::path::{Path, PathBuf};
use std::process;
+use std::str::Utf8Error;
pub(crate) type Result<T, E = Error> = std::result::Result<T, E>;
@@ -17,6 +18,7 @@
pub(crate) enum Error {
NoBridgeMod,
Fs(fs::Error),
+ Utf8(PathBuf, Utf8Error),
Syn(syn::Error),
}
@@ -25,6 +27,7 @@
match self {
Error::NoBridgeMod => write!(f, "no #[cxx::bridge] module found"),
Error::Fs(err) => err.fmt(f),
+ Error::Utf8(path, _) => write!(f, "Failed to read file `{}`", path.display()),
Error::Syn(err) => err.fmt(f),
}
}
@@ -34,6 +37,7 @@
fn source(&self) -> Option<&(dyn StdError + 'static)> {
match self {
Error::Fs(err) => err.source(),
+ Error::Utf8(_, err) => Some(err),
Error::Syn(err) => err.source(),
_ => None,
}
diff --git a/gen/src/fs.rs b/gen/src/fs.rs
index 6ad92f8..d1b0b70 100644
--- a/gen/src/fs.rs
+++ b/gen/src/fs.rs
@@ -66,9 +66,9 @@
}
}
-pub(crate) fn read_to_string(path: impl AsRef<Path>) -> Result<String> {
+pub(crate) fn read(path: impl AsRef<Path>) -> Result<Vec<u8>> {
let path = path.as_ref();
- match std::fs::read_to_string(path) {
+ match std::fs::read(path) {
Ok(string) => Ok(string),
Err(e) => err!(e, "Failed to read file `{}`", path),
}
diff --git a/gen/src/mod.rs b/gen/src/mod.rs
index c52d273..f4d643d 100644
--- a/gen/src/mod.rs
+++ b/gen/src/mod.rs
@@ -69,9 +69,9 @@
}
pub(super) fn generate_from_path(path: &Path, opt: &Opt) -> GeneratedCode {
- let source = match fs::read_to_string(path) {
+ let source = match read_to_string(path) {
Ok(source) => source,
- Err(err) => format_err(path, "", Error::Fs(err)),
+ Err(err) => format_err(path, "", err),
};
match generate_from_string(&source, opt) {
Ok(out) => out,
@@ -79,6 +79,14 @@
}
}
+fn read_to_string(path: &Path) -> Result<String> {
+ let bytes = fs::read(path)?;
+ match String::from_utf8(bytes) {
+ Ok(string) => Ok(string),
+ Err(err) => Err(Error::Utf8(path.to_owned(), err.utf8_error())),
+ }
+}
+
fn generate_from_string(source: &str, opt: &Opt) -> Result<GeneratedCode> {
let mut source = source;
if source.starts_with("#!") && !source.starts_with("#![") {