Skip to content

Commit

Permalink
Add support for NonZeroT types
Browse files Browse the repository at this point in the history
  • Loading branch information
ranfdev committed Jul 20, 2023
1 parent 1986a82 commit 2476dde
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 79 deletions.
108 changes: 29 additions & 79 deletions glib/src/param_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::{
char::CharTryFromError,
convert::TryFrom,
ffi::CStr,
num::{NonZeroI32, NonZeroI64, NonZeroI8, NonZeroU32, NonZeroU64, NonZeroU8},
path::{Path, PathBuf},
};

Expand Down Expand Up @@ -2174,87 +2175,36 @@ impl HasParamSpec for char {
Self::ParamSpec::builder
}
}
impl HasParamSpec for f64 {
type ParamSpec = ParamSpecDouble;
type SetValue = Self;
type BuilderFn = fn(&str) -> ParamSpecDoubleBuilder;

fn param_spec_builder() -> Self::BuilderFn {
Self::ParamSpec::builder
}
}
impl HasParamSpec for f32 {
type ParamSpec = ParamSpecFloat;
type SetValue = Self;
type BuilderFn = fn(&str) -> ParamSpecFloatBuilder;

fn param_spec_builder() -> Self::BuilderFn {
Self::ParamSpec::builder
}
}
impl HasParamSpec for i64 {
type ParamSpec = ParamSpecInt64;
type SetValue = Self;
type BuilderFn = fn(&str) -> ParamSpecInt64Builder;

fn param_spec_builder() -> Self::BuilderFn {
Self::ParamSpec::builder
}
}
impl HasParamSpec for i32 {
type ParamSpec = ParamSpecInt;
type SetValue = Self;
type BuilderFn = fn(&str) -> ParamSpecIntBuilder;

fn param_spec_builder() -> Self::BuilderFn {
Self::ParamSpec::builder
}
}
impl HasParamSpec for i8 {
type ParamSpec = ParamSpecChar;
type SetValue = Self;
type BuilderFn = fn(&str) -> ParamSpecCharBuilder;
// Simple types which have `type SetValue = Self`
// and a builder function that doesn't require any parameter except the name
macro_rules! has_simple_spec {
($t:ty, $s:ty, $b:ty) => {
impl HasParamSpec for $t {
type ParamSpec = $s;
type SetValue = Self;
type BuilderFn = fn(&str) -> $b;

fn param_spec_builder() -> Self::BuilderFn {
Self::ParamSpec::builder
}
}
impl HasParamSpec for u64 {
type ParamSpec = ParamSpecUInt64;
type SetValue = Self;
type BuilderFn = fn(&str) -> ParamSpecUInt64Builder;

fn param_spec_builder() -> Self::BuilderFn {
Self::ParamSpec::builder
}
}
impl HasParamSpec for u32 {
type ParamSpec = ParamSpecUInt;
type SetValue = Self;
type BuilderFn = fn(&str) -> ParamSpecUIntBuilder;

fn param_spec_builder() -> Self::BuilderFn {
Self::ParamSpec::builder
}
}
impl HasParamSpec for u8 {
type ParamSpec = ParamSpecUChar;
type SetValue = Self;
type BuilderFn = fn(&str) -> ParamSpecUCharBuilder;

fn param_spec_builder() -> Self::BuilderFn {
Self::ParamSpec::builder
}
}
impl HasParamSpec for bool {
type ParamSpec = ParamSpecBoolean;
type SetValue = Self;
type BuilderFn = fn(&str) -> ParamSpecBooleanBuilder;

fn param_spec_builder() -> Self::BuilderFn {
Self::ParamSpec::builder
}
fn param_spec_builder() -> Self::BuilderFn {
Self::ParamSpec::builder
}
}
};
}
has_simple_spec!(f64, ParamSpecDouble, ParamSpecDoubleBuilder);
has_simple_spec!(f32, ParamSpecFloat, ParamSpecFloatBuilder);
has_simple_spec!(i64, ParamSpecInt64, ParamSpecInt64Builder);
has_simple_spec!(NonZeroI64, ParamSpecInt64, ParamSpecInt64Builder);
has_simple_spec!(i32, ParamSpecInt, ParamSpecIntBuilder);
has_simple_spec!(NonZeroI32, ParamSpecInt, ParamSpecIntBuilder);
has_simple_spec!(i8, ParamSpecChar, ParamSpecCharBuilder);
has_simple_spec!(NonZeroI8, ParamSpecChar, ParamSpecCharBuilder);
has_simple_spec!(u64, ParamSpecUInt64, ParamSpecUInt64Builder);
has_simple_spec!(NonZeroU64, ParamSpecUInt64, ParamSpecUInt64Builder);
has_simple_spec!(u32, ParamSpecUInt, ParamSpecUIntBuilder);
has_simple_spec!(NonZeroU32, ParamSpecUInt, ParamSpecUIntBuilder);
has_simple_spec!(u8, ParamSpecUChar, ParamSpecUCharBuilder);
has_simple_spec!(NonZeroU8, ParamSpecUChar, ParamSpecUCharBuilder);
has_simple_spec!(bool, ParamSpecBoolean, ParamSpecBooleanBuilder);

impl HasParamSpec for crate::Variant {
type ParamSpec = ParamSpecVariant;
Expand Down
7 changes: 7 additions & 0 deletions glib/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::{
fmt,
marker::PhantomData,
mem,
num::{NonZeroI32, NonZeroI64, NonZeroI8, NonZeroU32, NonZeroU64, NonZeroU8},
path::{Path, PathBuf},
ptr,
};
Expand Down Expand Up @@ -491,11 +492,17 @@ impl PartialOrd<ULong> for libc::c_ulong {

builtin!(bool, BOOL);
builtin!(i8, I8);
builtin!(NonZeroI8, I8);
builtin!(u8, U8);
builtin!(NonZeroU8, U8);
builtin!(i32, I32);
builtin!(NonZeroI32, I32);
builtin!(u32, U32);
builtin!(NonZeroU32, U32);
builtin!(i64, I64);
builtin!(NonZeroI64, I64);
builtin!(u64, U64);
builtin!(NonZeroU64, U64);
builtin!(ILong, I_LONG);
builtin!(ULong, U_LONG);
builtin!(f32, F32);
Expand Down
71 changes: 71 additions & 0 deletions glib/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ use std::{
error,
ffi::CStr,
fmt, mem,
num::{NonZeroI32, NonZeroI64, NonZeroI8, NonZeroU32, NonZeroU64, NonZeroU8},
ops::Deref,
path::{Path, PathBuf},
ptr,
Expand Down Expand Up @@ -1244,37 +1245,90 @@ macro_rules! numeric {
}
};
}
macro_rules! not_zero {
($name:ty, $num:ty) => {
impl ValueType for $name {
type Type = $name;
}

unsafe impl<'a> FromValue<'a> for $name {
// Works because it returns `UnexpectedNone` if the value is NULL
// by checking it against `0`.
type Checker = GenericValueTypeOrNoneChecker<Self>;

#[inline]
unsafe fn from_value(value: &'a Value) -> Self {
let res = <$num>::from_value(value);
Self::try_from(res).unwrap()
}
}

impl ToValue for $name {
#[inline]
fn to_value(&self) -> Value {
<$num>::to_value(&<$num>::from(*self))
}

#[inline]
fn value_type(&self) -> Type {
Self::static_type()
}
}

impl From<$name> for Value {
#[inline]
fn from(v: $name) -> Self {
v.to_value()
}
}

impl ToValueOptional for $name {
fn to_value_optional(s: Option<&Self>) -> Value {
match s {
Some(x) => x.to_value(),
None => <$num>::to_value(&0),
}
}
}
};
}

numeric!(
i8,
gobject_ffi::g_value_get_schar,
gobject_ffi::g_value_set_schar
);
not_zero!(NonZeroI8, i8);
numeric!(
u8,
gobject_ffi::g_value_get_uchar,
gobject_ffi::g_value_set_uchar
);
not_zero!(NonZeroU8, u8);
numeric!(
i32,
gobject_ffi::g_value_get_int,
gobject_ffi::g_value_set_int
);
not_zero!(NonZeroI32, i32);
numeric!(
u32,
gobject_ffi::g_value_get_uint,
gobject_ffi::g_value_set_uint
);
not_zero!(NonZeroU32, u32);
numeric!(
i64,
gobject_ffi::g_value_get_int64,
gobject_ffi::g_value_set_int64
);
not_zero!(NonZeroI64, i64);
numeric!(
u64,
gobject_ffi::g_value_get_uint64,
gobject_ffi::g_value_set_uint64
);
not_zero!(NonZeroU64, u64);
numeric!(
crate::ILong,
|v| gobject_ffi::g_value_get_long(v).into(),
Expand Down Expand Up @@ -1417,6 +1471,8 @@ impl ToValueOptional for BoxedValue {

#[cfg(test)]
mod tests {
use std::num::NonZeroI32;

use super::*;

#[test]
Expand Down Expand Up @@ -1557,6 +1613,21 @@ mod tests {
none_v.get::<i32>(),
Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
);

// Check handling of NonZeroT
let v = NonZeroI32::new(123).unwrap().to_value();
assert_eq!(v.get::<NonZeroI32>(), Ok(NonZeroI32::new(123).unwrap()));

let v = 123i32.to_value();
assert_eq!(v.get::<NonZeroI32>(), Ok(NonZeroI32::new(123).unwrap()));

let v = 0i32.to_value();
assert_eq!(
v.get::<NonZeroI32>(),
Err(ValueTypeMismatchOrNoneError::UnexpectedNone)
);

assert_eq!(v.get::<Option<NonZeroI32>>(), Ok(None));
}

#[test]
Expand Down

0 comments on commit 2476dde

Please sign in to comment.