singe-npp 0.1.0-alpha.8

Safe Rust wrappers for NVIDIA Performance Primitives library (NPP).
Documentation
use crate::{
    error::{Error, Result},
    types::Size,
};
use singe_core::checked_int;

pub fn to_i32(value: impl TryInto<i32>, name: &str) -> Result<i32> {
    checked_int(value, name, |name| Error::OutOfRange { name })
}

pub fn to_u32(value: impl TryInto<u32>, name: &str) -> Result<u32> {
    checked_int(value, name, |name| Error::OutOfRange { name })
}

pub fn to_usize(value: impl TryInto<usize>, name: &str) -> Result<usize> {
    checked_int(value, name, |name| Error::OutOfRange { name })
}

pub fn to_u64(value: impl TryInto<u64>, name: &str) -> Result<u64> {
    checked_int(value, name, |name| Error::OutOfRange { name })
}

pub fn ensure_positive(value: i32, name: &str) -> Result<()> {
    if value <= 0 {
        return Err(Error::ValueNotPositive { name: name.into() });
    }
    Ok(())
}

pub fn batch_size_i32(left_len: usize, right_len: usize) -> Result<i32> {
    validate_batch_lengths(left_len, right_len)?;
    to_i32(left_len, "batch size")
}

pub fn batch_size_u32(left_len: usize, right_len: usize) -> Result<u32> {
    validate_batch_lengths(left_len, right_len)?;
    to_u32(left_len, "batch size")
}

fn validate_batch_lengths(left_len: usize, right_len: usize) -> Result<()> {
    if left_len != right_len {
        return Err(Error::LengthMismatch {
            name: "batch".into(),
            expected: left_len,
            actual: right_len,
        });
    }
    if left_len <= 1 {
        return Err(Error::OutOfRange {
            name: "batch size".into(),
        });
    }
    Ok(())
}

pub fn validate_same_len(expected: usize, actual: usize, name: &str) -> Result<()> {
    if actual == expected {
        return Ok(());
    }
    Err(Error::LengthMismatch {
        name: name.into(),
        expected,
        actual,
    })
}

pub fn checked_len(size: Size, channels: usize) -> Result<usize> {
    size.validate()?;
    (size.width as usize)
        .checked_mul(size.height as usize)
        .and_then(|value| value.checked_mul(channels))
        .ok_or_else(|| Error::OutOfRange { name: "len".into() })
}

pub fn checked_step(width: i32, channels: usize, element_size: usize) -> Result<i32> {
    let bytes = (width as usize)
        .checked_mul(channels)
        .and_then(|value| value.checked_mul(element_size))
        .ok_or_else(|| Error::OutOfRange {
            name: "step".into(),
        })?;
    to_i32(bytes, "step")
}