pub fn gen_swig(pkg_name: &str, src: &str) {
    let mut tmp_file = File::create("swig.i").unwrap();

    tmp_file.write_all(format!("\
%module {name}
#define PKG_NAME {name}
%include <std_vector.i>
%include <stdint.i>
%include <std_string.i>

%typemap(newfree) char * \"free_string($1);\";


%{{
    namespace ffi {{
        #include \"bindings.h\"
    }}

    using namespace ffi;

    namespace {name} {{
", name=pkg_name).as_bytes()).unwrap();

    let syntax = syn::parse_file(&src).expect("Unable to parse file");
    trace!("Syntax: {:#?}", syntax);
    let mut hdr = String::new();

    // SWIG code is inside doc comments:
    // #[doc = "<swig code here>"]
    // struct __SWIG_INJECT_Foo;
    //
    // So we extract this out.

    syntax.items.iter().flat_map(|i| {
        // Extract out all of the attributes which are attached to structs/functions
        // starting with "__SWIG_INJECT"
        match i {
            syn::Item::Impl(ii) => {
                ii.items.iter().fold(Vec::new(), |mut acc, ref ii| {
                    match ii {
                        syn::ImplItem::Method(iim) => {
                            debug!("{:#?}", iim);
                            if iim.sig.ident.to_string().starts_with(SwigTag::SwigInject.to_str()) {
                                acc.extend_from_slice(&iim.attrs[..]);
                            }            
                            acc
                        },
                        _ => Vec::new(),
                    }
                })
            },
            syn::Item::Struct(syn::ItemStruct { attrs, ident, .. }) |
            syn::Item::Fn(syn::ItemFn { attrs, ident, ..}) => {
                if ident.to_string().starts_with(SwigTag::SwigInject.to_str()) {
                    debug!("{:#?}", attrs);
                    attrs.clone()
                } else {
                    Vec::new()
                }
            },
            _ => Vec::new()
        }
    }).for_each(|ref attr| {
        match attr.interpret_meta() {
            Some(syn::Meta::NameValue(ref mnv)) if &mnv.ident.to_string() == "doc" => {
                // Extract out the doc comment for these attributes
                if let syn::Lit::Str(ref ls) = mnv.lit {
                    let mut swig_class = ls.value().replace("\\n", "\n");
                    let prefix_offset = swig_class.find(SwigTag::CodeStart.to_str()).expect("no code prefix") + SwigTag::CodeStart.len();
                    let suffix_offset = swig_class.find(SwigTag::CodeEnd.to_str()).expect("no code suffix");
                    let final_class = &swig_class[prefix_offset..suffix_offset];

                    let prefix_offset = swig_class.find(SwigTag::HdrStart.to_str()).expect("no header prefix") + SwigTag::HdrStart.len();
                    let suffix_offset = swig_class.find(SwigTag::HdrEnd.to_str()).expect("no header suffix");
                    let final_hdr = &swig_class[prefix_offset..suffix_offset];

                    tmp_file.write_all(&final_class.replace("\\n", "\n").as_bytes()).unwrap();
                    hdr += &final_hdr.replace("\\n", "\n");
                    debug!("{}", final_hdr);
                    debug!("{}", final_class);                    

                }
            },
            _ => ()
            }
    });

    tmp_file.write_all(format!("\
    }}
%}}

namespace {name} {{
    {header}
}}

%ignore {inject};
%include \"bindings.h\";
", name=pkg_name, header=hdr, inject=SwigTag::SwigInject).as_bytes()).unwrap();
}
/// Write the swig code (injected via doc comments) into `swig.i`.
/// This parses expanded Rust code, and writes the SWIG code to a file.
Write the swig code (injected via doc comments) into `swig.i`.
This parses expanded Rust code, and writes the SWIG code to a file.
Write the swig code ( injected via doc comments ) into ` swig . i ` . This parses expanded Rust code and writes the SWIG code to a file .
pub fn gen_swig(pkg_name: &str, src: &str) {
    let mut tmp_file = File::create("swig.i").unwrap();
    tmp_file.write_all(format!("\
%module {name}
#define PKG_NAME {name}
%include <std_vector.i>
%include <stdint.i>
%include <std_string.i>
%typemap(newfree) char * \"free_string($1);\";
%{{
    namespace ffi {{
        #include \"bindings.h\"
    }}
    using namespace ffi;
    namespace {name} {{
", name=pkg_name).as_bytes()).unwrap();
    let syntax = syn::parse_file(&src).expect("Unable to parse file");
    trace!("Syntax: {:#?}", syntax);
    let mut hdr = String::new();
    // SWIG code is inside doc comments:
    // #[doc = "<swig code here>"]
    // struct __SWIG_INJECT_Foo;
    //
    // So we extract this out.
    syntax.items.iter().flat_map(|i| {
        // Extract out all of the attributes which are attached to structs/functions
        // starting with "__SWIG_INJECT"
        match i {
            syn::Item::Impl(ii) => {
                ii.items.iter().fold(Vec::new(), |mut acc, ref ii| {
                    match ii {
                        syn::ImplItem::Method(iim) => {
                            debug!("{:#?}", iim);
                            if iim.sig.ident.to_string().starts_with(SwigTag::SwigInject.to_str()) {
                                acc.extend_from_slice(&iim.attrs[..]);
                            }            
                            acc
                        },
                        _ => Vec::new(),
                    }
                })
            },
            syn::Item::Struct(syn::ItemStruct { attrs, ident, .. }) |
            syn::Item::Fn(syn::ItemFn { attrs, ident, ..}) => {
                if ident.to_string().starts_with(SwigTag::SwigInject.to_str()) {
                    debug!("{:#?}", attrs);
                    attrs.clone()
                } else {
                    Vec::new()
                }
            },
            _ => Vec::new()
        }
    }).for_each(|ref attr| {
        match attr.interpret_meta() {
            Some(syn::Meta::NameValue(ref mnv)) if &mnv.ident.to_string() == "doc" => {
                // Extract out the doc comment for these attributes
                if let syn::Lit::Str(ref ls) = mnv.lit {
                    let mut swig_class = ls.value().replace("\\n", "\n");
                    let prefix_offset = swig_class.find(SwigTag::CodeStart.to_str()).expect("no code prefix") + SwigTag::CodeStart.len();
                    let suffix_offset = swig_class.find(SwigTag::CodeEnd.to_str()).expect("no code suffix");
                    let final_class = &swig_class[prefix_offset..suffix_offset];
                    let prefix_offset = swig_class.find(SwigTag::HdrStart.to_str()).expect("no header prefix") + SwigTag::HdrStart.len();
                    let suffix_offset = swig_class.find(SwigTag::HdrEnd.to_str()).expect("no header suffix");
                    let final_hdr = &swig_class[prefix_offset..suffix_offset];
                    tmp_file.write_all(&final_class.replace("\\n", "\n").as_bytes()).unwrap();
                    hdr += &final_hdr.replace("\\n", "\n");
                    debug!("{}", final_hdr);
                    debug!("{}", final_class);                    
                }
            },
            _ => ()
            }
    });
    tmp_file.write_all(format!("\
    }}
%}}
namespace {name} {{
    {header}
}}
%ignore {inject};
%include \"bindings.h\";
", name=pkg_name, header=hdr, inject=SwigTag::SwigInject).as_bytes()).unwrap();
}
pub fn gen_swig ( pkg_name : & str , src : & str ) { let mut tmp_file = File :: create ( " " ) . unwrap ( ) ; tmp_file . write_all ( format ! ( " \
 \" \" \" \" " name pkg_name ) . as_bytes ( ) ) . unwrap ( ) ; let syntax = syn :: parse_file ( & src ) . expect ( " " ) ; trace ! ( " " syntax ) ; let mut hdr = String :: new ( ) ; // SWIG code is inside doc comments: // #[doc = "<swig code here>"] // struct __SWIG_INJECT_Foo; // // So we extract this out. syntax . items . iter ( ) . flat_map ( | i | { // Extract out all of the attributes which are attached to structs/functions // starting with "__SWIG_INJECT" match i { syn :: Item :: Impl ( ii ) => { ii . items . iter ( ) . fold ( Vec :: new ( ) , | mut acc , ref ii | { match ii { syn :: ImplItem :: Method ( iim ) => { debug ! ( " " iim ) ; if iim . sig . ident . to_string ( ) . starts_with ( SwigTag :: SwigInject . to_str ( ) ) { acc . extend_from_slice ( & iim . attrs [ .. ] ) ; } acc } , _ => Vec :: new ( ) , } } ) } , syn :: Item :: Struct ( syn :: ItemStruct { attrs , ident , .. } ) | syn :: Item :: Fn ( syn :: ItemFn { attrs , ident , .. } ) => { if ident . to_string ( ) . starts_with ( SwigTag :: SwigInject . to_str ( ) ) { debug ! ( " " attrs ) ; attrs . clone ( ) } else { Vec :: new ( ) } } , _ => Vec :: new ( ) } } ) . for_each ( | ref attr | { match attr . interpret_meta ( ) { Some ( syn :: Meta :: NameValue ( ref mnv ) ) if & mnv . ident . to_string ( ) == " " => { // Extract out the doc comment for these attributes if let syn :: Lit :: Str ( ref ls ) = mnv . lit { let mut swig_class = ls . value ( ) . replace ( " \\ " , " \n " ) ; let prefix_offset = swig_class . find ( SwigTag :: CodeStart . to_str ( ) ) . expect ( " " ) + SwigTag :: CodeStart . len ( ) ; let suffix_offset = swig_class . find ( SwigTag :: CodeEnd . to_str ( ) ) . expect ( " " ) ; let final_class = & swig_class [ prefix_offset .. suffix_offset ] ; let prefix_offset = swig_class . find ( SwigTag :: HdrStart . to_str ( ) ) . expect ( " " ) + SwigTag :: HdrStart . len ( ) ; let suffix_offset = swig_class . find ( SwigTag :: HdrEnd . to_str ( ) ) . expect ( " " ) ; let final_hdr = & swig_class [ prefix_offset .. suffix_offset ] ; tmp_file . write_all ( & final_class . replace ( " \\ " , " \n " ) . as_bytes ( ) ) . unwrap ( ) ; hdr += & final_hdr . replace ( " \\ " , " \n " ) ; debug ! ( " " final_hdr ) ; debug ! ( " " final_class ) ; } } , _ => ( ) } } ) ; tmp_file . write_all ( format ! ( " \
 \" \" " name pkg_name header hdr inject SwigTag SwigInject ) . as_bytes ( ) ) . unwrap ( ) ; }
Write the swig code (injected via doc comments) into `swig.i`.
Write the swig code ( injected via doc comments ) into ` swig . i ` .
pkg_name
&str
src
&str
pkg_name
&str
src
&str