fferris-sys 0.0.0

DO NOT USE THIS
use std::{fs::File, io::Write};

#[cfg(feature = "__bindgen")]
use bindgen::callbacks::{EnumVariantValue, ParseCallbacks};

#[cfg(feature = "__bindgen")]
extern crate bindgen;

//#[cfg(feature = "__bindgen")]
//#[path = "src/gen.rs"]
//mod gen;
//
//#[cfg(feature = "__bindgen")]
//#[derive(Debug)]
//struct Processor;
//#[cfg(feature = "__bindgen")]
//impl ParseCallbacks for Processor {
//    fn enum_variant_name(
//        &self,
//        enum_name: Option<&str>,
//        original_variant_name: &str,
//        variant_value: bindgen::callbacks::EnumVariantValue,
//    ) -> Option<String> {
//        match enum_name {
//            Some("enum AVCodecID") => {
//                if let Some(varname) = original_variant_name.strip_prefix("AV_CODEC_ID_") {
//                    if let EnumVariantValue::Unsigned(val) = variant_value {
//                        if val == gen::FIRST_AUDIO
//                            || val == gen::FIRST_SUBTITLE
//                            || val == gen::FIRST_UNKNOWN
//                        {
//                            None
//                        } else {
//                            Some(if val > gen::FIRST_UNKNOWN || val == 0 {
//                                varname.to_string()
//                            } else if val > gen::FIRST_SUBTITLE {
//                                format!("Sub{varname}")
//                            } else if val > gen::FIRST_AUDIO {
//                                format!("Audio{varname}")
//                            } else {
//                                format!("Video{varname}")
//                            })
//                        }
//                    } else {
//                        None
//                    }
//                } else {
//                    panic!()
//                }
//            }
//            _ => None,
//        }
//    }
//}

fn main() {
    // Only run bindgen if the super special feature is enabled
    //
    // libav is MASSIVE and not everybody needs to generate the bindings themself.
    // Regenerating the bindings while developing FFerris gets old FAST.
    #[cfg(feature = "__bindgen")]
    {
        std::process::Command::new("clang")
            .args(["-lavutil", "-lavcodec", "src/codec.c"])
            .output()
            .unwrap();
        let out = std::process::Command::new("./a.out")
            .output()
            .unwrap()
            .stdout;

        let mut f = File::options()
            .write(true)
            .create(true)
            .truncate(true)
            .open("src/gen.rs")
            .unwrap();

        f.write_all(out.as_slice()).unwrap();

        const VALID_ENUMS: &'static [&'static str] =
            &["AVMediaType", "AVPixelFormat", "AVClassCategory"];

        let mut b = bindgen::builder()
            // Use core for no_std compatibility
            .use_core()
            // TODO: Do I need this...?
            .generate_cstr(true)
            // Dynamic linking sucks
            .dynamic_link_require_all(true)
            .sort_semantically(true)
            .enable_function_attribute_detection()
            // It was causing me trouble, so I got rid of it.
            // Something related to floating point numbers I think?
            // TODO: Look into this you idiot
            .blocklist_item("FP_.*")
            // Break now; fix later
            .rustified_enum(".*")
            .newtype_enum("AVPixelFormat")
            .translate_enum_integer_types(true);
        //    .parse_callbacks(Box::new(Processor));

        // Includes are conditional, based on Rust features
        // Need to let clang know
        {
            #[cfg(feature = "avformat")]
            {
                b = b.clang_arg("-D__FFERRIS_ENABLE_AVFORMAT");
            }

            #[cfg(feature = "avcodec")]
            {
                b = b.clang_arg("-D__FFERRIS_ENABLE_AVCODEC");
            }

            #[cfg(feature = "avfilter")]
            {
                b = b.clang_arg("-D__FFERRIS_ENABLE_AVFILTER");
            }

            #[cfg(feature = "avdevice")]
            {
                b = b.clang_arg("-D__FFERRIS_ENABLE_AVDEVICE");
            }
        }

        b
            // All the comments because I like LSP autocomplete
            .clang_arg("-fretain-comments-from-system-headers")
            .clang_arg("-fparse-all-comments")
            // Include the include header file with my includes in it
            .header("src/include.h")
            // Finally generate the bindings :)
            .generate()
            .unwrap()
            .write_to_file("src/bindings.rs")
            .unwrap();
    }

    for f in ["src/include.h", "src/gen.c"] {
        println!("cargo::rerun-if-changed={f}");
    }

    println!("cargo::rustc-link-search=/usr/lib");
    println!("cargo::rustc-link-lib=avutil");

    #[cfg(feature = "avformat")]
    println!("cargo::rustc-link-lib=avformat");

    #[cfg(feature = "avcodec")]
    println!("cargo::rustc-link-lib=avcodec");

    #[cfg(feature = "avfilter")]
    println!("cargo::rustc-link-lib=avfilter");

    #[cfg(feature = "avdevice")]
    println!("cargo::rustc-link-lib=avdevice");
}