pub fn generate_cffi_declarations(crate_dir: &Path, python: &PathBuf) -> Result<String> {
    let tempdir = tempdir()?;
    let header = cffi_header(&crate_dir, &tempdir)?;

    let ffi_py = tempdir.as_ref().join("ffi.py");

    // Using raw strings is important because on windows there are path like
    // `C:\Users\JohnDoe\AppData\Local\TEmpl\pip-wheel-asdf1234` where the \U
    // would otherwise be a broken unicode escape sequence
    let cffi_invocation = format!(
        r#"
import cffi
from cffi import recompiler

ffi = cffi.FFI()
with open(r"{header}") as header:
    ffi.cdef(header.read())
recompiler.make_py_source(ffi, "ffi", r"{ffi_py}")
"#,
        ffi_py = ffi_py.display(),
        header = header.display(),
    );

    let output = call_python(&python, &["-c", &cffi_invocation])?;
    let install_cffi = if !output.status.success() {
        // First, check whether the error was cffi not being installed
        let last_line = str::from_utf8(&output.stderr)?.lines().last().unwrap_or("");
        if last_line == "ModuleNotFoundError: No module named 'cffi'" {
            // Then check whether we're running in a virtualenv.
            // We don't want to modify any global environment
            // https://stackoverflow.com/a/42580137/3549270
            let output = call_python(
                &python,
                &["-c", "import sys\nprint(sys.base_prefix != sys.prefix)"],
            )?;

            match str::from_utf8(&output.stdout)?.trim() {
                "True" => true,
                "False" => false,
                _ => {
                    println!(
                        "⚠  Failed to determine whether python at {:?} is running inside a virtualenv",
                        &python
                    );
                    false
                }
            }
        } else {
            false
        }
    } else {
        false
    };

    // If there was success or an error that was not missing cffi, return here
    if !install_cffi {
        return handle_cffi_call_result(&python, tempdir, &ffi_py, &output);
    }

    println!("⚠  cffi not found. Trying to install it");
    // Call pip through python to don't do the wrong thing when python and pip
    // are coming from different environments
    let output = call_python(&python, &["-m", "pip", "install", "cffi"])?;
    if !output.status.success() {
        bail!(
            "Installing cffi with `{:?} -m pip install cffi` failed: {}\n--- Stdout:\n{}\n--- Stderr:\n{}\n---\nPlease install cffi yourself.",
            &python,
            output.status,
            str::from_utf8(&output.stdout)?,
            str::from_utf8(&output.stderr)?
        );
    }
    println!("🎁 Installed cffi");

    // Try again
    let output = call_python(&python, &["-c", &cffi_invocation])?;
    handle_cffi_call_result(&python, tempdir, &ffi_py, &output)
}
/// Returns the content of what will become ffi.py by invoking cbindgen and cffi
///
/// Checks if user has provided their own header at `target/header.h`, otherwise
/// we run cbindgen to generate one. Installs cffi if it's missing and we're inside a virtualenv
///
/// We're using the cffi recompiler, which reads the header, translates them into instructions
/// how to load the shared library without the header and then writes those instructions to a
/// file called `ffi.py`. This `ffi.py` will expose an object called `ffi`. This object is used
/// in `__init__.py` to load the shared library into a module called `lib`.
Returns the content of what will become ffi.py by invoking cbindgen and cffi
Checks if user has provided their own header at `target/header.h`, otherwise
we run cbindgen to generate one. Installs cffi if it's missing and we're inside a virtualenv

We're using the cffi recompiler, which reads the header, translates them into instructions
how to load the shared library without the header and then writes those instructions to a
file called `ffi.py`. This `ffi.py` will expose an object called `ffi`. This object is used
in `__init__.py` to load the shared library into a module called `lib`.
Returns the content of what will become ffi . py by invoking cbindgen and cffi Checks if user has provided their own header at ` target / header . h ` otherwise we run cbindgen to generate one . Installs cffi if it ' s missing and we ' re inside a virtualenv We ' re using the cffi recompiler which reads the header translates them into instructions how to load the shared library without the header and then writes those instructions to a file called ` ffi . py ` . This ` ffi . py ` will expose an object called ` ffi ` . This object is used in ` __init__ . py ` to load the shared library into a module called ` lib ` .
pub fn generate_cffi_declarations(crate_dir: &Path, python: &PathBuf) -> Result<String> {
    let tempdir = tempdir()?;
    let header = cffi_header(&crate_dir, &tempdir)?;
    let ffi_py = tempdir.as_ref().join("ffi.py");
    // Using raw strings is important because on windows there are path like
    // `C:\Users\JohnDoe\AppData\Local\TEmpl\pip-wheel-asdf1234` where the \U
    // would otherwise be a broken unicode escape sequence
    let cffi_invocation = format!(
        r#"
import cffi
from cffi import recompiler
ffi = cffi.FFI()
with open(r"{header}") as header:
    ffi.cdef(header.read())
recompiler.make_py_source(ffi, "ffi", r"{ffi_py}")
"#,
        ffi_py = ffi_py.display(),
        header = header.display(),
    );
    let output = call_python(&python, &["-c", &cffi_invocation])?;
    let install_cffi = if !output.status.success() {
        // First, check whether the error was cffi not being installed
        let last_line = str::from_utf8(&output.stderr)?.lines().last().unwrap_or("");
        if last_line == "ModuleNotFoundError: No module named 'cffi'" {
            // Then check whether we're running in a virtualenv.
            // We don't want to modify any global environment
            // https://stackoverflow.com/a/42580137/3549270
            let output = call_python(
                &python,
                &["-c", "import sys\nprint(sys.base_prefix != sys.prefix)"],
            )?;
            match str::from_utf8(&output.stdout)?.trim() {
                "True" => true,
                "False" => false,
                _ => {
                    println!(
                        "⚠  Failed to determine whether python at {:?} is running inside a virtualenv",
                        &python
                    );
                    false
                }
            }
        } else {
            false
        }
    } else {
        false
    };
    // If there was success or an error that was not missing cffi, return here
    if !install_cffi {
        return handle_cffi_call_result(&python, tempdir, &ffi_py, &output);
    }
    println!("⚠  cffi not found. Trying to install it");
    // Call pip through python to don't do the wrong thing when python and pip
    // are coming from different environments
    let output = call_python(&python, &["-m", "pip", "install", "cffi"])?;
    if !output.status.success() {
        bail!(
            "Installing cffi with `{:?} -m pip install cffi` failed: {}\n--- Stdout:\n{}\n--- Stderr:\n{}\n---\nPlease install cffi yourself.",
            &python,
            output.status,
            str::from_utf8(&output.stdout)?,
            str::from_utf8(&output.stderr)?
        );
    }
    println!("🎁 Installed cffi");
    // Try again
    let output = call_python(&python, &["-c", &cffi_invocation])?;
    handle_cffi_call_result(&python, tempdir, &ffi_py, &output)
}
pub fn generate_cffi_declarations ( crate_dir : & Path , python : & PathBuf ) -> Result < String > { let tempdir = tempdir ( ) ? ; let header = cffi_header ( & crate_dir , & tempdir ) ? ; let ffi_py = tempdir . as_ref ( ) . join ( " " ) ; // Using raw strings is important because on windows there are path like // `C:\Users\JohnDoe\AppData\Local\TEmpl\pip-wheel-asdf1234` where the \U // would otherwise be a broken unicode escape sequence let cffi_invocation = format ! ( r#"
import cffi
from cffi import recompiler

ffi = cffi.FFI()
with open(r"{header}") as header:
    ffi.cdef(header.read())
recompiler.make_py_source(ffi, "ffi", r"{ffi_py}")
"# ffi_py ffi_py display ( ) header header display ( ) ) ; let output = call_python ( & python , & [ " " , & cffi_invocation ] ) ? ; let install_cffi = if ! output . status . success ( ) { // First, check whether the error was cffi not being installed let last_line = str :: from_utf8 ( & output . stderr ) ? . lines ( ) . last ( ) . unwrap_or ( " " ) ; if last_line == " " { // Then check whether we're running in a virtualenv. // We don't want to modify any global environment // https://stackoverflow.com/a/42580137/3549270 let output = call_python ( & python , & [ " " , " \n " ] , ) ? ; match str :: from_utf8 ( & output . stdout ) ? . trim ( ) { " " => true , " " => false , _ => { println ! ( " python ) ; false } } } else { false } } else { false } ; // If there was success or an error that was not missing cffi, return here if ! install_cffi { return handle_cffi_call_result ( & python , tempdir , & ffi_py , & output ) ; } println ! ( " ; // Call pip through python to don't do the wrong thing when python and pip // are coming from different environments let output = call_python ( & python , & [ " " , " " , " " , " " ] ) ? ; if ! output . status . success ( ) { bail ! ( " \n \n \n \n \n \n " python output status str from_utf8 ( output stdout ) str from_utf8 ( output stderr ) ) ; } println ! ( " // Try again let output = call_python ( & python , & [ " " , & cffi_invocation ] ) ? ; handle_cffi_call_result ( & python , tempdir , & ffi_py , & output ) }
Returns the content of what will become ffi.py by invoking cbindgen and cffi
Checks if user has provided their own header at `target/header.h`, otherwise
we run cbindgen to generate one.
Returns the content of what will become ffi . py by invoking cbindgen and cffi Checks if user has provided their own header at ` target / header . h ` otherwise we run cbindgen to generate one .
crate_dir
&Path
python
&PathBuf
crate_dir
&Path
python
&PathBuf