diff --git a/examples/non-utf8/Cargo.toml b/examples/non-utf8/Cargo.toml new file mode 100644 index 00000000..b5181a84 --- /dev/null +++ b/examples/non-utf8/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "non-utf8-example" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies] +dotenvy = { path = "../../dotenvy" } +encoding_rs_io = "0.1" \ No newline at end of file diff --git a/examples/non-utf8/env-example-utf16 b/examples/non-utf8/env-example-utf16 new file mode 100644 index 00000000..3e41916e Binary files /dev/null and b/examples/non-utf8/env-example-utf16 differ diff --git a/examples/non-utf8/src/main.rs b/examples/non-utf8/src/main.rs new file mode 100644 index 00000000..60e7370d --- /dev/null +++ b/examples/non-utf8/src/main.rs @@ -0,0 +1,35 @@ +//! dotenvy only handles UTF-8. +//! +//! If a source file is non-UTF-8, it can still be loaded with help from the `encoding_rs_io` crate. + +use dotenvy::EnvLoader; +use encoding_rs_io::DecodeReaderBytes; +use std::{ + error::{self, Error}, + fs, + io::{self, Read}, +}; + +fn main() -> Result<(), Box> { + let path = "env-example-utf16"; + + // this will fail + let e = EnvLoader::with_path(path).load().unwrap_err(); + let io_err = e.source().unwrap().downcast_ref::().unwrap(); + assert_eq!(io_err.kind(), io::ErrorKind::InvalidData); + + // with `encoding_rs_io`, this will work + let bytes = fs::read(path)?; + let mut decoder = DecodeReaderBytes::new(&bytes[..]); + let mut dest = Vec::new(); + + // read to end to ensure the stream is fully decoded + decoder.read_to_end(&mut dest)?; + + // `path` setter provides the path to error messages + let env_map = EnvLoader::with_reader(&dest[..]).path(path).load()?; + + println!("HOST={}", env_map.var("HOST")?); + + Ok(()) +}