From 73e824ee5c81e33539b193a83892c54eea2c7020 Mon Sep 17 00:00:00 2001 From: zawz Date: Fri, 18 Aug 2023 11:53:09 +0200 Subject: [PATCH] enh(conf): proper error handling on number types for sets --- src/util/smartset.rs | 57 ++++++++++++++++++++++++++++++++++++++------ test/vmpk.yml | 1 - 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/src/util/smartset.rs b/src/util/smartset.rs index 2d0ca9b..c934a5b 100644 --- a/src/util/smartset.rs +++ b/src/util/smartset.rs @@ -6,6 +6,8 @@ use std::ops; use num::{Num,NumCast}; +use thiserror::Error; + // Trait aliases are unstable //trait smartsetnum = T: Num+Ord+Copy + std::str::FromStr + ops::AddAssign; @@ -64,20 +66,61 @@ where } } + pub fn insert(&mut self, v: T) -> bool { + self.set.insert(v) + } + pub fn len(&self) -> usize { self.set.len() } } -impl From for SmartSet +impl From for SmartSet where T: Num+Ord+Copy+NumCast + std::str::FromStr + ops::AddAssign, - U: Num+Ord+Copy+num::ToPrimitive + std::str::FromStr + ops::AddAssign, { - fn from(i: U) -> Self { - let mut r = SmartSet::::new(); - r.set.insert(num::NumCast::from(i).unwrap()); - r + fn from(i: T) -> Self { + SmartSet { + set: BTreeSet::from([i]), + } + } +} + +#[derive(Error,Debug)] +pub enum Error +where + T: std::fmt::Display, +{ + #[error("invalid type: `{0}`, expected {1}")] + Cast(T,String), + #[error("unknown error")] + Unknown, +} + +trait InternalTryFrom +where + Self: Sized +{ + type Error; + fn i_try_from(other: T) -> Result; +} + +impl InternalTryFrom for SmartSet +where + T: Num+Ord+Copy+NumCast + std::str::FromStr + ops::AddAssign, + U: Num+Ord+Copy+num::ToPrimitive + std::str::FromStr + ops::AddAssign + std::fmt::Display, +{ + type Error = Error; + fn i_try_from(i: U) -> Result { + // let mut r = SmartSet::::new(); + match num::NumCast::from(i) { + Some(v) => { + Ok(SmartSet { + set: BTreeSet::from([v]), + }) + } + _ => Err(Error::Cast(i, std::any::type_name::().to_string())) + } } } @@ -163,7 +206,7 @@ macro_rules! visit_from { where E: de::Error, { - Ok(SmartSet::from(value)) + SmartSet::i_try_from(value).map_err(serde::de::Error::custom) } )* }; diff --git a/test/vmpk.yml b/test/vmpk.yml index cf17dac..a36852e 100644 --- a/test/vmpk.yml +++ b/test/vmpk.yml @@ -42,7 +42,6 @@ devices: - args: [ "sh", "-c", "echo 2 [$channel] NoteOff $id" ] - type: NoteOn channel: 0 - #channel: -1 remap: -1 run: - args: [ "sh", "-c", "echo 2 [$channel] NoteOn $id $value" ]