Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error cleanup #53

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 43 additions & 106 deletions wooting-analog-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ extern crate enum_primitive_derive;
extern crate ffi_support;
extern crate num_traits;

use ffi_support::FfiStr;
use std::convert::TryFrom;
pub use num_traits::{FromPrimitive, ToPrimitive};
#[cfg(feature = "serdes")]
use serde::{Deserialize, Serialize};
use std::ffi::{CStr, CString};
use std::ops::Deref;
use std::os::raw::{c_char, c_int};
use std::os::raw::{c_char, c_float, c_int};
use thiserror::Error;

#[cfg(target_os = "macos")]
Expand Down Expand Up @@ -217,7 +216,7 @@ pub enum DeviceEventType {
}

#[cfg_attr(feature = "serdes", derive(Serialize, Deserialize))]
#[derive(Debug, PartialEq, Clone, Primitive, Error)]
#[derive(Debug, Default, PartialEq, Clone, Primitive, Error)]
#[repr(C)]
pub enum WootingAnalogResult {
#[error("All OK")]
Expand All @@ -241,6 +240,7 @@ pub enum WootingAnalogResult {
#[error("No Plugins were found")]
NoPlugins = -1995isize,
/// The specified function was not found in the library
#[default]
#[error("The specified function was not found in the library")]
FunctionNotFound = -1994isize,
/// No Keycode mapping to HID was found for the given Keycode
Expand All @@ -265,107 +265,72 @@ impl WootingAnalogResult {
pub fn is_ok_or_no_device(&self) -> bool {
*self == WootingAnalogResult::Ok || *self == WootingAnalogResult::NoDevices
}
}

impl Default for WootingAnalogResult {
fn default() -> Self {
WootingAnalogResult::FunctionNotFound
}
}

#[derive(Debug)]
pub struct SDKResult<T>(pub std::result::Result<T, WootingAnalogResult>);

impl<T> Default for SDKResult<T> {
fn default() -> Self {
Err(Default::default()).into()
pub fn into_sdk_result(self) -> SDKResult<()> {
if self.is_ok() { Ok(()) } else { Err(self) }
}
}

impl<T> Deref for SDKResult<T> {
type Target = std::result::Result<T, WootingAnalogResult>;
pub type SDKResult<T> = Result<T, WootingAnalogResult>;

fn deref(&self) -> &Self::Target {
&self.0
}
pub trait IntoSDKResultExt<T> {
fn into_sdk_result(self) -> SDKResult<T>;
}

impl<T> From<std::result::Result<T, WootingAnalogResult>> for SDKResult<T> {
fn from(ptr: std::result::Result<T, WootingAnalogResult>) -> Self {
SDKResult(ptr)
impl IntoSDKResultExt<u32> for c_int {
fn into_sdk_result(self) -> SDKResult<u32> {
u32::try_from(self).map_err(|_|
WootingAnalogResult::try_from(self)
.unwrap_or(WootingAnalogResult::Failure)
)
}
}

impl<T> Into<std::result::Result<T, WootingAnalogResult>> for SDKResult<T> {
fn into(self) -> std::result::Result<T, WootingAnalogResult> {
self.0
}
}

//TODO: Figure out a way to not have to use this for the lib_wrap_option in the sdk
impl<'a> From<FfiStr<'a>> for SDKResult<FfiStr<'a>> {
fn from(res: FfiStr<'a>) -> Self {
Ok(res).into()
}
}

impl From<c_int> for SDKResult<c_int> {
fn from(res: c_int) -> Self {
if res >= 0 {
Ok(res).into()
} else {
Err(WootingAnalogResult::from_i32(res).unwrap_or(WootingAnalogResult::Failure)).into()
impl IntoSDKResultExt<f32> for f32 {
fn into_sdk_result(self) -> SDKResult<f32> {
match self {
//the RFC was made with matching exact values in mind,
//to prevent problems with structural vs semantic equality (e.g. -0 vs +0).
//there was never any consensus about how ranges should be treated.
//none of this matters though, as the RFC got rejected. the lint just hasn't been removed yet
#[allow(illegal_floating_point_literal_pattern)]
0_f32..=1_f32 => Ok(self),
_ => (self as c_int).into_sdk_result().map(|v| v as f32) //wtf
}
}
}

impl From<c_int> for SDKResult<u32> {
fn from(res: c_int) -> Self {
if res >= 0 {
Ok(res as u32).into()
} else {
Err(WootingAnalogResult::from_i32(res).unwrap_or(WootingAnalogResult::Failure)).into()
}
}
pub trait IntoWootingAnalogResultExt {
fn into_wooting_analog_result(self) -> WootingAnalogResult;
}

impl Into<c_int> for WootingAnalogResult {
fn into(self) -> c_int {
self as c_int
impl IntoWootingAnalogResultExt for SDKResult<()> {
fn into_wooting_analog_result(self) -> WootingAnalogResult {
self.map(|_| WootingAnalogResult::Ok).unwrap_or_else(|e| e) //for some reason rust doesnt have .unwrap_err_or()
}
}

impl From<u32> for SDKResult<u32> {
fn from(res: u32) -> Self {
Ok(res).into()
}
pub trait IntoCResultExt<T> {
fn into_c_result(self) -> T;
}

impl Into<i32> for SDKResult<u32> {
fn into(self) -> i32 {
match self.0 {
Ok(v) => v as i32,
Err(e) => e.into(),
}
impl IntoCResultExt<c_int> for SDKResult<u32> {
fn into_c_result(self) -> c_int {
self.map(|value| value as _)
.unwrap_or_else(|error| error as _)
}
}

impl Into<c_int> for SDKResult<c_int> {
fn into(self) -> c_int {
match self.0 {
Ok(v) => v,
Err(e) => e.into(),
}
impl IntoCResultExt<c_float> for SDKResult<f32> {
fn into_c_result(self) -> c_float {
self.map(|value| value as _)
.unwrap_or_else(|error| error as isize as _)
}
}

impl From<f32> for SDKResult<f32> {
fn from(res: f32) -> Self {
if res >= 0.0 {
Ok(res).into()
} else {
Err(WootingAnalogResult::from_f32(res).unwrap_or(WootingAnalogResult::Failure)).into()
}
impl Into<c_int> for WootingAnalogResult {
fn into(self) -> c_int {
self as c_int
}
}

Expand All @@ -375,34 +340,6 @@ impl Into<f32> for WootingAnalogResult {
}
}

impl Into<f32> for SDKResult<f32> {
fn into(self) -> f32 {
match self.0 {
Ok(v) => v,
Err(e) => e.into(),
}
}
}

impl Into<WootingAnalogResult> for SDKResult<()> {
fn into(self) -> WootingAnalogResult {
match self.0 {
Ok(_) => WootingAnalogResult::Ok,
Err(e) => e,
}
}
}

impl From<WootingAnalogResult> for SDKResult<()> {
fn from(res: WootingAnalogResult) -> Self {
if res.is_ok() {
Ok(()).into()
} else {
Err(res).into()
}
}
}

impl Into<bool> for WootingAnalogResult {
fn into(self) -> bool {
self == WootingAnalogResult::Ok
Expand Down
Loading