From 9d10cd96dcc549a4ae3708d0b75d02a6817d57bb Mon Sep 17 00:00:00 2001
From: Ryan Hunt <rhunt@eqrion.net>
Date: Sun, 11 Jun 2017 17:32:22 -0400
Subject: [PATCH] Use Cargo.toml to find the root package name

Fixes #18
---
 src/bindgen/cargo_toml.rs | 44 +++++++++++++++++++++++++++++++++++++++
 src/bindgen/mod.rs        |  2 ++
 src/main.rs               | 16 ++++++--------
 3 files changed, 52 insertions(+), 10 deletions(-)
 create mode 100644 src/bindgen/cargo_toml.rs

diff --git a/src/bindgen/cargo_toml.rs b/src/bindgen/cargo_toml.rs
new file mode 100644
index 0000000..46408ea
--- /dev/null
+++ b/src/bindgen/cargo_toml.rs
@@ -0,0 +1,44 @@
+use std::io;
+use std::io::Read;
+use std::fs::File;
+use std::path::Path;
+
+use toml;
+
+#[derive(Debug)]
+/// Possible errors that can occur during Cargo.toml parsing.
+pub enum Error {
+    /// Error during reading of Cargo.toml
+    Io(io::Error),
+    /// Deserialization error
+    Toml(toml::de::Error),
+}
+
+impl From<io::Error> for Error {
+    fn from(err: io::Error) -> Self {
+        Error::Io(err)
+    }
+}
+impl From<toml::de::Error> for Error {
+    fn from(err: toml::de::Error) -> Self {
+        Error::Toml(err)
+    }
+}
+
+#[derive(Clone, Deserialize, Debug)]
+pub struct Manifest {
+    pub package: Package,
+}
+
+#[derive(Clone, Deserialize, Debug)]
+pub struct Package {
+    pub name: String,
+}
+
+pub fn manifest(manifest_path: &Path) -> Result<Manifest, Error> {
+    let mut s = String::new();
+    let mut f = File::open(manifest_path)?;
+    f.read_to_string(&mut s)?;
+
+    toml::from_str::<Manifest>(&s).map_err(|x| x.into())
+}
diff --git a/src/bindgen/mod.rs b/src/bindgen/mod.rs
index b24c514..bf80c2e 100644
--- a/src/bindgen/mod.rs
+++ b/src/bindgen/mod.rs
@@ -29,6 +29,7 @@ macro_rules! deserialize_enum_str {
 
 mod cargo_expand;
 mod cargo_metadata;
+mod cargo_toml;
 mod cdecl;
 mod config;
 mod annotation;
@@ -41,3 +42,4 @@ mod writer;
 
 pub use self::config::*;
 pub use self::library::Library;
+pub use self::cargo_toml::manifest;
diff --git a/src/main.rs b/src/main.rs
index 7df04b0..74ecfe9 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -78,17 +78,13 @@ fn main() {
 
     let library = if Path::new(&input).is_dir() {
         let binding_crate = match matches.value_of("crate") {
-            Some(binding_crate) => binding_crate,
+            Some(binding_crate) => String::from(binding_crate),
             None => {
-                // Try and guess the root crate name by looking
-                // at the directory name, it would be better to
-                // look at the Cargo.toml for this
-                match Path::new(input).parent()
-                                      .and_then(|x| x.file_name())
-                                      .and_then(|x| x.to_str()) {
-                    Some(name) => name,
-                    None => {
-                        error!("cannot infer the name of the bindings crate. specify it with --crate");
+                // Parse the Cargo.toml to find the root package name
+                match bindgen::manifest(&Path::new(&input).join("Cargo.toml")) {
+                    Ok(manifest) => manifest.package.name,
+                    Err(_) => {
+                        error!("cannot parse Cargo.toml to find package name");
                         return;
                     }
                 }
-- 
GitLab