Skip to content

Commit 2476dde

Browse files
committed
Add support for NonZeroT types
1 parent 1986a82 commit 2476dde

File tree

3 files changed

+107
-79
lines changed

3 files changed

+107
-79
lines changed

glib/src/param_spec.rs

Lines changed: 29 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::{
44
char::CharTryFromError,
55
convert::TryFrom,
66
ffi::CStr,
7+
num::{NonZeroI32, NonZeroI64, NonZeroI8, NonZeroU32, NonZeroU64, NonZeroU8},
78
path::{Path, PathBuf},
89
};
910

@@ -2174,87 +2175,36 @@ impl HasParamSpec for char {
21742175
Self::ParamSpec::builder
21752176
}
21762177
}
2177-
impl HasParamSpec for f64 {
2178-
type ParamSpec = ParamSpecDouble;
2179-
type SetValue = Self;
2180-
type BuilderFn = fn(&str) -> ParamSpecDoubleBuilder;
2181-
2182-
fn param_spec_builder() -> Self::BuilderFn {
2183-
Self::ParamSpec::builder
2184-
}
2185-
}
2186-
impl HasParamSpec for f32 {
2187-
type ParamSpec = ParamSpecFloat;
2188-
type SetValue = Self;
2189-
type BuilderFn = fn(&str) -> ParamSpecFloatBuilder;
2190-
2191-
fn param_spec_builder() -> Self::BuilderFn {
2192-
Self::ParamSpec::builder
2193-
}
2194-
}
2195-
impl HasParamSpec for i64 {
2196-
type ParamSpec = ParamSpecInt64;
2197-
type SetValue = Self;
2198-
type BuilderFn = fn(&str) -> ParamSpecInt64Builder;
2199-
2200-
fn param_spec_builder() -> Self::BuilderFn {
2201-
Self::ParamSpec::builder
2202-
}
2203-
}
2204-
impl HasParamSpec for i32 {
2205-
type ParamSpec = ParamSpecInt;
2206-
type SetValue = Self;
2207-
type BuilderFn = fn(&str) -> ParamSpecIntBuilder;
2208-
2209-
fn param_spec_builder() -> Self::BuilderFn {
2210-
Self::ParamSpec::builder
2211-
}
2212-
}
2213-
impl HasParamSpec for i8 {
2214-
type ParamSpec = ParamSpecChar;
2215-
type SetValue = Self;
2216-
type BuilderFn = fn(&str) -> ParamSpecCharBuilder;
2178+
// Simple types which have `type SetValue = Self`
2179+
// and a builder function that doesn't require any parameter except the name
2180+
macro_rules! has_simple_spec {
2181+
($t:ty, $s:ty, $b:ty) => {
2182+
impl HasParamSpec for $t {
2183+
type ParamSpec = $s;
2184+
type SetValue = Self;
2185+
type BuilderFn = fn(&str) -> $b;
22172186

2218-
fn param_spec_builder() -> Self::BuilderFn {
2219-
Self::ParamSpec::builder
2220-
}
2221-
}
2222-
impl HasParamSpec for u64 {
2223-
type ParamSpec = ParamSpecUInt64;
2224-
type SetValue = Self;
2225-
type BuilderFn = fn(&str) -> ParamSpecUInt64Builder;
2226-
2227-
fn param_spec_builder() -> Self::BuilderFn {
2228-
Self::ParamSpec::builder
2229-
}
2230-
}
2231-
impl HasParamSpec for u32 {
2232-
type ParamSpec = ParamSpecUInt;
2233-
type SetValue = Self;
2234-
type BuilderFn = fn(&str) -> ParamSpecUIntBuilder;
2235-
2236-
fn param_spec_builder() -> Self::BuilderFn {
2237-
Self::ParamSpec::builder
2238-
}
2239-
}
2240-
impl HasParamSpec for u8 {
2241-
type ParamSpec = ParamSpecUChar;
2242-
type SetValue = Self;
2243-
type BuilderFn = fn(&str) -> ParamSpecUCharBuilder;
2244-
2245-
fn param_spec_builder() -> Self::BuilderFn {
2246-
Self::ParamSpec::builder
2247-
}
2248-
}
2249-
impl HasParamSpec for bool {
2250-
type ParamSpec = ParamSpecBoolean;
2251-
type SetValue = Self;
2252-
type BuilderFn = fn(&str) -> ParamSpecBooleanBuilder;
2253-
2254-
fn param_spec_builder() -> Self::BuilderFn {
2255-
Self::ParamSpec::builder
2256-
}
2187+
fn param_spec_builder() -> Self::BuilderFn {
2188+
Self::ParamSpec::builder
2189+
}
2190+
}
2191+
};
22572192
}
2193+
has_simple_spec!(f64, ParamSpecDouble, ParamSpecDoubleBuilder);
2194+
has_simple_spec!(f32, ParamSpecFloat, ParamSpecFloatBuilder);
2195+
has_simple_spec!(i64, ParamSpecInt64, ParamSpecInt64Builder);
2196+
has_simple_spec!(NonZeroI64, ParamSpecInt64, ParamSpecInt64Builder);
2197+
has_simple_spec!(i32, ParamSpecInt, ParamSpecIntBuilder);
2198+
has_simple_spec!(NonZeroI32, ParamSpecInt, ParamSpecIntBuilder);
2199+
has_simple_spec!(i8, ParamSpecChar, ParamSpecCharBuilder);
2200+
has_simple_spec!(NonZeroI8, ParamSpecChar, ParamSpecCharBuilder);
2201+
has_simple_spec!(u64, ParamSpecUInt64, ParamSpecUInt64Builder);
2202+
has_simple_spec!(NonZeroU64, ParamSpecUInt64, ParamSpecUInt64Builder);
2203+
has_simple_spec!(u32, ParamSpecUInt, ParamSpecUIntBuilder);
2204+
has_simple_spec!(NonZeroU32, ParamSpecUInt, ParamSpecUIntBuilder);
2205+
has_simple_spec!(u8, ParamSpecUChar, ParamSpecUCharBuilder);
2206+
has_simple_spec!(NonZeroU8, ParamSpecUChar, ParamSpecUCharBuilder);
2207+
has_simple_spec!(bool, ParamSpecBoolean, ParamSpecBooleanBuilder);
22582208

22592209
impl HasParamSpec for crate::Variant {
22602210
type ParamSpec = ParamSpecVariant;

glib/src/types.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::{
77
fmt,
88
marker::PhantomData,
99
mem,
10+
num::{NonZeroI32, NonZeroI64, NonZeroI8, NonZeroU32, NonZeroU64, NonZeroU8},
1011
path::{Path, PathBuf},
1112
ptr,
1213
};
@@ -491,11 +492,17 @@ impl PartialOrd<ULong> for libc::c_ulong {
491492

492493
builtin!(bool, BOOL);
493494
builtin!(i8, I8);
495+
builtin!(NonZeroI8, I8);
494496
builtin!(u8, U8);
497+
builtin!(NonZeroU8, U8);
495498
builtin!(i32, I32);
499+
builtin!(NonZeroI32, I32);
496500
builtin!(u32, U32);
501+
builtin!(NonZeroU32, U32);
497502
builtin!(i64, I64);
503+
builtin!(NonZeroI64, I64);
498504
builtin!(u64, U64);
505+
builtin!(NonZeroU64, U64);
499506
builtin!(ILong, I_LONG);
500507
builtin!(ULong, U_LONG);
501508
builtin!(f32, F32);

glib/src/value.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ use std::{
4545
error,
4646
ffi::CStr,
4747
fmt, mem,
48+
num::{NonZeroI32, NonZeroI64, NonZeroI8, NonZeroU32, NonZeroU64, NonZeroU8},
4849
ops::Deref,
4950
path::{Path, PathBuf},
5051
ptr,
@@ -1244,37 +1245,90 @@ macro_rules! numeric {
12441245
}
12451246
};
12461247
}
1248+
macro_rules! not_zero {
1249+
($name:ty, $num:ty) => {
1250+
impl ValueType for $name {
1251+
type Type = $name;
1252+
}
1253+
1254+
unsafe impl<'a> FromValue<'a> for $name {
1255+
// Works because it returns `UnexpectedNone` if the value is NULL
1256+
// by checking it against `0`.
1257+
type Checker = GenericValueTypeOrNoneChecker<Self>;
1258+
1259+
#[inline]
1260+
unsafe fn from_value(value: &'a Value) -> Self {
1261+
let res = <$num>::from_value(value);
1262+
Self::try_from(res).unwrap()
1263+
}
1264+
}
1265+
1266+
impl ToValue for $name {
1267+
#[inline]
1268+
fn to_value(&self) -> Value {
1269+
<$num>::to_value(&<$num>::from(*self))
1270+
}
1271+
1272+
#[inline]
1273+
fn value_type(&self) -> Type {
1274+
Self::static_type()
1275+
}
1276+
}
1277+
1278+
impl From<$name> for Value {
1279+
#[inline]
1280+
fn from(v: $name) -> Self {
1281+
v.to_value()
1282+
}
1283+
}
1284+
1285+
impl ToValueOptional for $name {
1286+
fn to_value_optional(s: Option<&Self>) -> Value {
1287+
match s {
1288+
Some(x) => x.to_value(),
1289+
None => <$num>::to_value(&0),
1290+
}
1291+
}
1292+
}
1293+
};
1294+
}
12471295

12481296
numeric!(
12491297
i8,
12501298
gobject_ffi::g_value_get_schar,
12511299
gobject_ffi::g_value_set_schar
12521300
);
1301+
not_zero!(NonZeroI8, i8);
12531302
numeric!(
12541303
u8,
12551304
gobject_ffi::g_value_get_uchar,
12561305
gobject_ffi::g_value_set_uchar
12571306
);
1307+
not_zero!(NonZeroU8, u8);
12581308
numeric!(
12591309
i32,
12601310
gobject_ffi::g_value_get_int,
12611311
gobject_ffi::g_value_set_int
12621312
);
1313+
not_zero!(NonZeroI32, i32);
12631314
numeric!(
12641315
u32,
12651316
gobject_ffi::g_value_get_uint,
12661317
gobject_ffi::g_value_set_uint
12671318
);
1319+
not_zero!(NonZeroU32, u32);
12681320
numeric!(
12691321
i64,
12701322
gobject_ffi::g_value_get_int64,
12711323
gobject_ffi::g_value_set_int64
12721324
);
1325+
not_zero!(NonZeroI64, i64);
12731326
numeric!(
12741327
u64,
12751328
gobject_ffi::g_value_get_uint64,
12761329
gobject_ffi::g_value_set_uint64
12771330
);
1331+
not_zero!(NonZeroU64, u64);
12781332
numeric!(
12791333
crate::ILong,
12801334
|v| gobject_ffi::g_value_get_long(v).into(),
@@ -1417,6 +1471,8 @@ impl ToValueOptional for BoxedValue {
14171471

14181472
#[cfg(test)]
14191473
mod tests {
1474+
use std::num::NonZeroI32;
1475+
14201476
use super::*;
14211477

14221478
#[test]
@@ -1557,6 +1613,21 @@ mod tests {
15571613
none_v.get::<i32>(),
15581614
Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
15591615
);
1616+
1617+
// Check handling of NonZeroT
1618+
let v = NonZeroI32::new(123).unwrap().to_value();
1619+
assert_eq!(v.get::<NonZeroI32>(), Ok(NonZeroI32::new(123).unwrap()));
1620+
1621+
let v = 123i32.to_value();
1622+
assert_eq!(v.get::<NonZeroI32>(), Ok(NonZeroI32::new(123).unwrap()));
1623+
1624+
let v = 0i32.to_value();
1625+
assert_eq!(
1626+
v.get::<NonZeroI32>(),
1627+
Err(ValueTypeMismatchOrNoneError::UnexpectedNone)
1628+
);
1629+
1630+
assert_eq!(v.get::<Option<NonZeroI32>>(), Ok(None));
15601631
}
15611632

15621633
#[test]

0 commit comments

Comments
 (0)