gled-core 2.32.1

The engine of gled without a user interface: inputs, timing, rendering, Art-Net/DMX output and storage
Documentation
//! The arguments of an OSC message, read as the values the actions take.

use rosc::{OscMessage, OscType};
use uuid::Uuid;

use crate::storage::asset::curve::Curve;
use crate::storage::asset_id::AssetId;

pub(super) fn parse_uuid(msg: &OscMessage, index: usize) -> Result<Uuid, ()> {
    let raw = parse_string(msg, index)?;
    Uuid::parse_str(&raw).map_err(|_| ())
}

pub(super) fn parse_optional_uuid(msg: &OscMessage, index: usize) -> Result<Option<Uuid>, ()> {
    let raw = parse_string(msg, index)?;
    if raw.eq_ignore_ascii_case("none") {
        return Ok(None);
    }
    Uuid::parse_str(&raw).map(Some).map_err(|_| ())
}

pub(super) fn parse_index(value: &str) -> Result<usize, ()> {
    value.parse::<usize>().map_err(|_| ())
}

pub(super) fn parse_rgb(msg: &OscMessage) -> Result<[f32; 3], ()> {
    Ok([parse_f32(msg, 0)?, parse_f32(msg, 1)?, parse_f32(msg, 2)?])
}

fn arg_at(msg: &OscMessage, index: usize) -> Result<&OscType, ()> {
    msg.args.get(index).ok_or(())
}

pub(super) fn parse_f32(msg: &OscMessage, index: usize) -> Result<f32, ()> {
    match arg_at(msg, index)? {
        OscType::Float(value) => Ok(*value),
        OscType::Double(value) => Ok(*value as f32),
        OscType::Int(value) => Ok(*value as f32),
        OscType::Long(value) => Ok(*value as f32),
        _ => Err(()),
    }
}

pub(super) fn parse_u16(msg: &OscMessage, index: usize) -> Result<u16, ()> {
    match arg_at(msg, index)? {
        OscType::Int(value) => u16::try_from(*value).map_err(|_| ()),
        OscType::Long(value) => u16::try_from(*value).map_err(|_| ()),
        _ => Err(()),
    }
}

pub(super) fn parse_u32(msg: &OscMessage, index: usize) -> Result<u32, ()> {
    match arg_at(msg, index)? {
        OscType::Int(value) => u32::try_from(*value).map_err(|_| ()),
        OscType::Long(value) => u32::try_from(*value).map_err(|_| ()),
        _ => Err(()),
    }
}

pub(super) fn parse_i32(msg: &OscMessage, index: usize) -> Result<i32, ()> {
    match arg_at(msg, index)? {
        OscType::Int(value) => Ok(*value),
        OscType::Long(value) => i32::try_from(*value).map_err(|_| ()),
        _ => Err(()),
    }
}

pub(super) fn parse_bool(msg: &OscMessage, index: usize) -> Result<bool, ()> {
    match arg_at(msg, index)? {
        OscType::Bool(value) => Ok(*value),
        OscType::Int(value) => match *value {
            0 => Ok(false),
            1 => Ok(true),
            _ => Err(()),
        },
        OscType::Long(value) => match *value {
            0 => Ok(false),
            1 => Ok(true),
            _ => Err(()),
        },
        _ => Err(()),
    }
}

pub(super) fn parse_string(msg: &OscMessage, index: usize) -> Result<String, ()> {
    match arg_at(msg, index)? {
        OscType::String(value) => Ok(value.clone()),
        _ => Err(()),
    }
}

pub(super) fn parse_curve_id(msg: &OscMessage, index: usize) -> Result<Option<AssetId<Curve>>, ()> {
    let raw = parse_string(msg, index)?;
    if raw.eq_ignore_ascii_case("none") {
        return Ok(None);
    }
    let uuid = Uuid::parse_str(&raw).map_err(|_| ())?;
    Ok(Some(AssetId::from_uuid(uuid)))
}