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)))
}