extern crate libc;

use self::libc::c_char;

use std::ffi::CStr;
use std::str::Utf8Error;
use std::ffi::CString;

pub struct CStringUtils {}

impl CStringUtils {
    pub fn c_str_to_string(cstr: *const c_char) -> Result<Option<String>, Utf8Error> {
        if cstr.is_null() {
            return Ok(None);
        }

        unsafe {
            match CStr::from_ptr(cstr).to_str() {
                Ok(str) => Ok(Some(str.to_string())),
                Err(err) => Err(err)
            }
        }
    }

    pub fn string_to_cstring(s: String) -> CString {
        CString::new(s).unwrap()
    }
}

macro_rules! check_useful_c_str {
    ($x:ident, $e:expr) => {
        let $x = match CStringUtils::c_str_to_string($x) {
            Ok(Some(val)) => val,
            _ => return $e,
        };

        if $x.is_empty() {
            return $e
        }
    }
}

macro_rules! check_useful_opt_c_str {
    ($x:ident, $e:expr) => {
        let $x = match CStringUtils::c_str_to_string($x) {
            Ok(opt_val) => opt_val,
            Err(_) => return $e
        };
    }
}
extern crate libc;

use self::libc::c_char;

use std::ffi::CStr;
use std::str::Utf8Error;
use std::ffi::CString;

pub struct CStringUtils {}

impl CStringUtils {
    pub fn c_str_to_string(cstr: *const c_char) -> Result<Option<String>, Utf8Error> {
        if cstr.is_null() {
            return Ok(None)
        }

        unsafe {
            match CStr::from_ptr(cstr).to_str() {
                Ok(str) => Ok(Some(str.to_string())),
                Err(err) => Err(err)
            }
        }
    }

    pub fn string_to_cstring(s: String) -> CString {
        CString::new(s).unwrap()
    }
}

macro_rules! check_useful_c_str {
    ($x:ident, $e:expr) => {
        let $x = match CStringUtils::c_str_to_string($x) {
            Ok(Some(val)) => val,
            Ok(None) => return $e,
            Err(_) => return $e
        };

        if $x.is_empty() {
            return $e
        }
    }
}

macro_rules! check_useful_opt_c_str {
    ($x:ident, $e:expr) => {
        let $x = match CStringUtils::c_str_to_string($x) {
            Ok(Some(val)) => if val.is_empty() { None } else { Some(val) },
            Ok(None) => None,
            Err(_) => return $e
        };
    }
}
--- 
+++ 
@@ -11,7 +11,7 @@
 impl CStringUtils {
     pub fn c_str_to_string(cstr: *const c_char) -> Result<Option<String>, Utf8Error> {
         if cstr.is_null() {
-            return Ok(None)
+            return Ok(None);
         }
 
         unsafe {
@@ -31,8 +31,7 @@
     ($x:ident, $e:expr) => {
         let $x = match CStringUtils::c_str_to_string($x) {
             Ok(Some(val)) => val,
-            Ok(None) => return $e,
-            Err(_) => return $e
+            _ => return $e,
         };
 
         if $x.is_empty() {
@@ -44,8 +43,7 @@
 macro_rules! check_useful_opt_c_str {
     ($x:ident, $e:expr) => {
         let $x = match CStringUtils::c_str_to_string($x) {
-            Ok(Some(val)) => if val.is_empty() { None } else { Some(val) },
-            Ok(None) => None,
+            Ok(opt_val) => opt_val,
             Err(_) => return $e
         };
     }
Fix parsing empty C string.
