Files
ansi_term
arraydeque
atty
bear_lib_terminal
bear_lib_terminal_sys
bitflags
cfg_if
clap
const_cstr
dirs
dirs_sys
dlopen
dlopen_derive
downcast_rs
lazy_static
libc
num_traits
pir_8_as
pir_8_disasm
pir_8_emu
proc_macro2
quote
serde
serde_derive
strsim
syn
textwrap
time
tinyfiledialogs
toml
unicode_width
unicode_xid
vec_map
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
use super::super::raw::Library;
use super::super::Error;
use std::ops::{Deref, DerefMut};
use super::api::WrapperApi;
use std::ffi::OsStr;

/**
Container for a library handle and both obligatory and optional APIs inside one structure.

A common problem with dynamic link libraries is that they often have different versions and some
of those versions have broader API than others. This structure allows you to use two APIs at the
same time - one obligatory and one optional. If symbols of the optional API are found in the
library, the optional API gets loaded. Otherwise the `optional()` method will return `None`.

#Example

```no_run
#[macro_use]
extern crate dlopen_derive;
extern crate dlopen;
use dlopen::wrapper::{OptionalContainer, WrapperApi};

#[derive(WrapperApi)]
struct Obligatory<'a> {
    do_something: extern "C" fn(),
    global_count: &'a mut u32,
}

#[derive(WrapperApi)]
struct Optional{
    add_one: unsafe extern "C" fn (arg: i32) -> i32,
    c_string: * const u8
}

fn main () {
    let mut container: OptionalContainer<Obligatory, Optional> = unsafe {
        OptionalContainer::load("libexample.dylib")
    }.unwrap();
    container.do_something();
    *container.global_count_mut() += 1;

    match container.optional(){
        &Some(ref opt) => {
            let _result = unsafe { opt.add_one(5) };
            println!("First byte of C string is {}", unsafe{*opt.c_string});
        },
        &None => println!("The optional API was not loaded!")
    }
}
```

**Note:** For more complex cases (multiple versions of API) you can use
[`WrapperMultiApi`](./trait.WrapperMultiApi.html).
*/
pub struct OptionalContainer<Api, Optional>
where
    Api: WrapperApi,
    Optional: WrapperApi,
{
    #[allow(dead_code)]
    //this is not dead code because destructor of Library deallocates the library
    lib: Library,
    api: Api,
    optional: Option<Optional>,
}

impl<Api, Optional> OptionalContainer<Api, Optional>
where
    Api: WrapperApi,
    Optional: WrapperApi,
{
    ///Opens the library using provided file name or path and loads all symbols (including optional
    ///if it is possible).
    pub unsafe fn load<S>(name: S) -> Result<OptionalContainer<Api, Optional>, Error>
    where
        S: AsRef<OsStr>,
    {
        let lib = Library::open(name)?;
        let api = Api::load(&lib)?;
        let optional = Optional::load(&lib).ok();
        Ok(Self { lib, api, optional })
    }

    ///Load all symbols (including optional if it is possible) from the
    ///program itself.
    ///
    /// This allows a shared library to load symbols of the program it was
    /// loaded into.
    pub unsafe fn load_self() -> Result<OptionalContainer<Api, Optional>, Error> {
        let lib = Library::open_self()?;
        let api = Api::load(&lib)?;
        let optional = Optional::load(&lib).ok();
        Ok(Self { lib, api, optional })
    }

    ///Gives access to the optional API - constant version.
    pub fn optional(&self) -> &Option<Optional> {
        return &self.optional;
    }

    ///Gives access to the optional API - constant version.
    pub fn optional_mut(&mut self) -> &Option<Optional> {
        return &mut self.optional;
    }
}

impl<Api, Optional> Deref for OptionalContainer<Api, Optional>
where
    Api: WrapperApi,
    Optional: WrapperApi,
{
    type Target = Api;
    fn deref(&self) -> &Api {
        &self.api
    }
}

impl<Api, Optional> DerefMut for OptionalContainer<Api, Optional>
where
    Api: WrapperApi,
    Optional: WrapperApi,
{
    fn deref_mut(&mut self) -> &mut Api {
        &mut self.api
    }
}