rust-gl 0.1.7

Rust wrapper around webgl.
use super::*;
use std::rc::Rc;

#[derive(Debug)]
pub struct Base<T> {
    index: Index,
    name: String,
    gl: Rc<GL>,
    value: T,
}

use core::ops::Deref;
impl<T> Deref for Base<T>{
    type Target = T;
    fn deref(&self) -> &Self::Target{
        &self.value
    }
}

#[derive(Debug, PartialEq, Eq)]
pub enum Error {
    GLError(super::super::context::Error),
    Type(gltype::Error),
    Uniform(String),
    Active(String),
}

use core::fmt;
impl fmt::Display for Error {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
        match self {
            Error::GLError(x) => x.fmt(fmt),
            Error::Type(x) => x.fmt(fmt),
            Error::Uniform(x) => write! {fmt, "Uniform '{}' does not exists.", x},
            Error::Active(x) => write! {fmt, "Uniform '{}' is not active.", x},
        }
    }
}

impl<T> Uniform<T> for Base<T>
where
    T: GLType,
{
    fn index(&self) -> &Index {
        &self.index
    }
    fn swap(&mut self, mut value: T) -> T {
        use core::mem::swap;
        value.send(&*self.gl, &self.index);
        swap(&mut self.value, &mut value);
        value
    }
}

impl<T> ToUniform for T
where
    T: GLType,
{
    type Output = Base<T>;
    type Error = Error;
    fn to_uniform(
        self,
        gl: Rc<GL>,
        program: &WebGlProgram,
        member: Option<Rc<Member>>,
        map: &mut HashMap<String, WebGlActiveInfo>,
    ) -> Result<Self::Output, Self::Error> {
        let name = member.map(|x| x.to_string()).unwrap_or_default();
        let index = match gl.get_uniform_location(program, &name) {
            Some(x) => Ok(x),
            _ => {
                use crate::context::GLError;
                gl.error().map_err(Error::GLError)?;
                Err(Error::Uniform(name.clone()))
            }
        }?;

        let info = map.remove(&name).ok_or(Error::Active(name.clone()))?;

        //Compare if the type is compatible with the attribute.
        T::compatible(&info).map_err(Error::Type)?;

        use core::mem::MaybeUninit;
        let mut base = Base::<T> {
            index,
            name,
            gl,
            value: unsafe { MaybeUninit::uninit().assume_init() },
        };

        base.swap(self);

        Ok(base)
    }
}