miru-gl 0.1.1

OpenGL bindings for my personal game engine
Documentation
use std::fmt;
use std::ops;
use std::rc::Rc;

#[allow(clippy::all)]
mod gl {
    include!(concat!(env!("OUT_DIR"), "/opengl-bindings.rs"));
}

pub use gl::*;

mod miru {
    include!(concat!(env!("OUT_DIR"), "/miru-pinned-opengl-version.rs"));
}

/// Wrapper around Gl type that should be used instead of [`Gl`][1].
///
/// This transparent wrapper allows to safely share and use OpenGL functions
/// without risk of them being called before they're loaded.
///
/// \![`Send`][2] nature of [`Rc<T>`][3] also guarantees that context won't be
/// transferred across thread boundaries, ensuring that functions of a context
/// can only be called in the same thread they were loaded in.
///
/// [1]: struct.Gl.html
/// [2]: https://doc.rust-lang.org/std/marker/trait.Send.html
/// [3]: https://doc.rust-lang.org/std/rc/struct.Rc.html
#[derive(Clone)]
pub struct MiruGl {
    inner: Rc<Gl>,
}

impl MiruGl {
    /// Loads OpenGL functions and returns shared handle.
    ///
    /// # Examples
    ///
    /// ~~~ignore
    /// // the supplied function must be of the type:
    /// // `&fn(symbol: &'static str) -> *const std::ffi::c_void`
    /// let gl = miru_gl::MiruGl::load_with(|symbol| window.get_proc_address(symbol) as *const _);
    /// ~~~
    #[cfg_attr(tarpaulin, skip)]
    pub fn load_with<F>(loadfn: F) -> MiruGl
    where
        F: FnMut(&'static str) -> *const std::ffi::c_void,
    {
        MiruGl {
            inner: Rc::new(Gl::load_with(loadfn)),
        }
    }

    /// Returns OpenGL version used by Miru.
    ///
    /// # Examples
    ///
    /// ~~~ignore
    /// let (major, minor) = gl.version();
    /// ~~~
    #[cfg_attr(tarpaulin, skip)]
    pub fn version(&self) -> (u8, u8) {
        miru::OPENGL_VERSION
    }
}

impl fmt::Debug for MiruGl {
    #[cfg_attr(tarpaulin, skip)]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let (major, minor) = self.version();
        write!(
            f,
            "MiruGl: Shared OpenGL {}.{} (Core Profile) api handle",
            major, minor
        )
    }
}

impl ops::Deref for MiruGl {
    type Target = Gl;

    #[cfg_attr(tarpaulin, skip)]
    fn deref(&self) -> &Self::Target {
        &self.inner
    }
}