1use std::{
44 convert::Infallible,
45 error,
46 ffi::CStr,
47 fmt, mem,
48 num::{NonZeroI32, NonZeroI64, NonZeroI8, NonZeroU32, NonZeroU64, NonZeroU8},
49 ops::Deref,
50 path::{Path, PathBuf},
51 ptr,
52};
53
54use libc::{c_char, c_void};
55
56use crate::{
57 ffi, gobject_ffi,
58 gstring::GString,
59 prelude::*,
60 translate::*,
61 types::{Pointee, Pointer, Type},
62 GStr,
63};
64
65pub trait ValueType: ToValue + for<'a> FromValue<'a> + 'static {
68 type Type: StaticType;
75}
76
77pub trait ValueTypeOptional:
82 ValueType + ToValueOptional + FromValueOptional<'static> + StaticType
83{
84}
85
86impl<T, C, E> ValueType for Option<T>
87where
88 T: for<'a> FromValue<'a, Checker = C> + ValueTypeOptional + StaticType + 'static,
89 C: ValueTypeChecker<Error = ValueTypeMismatchOrNoneError<E>>,
90 E: error::Error + Send + Sized + 'static,
91{
92 type Type = T::Type;
93}
94
95pub unsafe trait ValueTypeChecker {
98 type Error: error::Error + Send + Sized + 'static;
99
100 fn check(value: &Value) -> Result<(), Self::Error>;
101}
102
103#[derive(Clone, PartialEq, Eq, Debug)]
107pub struct ValueTypeMismatchError {
108 actual: Type,
109 requested: Type,
110}
111
112impl ValueTypeMismatchError {
113 pub fn new(actual: Type, requested: Type) -> Self {
114 Self { actual, requested }
115 }
116}
117
118impl ValueTypeMismatchError {
119 pub fn actual_type(&self) -> Type {
120 self.actual
121 }
122
123 pub fn requested_type(&self) -> Type {
124 self.requested
125 }
126}
127
128impl fmt::Display for ValueTypeMismatchError {
129 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
130 write!(
131 f,
132 "Value type mismatch. Actual {:?}, requested {:?}",
133 self.actual_type(),
134 self.requested_type(),
135 )
136 }
137}
138
139impl error::Error for ValueTypeMismatchError {}
140
141impl From<Infallible> for ValueTypeMismatchError {
142 fn from(e: Infallible) -> Self {
143 match e {}
144 }
145}
146
147pub struct GenericValueTypeChecker<T>(std::marker::PhantomData<T>);
150
151unsafe impl<T: StaticType> ValueTypeChecker for GenericValueTypeChecker<T> {
152 type Error = ValueTypeMismatchError;
153
154 #[doc(alias = "g_type_check_value_holds")]
155 #[inline]
156 fn check(value: &Value) -> Result<(), Self::Error> {
157 unsafe {
158 if gobject_ffi::g_type_check_value_holds(&value.inner, T::static_type().into_glib())
159 == ffi::GFALSE
160 {
161 Err(ValueTypeMismatchError::new(
162 Type::from_glib(value.inner.g_type),
163 T::static_type(),
164 ))
165 } else {
166 Ok(())
167 }
168 }
169 }
170}
171
172pub struct CharTypeChecker();
173unsafe impl ValueTypeChecker for CharTypeChecker {
174 type Error = InvalidCharError;
175
176 #[inline]
177 fn check(value: &Value) -> Result<(), Self::Error> {
178 let v = value.get::<u32>()?;
179 match char::from_u32(v) {
180 Some(_) => Ok(()),
181 None => Err(InvalidCharError::CharConversionError),
182 }
183 }
184}
185
186#[derive(Clone, PartialEq, Eq, Debug)]
190pub enum InvalidCharError {
191 WrongValueType(ValueTypeMismatchError),
192 CharConversionError,
193}
194impl fmt::Display for InvalidCharError {
195 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
196 match self {
197 Self::WrongValueType(err) => err.fmt(f),
198 Self::CharConversionError => {
199 write!(f, "couldn't convert to char, invalid u32 contents")
200 }
201 }
202 }
203}
204impl error::Error for InvalidCharError {}
205
206impl From<ValueTypeMismatchError> for InvalidCharError {
207 fn from(err: ValueTypeMismatchError) -> Self {
208 Self::WrongValueType(err)
209 }
210}
211
212impl From<Infallible> for InvalidCharError {
213 fn from(e: Infallible) -> Self {
214 match e {}
215 }
216}
217
218#[derive(Clone, PartialEq, Eq, Debug)]
222pub enum ValueTypeMismatchOrNoneError<E: error::Error> {
223 WrongValueType(E),
224 UnexpectedNone,
225}
226
227impl<E: error::Error> fmt::Display for ValueTypeMismatchOrNoneError<E> {
228 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
229 match self {
230 Self::WrongValueType(err) => <E as fmt::Display>::fmt(err, f),
231 Self::UnexpectedNone => write!(f, "Unexpected None",),
232 }
233 }
234}
235
236impl<E: error::Error> error::Error for ValueTypeMismatchOrNoneError<E> {}
237
238impl<E: error::Error> From<E> for ValueTypeMismatchOrNoneError<E> {
239 fn from(err: E) -> Self {
240 Self::WrongValueType(err)
241 }
242}
243
244pub struct GenericValueTypeOrNoneChecker<T>(std::marker::PhantomData<T>);
247
248unsafe impl<T: StaticType> ValueTypeChecker for GenericValueTypeOrNoneChecker<T> {
249 type Error = ValueTypeMismatchOrNoneError<ValueTypeMismatchError>;
250
251 #[inline]
252 fn check(value: &Value) -> Result<(), Self::Error> {
253 GenericValueTypeChecker::<T>::check(value)?;
254
255 unsafe {
256 if value.inner.data[0].v_uint64 == 0 {
259 return Err(Self::Error::UnexpectedNone);
260 }
261 }
262
263 Ok(())
264 }
265}
266
267pub unsafe trait FromValue<'a>: Sized {
273 type Checker: ValueTypeChecker;
276
277 unsafe fn from_value(value: &'a Value) -> Self;
283}
284
285pub trait FromValueOptional<'a>: private::FromValueOptionalSealed<'a> {}
290
291impl<'a, T, C, E> FromValueOptional<'a> for T
292where
293 T: FromValue<'a, Checker = C>,
294 C: ValueTypeChecker<Error = ValueTypeMismatchOrNoneError<E>>,
295 E: error::Error + Send + Sized + 'static,
296{
297}
298
299mod private {
300 pub trait FromValueOptionalSealed<'a> {}
301
302 impl<'a, T, C, E> FromValueOptionalSealed<'a> for T
303 where
304 T: super::FromValue<'a, Checker = C>,
305 C: super::ValueTypeChecker<Error = super::ValueTypeMismatchOrNoneError<E>>,
306 E: super::error::Error + Send + Sized + 'static,
307 {
308 }
309}
310
311pub struct ValueTypeOrNoneChecker<T, C, E>(std::marker::PhantomData<(T, C, E)>);
314
315unsafe impl<'a, T, C, E> ValueTypeChecker for ValueTypeOrNoneChecker<T, C, E>
316where
317 T: FromValue<'a, Checker = C> + StaticType,
318 C: ValueTypeChecker<Error = ValueTypeMismatchOrNoneError<E>>,
319 E: error::Error + Send + Sized + 'static,
320{
321 type Error = E;
322
323 #[inline]
324 fn check(value: &Value) -> Result<(), Self::Error> {
325 match T::Checker::check(value) {
326 Err(ValueTypeMismatchOrNoneError::UnexpectedNone) => Ok(()),
327 Err(ValueTypeMismatchOrNoneError::WrongValueType(err)) => Err(err),
328 Ok(_) => Ok(()),
329 }
330 }
331}
332
333unsafe impl<'a, T, C, E> FromValue<'a> for Option<T>
336where
337 T: FromValue<'a, Checker = C> + StaticType,
338 C: ValueTypeChecker<Error = ValueTypeMismatchOrNoneError<E>>,
339 E: error::Error + Send + Sized + 'static,
340{
341 type Checker = ValueTypeOrNoneChecker<T, C, E>;
342
343 #[inline]
344 unsafe fn from_value(value: &'a Value) -> Self {
345 match T::Checker::check(value) {
346 Err(ValueTypeMismatchOrNoneError::UnexpectedNone) => None,
347 Err(ValueTypeMismatchOrNoneError::WrongValueType(_err)) => {
348 unreachable!();
350 }
351 Ok(_) => Some(T::from_value(value)),
352 }
353 }
354}
355
356pub trait ToValue {
372 fn to_value(&self) -> Value;
375
376 fn value_type(&self) -> Type;
381}
382
383impl<T: ToValue + StaticType> ToValue for &T {
386 #[inline]
387 fn to_value(&self) -> Value {
388 T::to_value(*self)
389 }
390
391 #[inline]
392 fn value_type(&self) -> Type {
393 T::static_type()
394 }
395}
396
397pub trait ToValueOptional {
400 #[allow(clippy::wrong_self_convention)]
403 fn to_value_optional(s: Option<&Self>) -> Value;
404}
405
406impl<T: ToValueOptional + StaticType> ToValue for Option<T> {
409 #[inline]
410 fn to_value(&self) -> Value {
411 T::to_value_optional(self.as_ref())
412 }
413
414 #[inline]
415 fn value_type(&self) -> Type {
416 T::static_type()
417 }
418}
419
420impl<T: Into<Value> + ToValueOptional> From<Option<T>> for Value {
421 #[inline]
422 fn from(t: Option<T>) -> Self {
423 match t {
424 None => T::to_value_optional(None),
425 Some(t) => t.into(),
426 }
427 }
428}
429
430impl<T: ToValueOptional + StaticType> StaticType for Option<T> {
431 #[inline]
432 fn static_type() -> Type {
433 T::static_type()
434 }
435}
436
437impl<T: ToValueOptional + StaticType + ?Sized> ToValueOptional for &T {
438 #[inline]
439 fn to_value_optional(s: Option<&Self>) -> Value {
440 <T as ToValueOptional>::to_value_optional(s.as_ref().map(|s| **s))
441 }
442}
443
444#[inline]
445unsafe fn copy_value(value: *const gobject_ffi::GValue) -> *mut gobject_ffi::GValue {
446 let copy = ffi::g_malloc0(mem::size_of::<gobject_ffi::GValue>()) as *mut gobject_ffi::GValue;
447 copy_into_value(copy, value);
448 copy
449}
450
451#[inline]
452unsafe fn free_value(value: *mut gobject_ffi::GValue) {
453 clear_value(value);
454 ffi::g_free(value as *mut _);
455}
456
457#[inline]
458unsafe fn init_value(value: *mut gobject_ffi::GValue) {
459 ptr::write(value, mem::zeroed());
460}
461
462#[inline]
463unsafe fn copy_into_value(dest: *mut gobject_ffi::GValue, src: *const gobject_ffi::GValue) {
464 gobject_ffi::g_value_init(dest, (*src).g_type);
465 gobject_ffi::g_value_copy(src, dest);
466}
467
468#[inline]
469unsafe fn clear_value(value: *mut gobject_ffi::GValue) {
470 if (*value).g_type != gobject_ffi::G_TYPE_INVALID {
473 gobject_ffi::g_value_unset(value);
474 }
475}
476
477crate::wrapper! {
479 #[doc(alias = "GValue")]
492 pub struct Value(BoxedInline<gobject_ffi::GValue>);
493
494 match fn {
495 copy => |ptr| copy_value(ptr),
496 free => |ptr| free_value(ptr),
497 init => |ptr| init_value(ptr),
498 copy_into => |dest, src| copy_into_value(dest, src),
499 clear => |ptr| clear_value(ptr),
500 }
501}
502
503impl Value {
504 pub fn from_type(type_: Type) -> Self {
511 unsafe {
512 assert_eq!(
513 gobject_ffi::g_type_check_is_value_type(type_.into_glib()),
514 ffi::GTRUE
515 );
516 Self::from_type_unchecked(type_)
517 }
518 }
519
520 #[inline]
527 pub unsafe fn from_type_unchecked(type_: Type) -> Self {
528 unsafe {
529 let mut value = Value::uninitialized();
530 gobject_ffi::g_value_init(value.to_glib_none_mut().0, type_.into_glib());
531 value
532 }
533 }
534
535 #[inline]
538 pub fn for_value_type<T: ValueType>() -> Self {
539 unsafe { Value::from_type_unchecked(T::Type::static_type()) }
540 }
541
542 #[inline]
545 #[doc(alias = "g_value_set_static_string")]
546 pub fn from_static_str(s: &'static GStr) -> Self {
547 unsafe {
548 let mut v = Self::from_type_unchecked(Type::STRING);
549 gobject_ffi::g_value_set_static_string(v.to_glib_none_mut().0, s.as_ptr());
550 v
551 }
552 }
553
554 #[cfg(feature = "v2_66")]
555 #[cfg_attr(docsrs, doc(cfg(feature = "v2_66")))]
556 #[inline]
560 #[doc(alias = "g_value_set_interned_string")]
561 pub fn from_interned_str(s: &'static GStr) -> Self {
562 unsafe {
563 let mut v = Self::from_type_unchecked(Type::STRING);
564 gobject_ffi::g_value_set_interned_string(v.to_glib_none_mut().0, s.as_ptr());
565 v
566 }
567 }
568
569 #[inline]
574 pub fn get<'a, T>(
575 &'a self,
576 ) -> Result<T, <<T as FromValue<'a>>::Checker as ValueTypeChecker>::Error>
577 where
578 T: FromValue<'a>,
579 {
580 unsafe {
581 T::Checker::check(self)?;
582 Ok(T::from_value(self))
583 }
584 }
585
586 #[inline]
589 pub fn get_owned<T>(
590 &self,
591 ) -> Result<T, <<T as FromValue<'_>>::Checker as ValueTypeChecker>::Error>
592 where
593 T: for<'b> FromValue<'b> + 'static,
594 {
595 unsafe {
596 T::Checker::check(self)?;
597 Ok(FromValue::from_value(self))
598 }
599 }
600
601 #[inline]
605 pub fn is<T: StaticType>(&self) -> bool {
606 self.is_type(T::static_type())
607 }
608
609 #[inline]
613 pub fn is_type(&self, type_: Type) -> bool {
614 self.type_().is_a(type_)
615 }
616
617 #[inline]
620 pub fn type_(&self) -> Type {
621 unsafe { from_glib(self.inner.g_type) }
622 }
623
624 #[doc(alias = "g_value_type_transformable")]
679 pub fn type_transformable(src: Type, dst: Type) -> bool {
680 unsafe {
681 from_glib(gobject_ffi::g_value_type_transformable(
682 src.into_glib(),
683 dst.into_glib(),
684 ))
685 }
686 }
687
688 #[doc(alias = "g_value_transform")]
729 pub fn transform<T: ValueType>(&self) -> Result<Value, crate::BoolError> {
730 self.transform_with_type(T::Type::static_type())
731 }
732
733 #[doc(alias = "g_value_transform")]
736 pub fn transform_with_type(&self, type_: Type) -> Result<Value, crate::BoolError> {
737 unsafe {
738 let mut dest = Value::from_type(type_);
739 if from_glib(gobject_ffi::g_value_transform(
740 self.to_glib_none().0,
741 dest.to_glib_none_mut().0,
742 )) {
743 Ok(dest)
744 } else {
745 Err(crate::bool_error!(
746 "Can't transform value of type '{}' into '{}'",
747 self.type_(),
748 type_
749 ))
750 }
751 }
752 }
753
754 #[inline]
757 pub fn into_raw(self) -> gobject_ffi::GValue {
758 unsafe {
759 let s = mem::ManuallyDrop::new(self);
760 ptr::read(&s.inner)
761 }
762 }
763
764 #[inline]
768 pub fn try_into_send_value<T: Send + StaticType>(self) -> Result<SendValue, Self> {
769 if self.type_().is_a(T::static_type()) {
770 unsafe { Ok(SendValue::unsafe_from(self.into_raw())) }
771 } else {
772 Err(self)
773 }
774 }
775
776 #[inline]
783 pub unsafe fn into_send_value(self) -> SendValue {
784 SendValue::unsafe_from(self.into_raw())
785 }
786
787 fn content_debug_string(&self) -> GString {
788 unsafe { from_glib_full(gobject_ffi::g_strdup_value_contents(self.to_glib_none().0)) }
789 }
790}
791
792impl fmt::Debug for Value {
793 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
794 write!(f, "({}) {}", self.type_(), self.content_debug_string())
795 }
796}
797
798impl<'a, T: ?Sized + ToValue> From<&'a T> for Value {
799 #[inline]
800 fn from(value: &'a T) -> Self {
801 value.to_value()
802 }
803}
804
805impl From<SendValue> for Value {
806 #[inline]
807 fn from(value: SendValue) -> Self {
808 unsafe { Value::unsafe_from(value.into_raw()) }
809 }
810}
811
812impl ToValue for Value {
813 #[inline]
814 fn to_value(&self) -> Value {
815 self.clone()
816 }
817
818 #[inline]
819 fn value_type(&self) -> Type {
820 self.type_()
821 }
822}
823
824impl ToValue for &Value {
825 #[inline]
826 fn to_value(&self) -> Value {
827 (*self).clone()
828 }
829
830 #[inline]
831 fn value_type(&self) -> Type {
832 self.type_()
833 }
834}
835
836pub struct NopChecker;
837
838unsafe impl ValueTypeChecker for NopChecker {
839 type Error = Infallible;
840
841 #[inline]
842 fn check(_value: &Value) -> Result<(), Self::Error> {
843 Ok(())
844 }
845}
846
847unsafe impl<'a> FromValue<'a> for Value {
848 type Checker = NopChecker;
849
850 #[inline]
851 unsafe fn from_value(value: &'a Value) -> Self {
852 value.clone()
853 }
854}
855
856unsafe impl<'a> FromValue<'a> for &'a Value {
857 type Checker = NopChecker;
858
859 #[inline]
860 unsafe fn from_value(value: &'a Value) -> Self {
861 value
862 }
863}
864
865impl ToValue for SendValue {
866 #[inline]
867 fn to_value(&self) -> Value {
868 unsafe { from_glib_none(self.to_glib_none().0) }
869 }
870
871 #[inline]
872 fn value_type(&self) -> Type {
873 self.type_()
874 }
875}
876
877impl ToValue for &SendValue {
878 #[inline]
879 fn to_value(&self) -> Value {
880 unsafe { from_glib_none(self.to_glib_none().0) }
881 }
882
883 #[inline]
884 fn value_type(&self) -> Type {
885 self.type_()
886 }
887}
888
889impl StaticType for BoxedValue {
890 #[inline]
891 fn static_type() -> Type {
892 unsafe { from_glib(gobject_ffi::g_value_get_type()) }
893 }
894}
895
896crate::wrapper! {
897 #[doc(alias = "GValue")]
903 pub struct SendValue(BoxedInline<gobject_ffi::GValue>);
904
905 match fn {
906 copy => |ptr| copy_value(ptr),
907 free => |ptr| free_value(ptr),
908 init => |ptr| init_value(ptr),
909 copy_into => |dest, src| copy_into_value(dest, src),
910 clear => |ptr| clear_value(ptr),
911 }
912}
913
914unsafe impl Send for SendValue {}
915
916impl SendValue {
917 #[inline]
920 pub fn into_raw(self) -> gobject_ffi::GValue {
921 unsafe {
922 let s = mem::ManuallyDrop::new(self);
923 ptr::read(&s.inner)
924 }
925 }
926 #[inline]
927 pub fn from_owned<T: Send + Into<Value>>(t: T) -> Self {
928 unsafe { Self::unsafe_from(t.into().into_raw()) }
929 }
930}
931
932impl fmt::Debug for SendValue {
933 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
934 write!(f, "({}) {}", self.type_(), self.content_debug_string())
935 }
936}
937
938impl Deref for SendValue {
939 type Target = Value;
940
941 #[inline]
942 fn deref(&self) -> &Value {
943 unsafe { &*(self as *const SendValue as *const Value) }
944 }
945}
946
947impl<'a, T: ?Sized + ToSendValue> From<&'a T> for SendValue {
948 #[inline]
949 fn from(value: &'a T) -> Self {
950 value.to_send_value()
951 }
952}
953
954pub trait ToSendValue: Send + ToValue {
957 fn to_send_value(&self) -> SendValue;
960}
961
962impl<T: Send + ToValue + ?Sized> ToSendValue for T {
963 #[inline]
964 fn to_send_value(&self) -> SendValue {
965 unsafe { SendValue::unsafe_from(self.to_value().into_raw()) }
966 }
967}
968
969unsafe impl<'a> FromValue<'a> for &'a str {
970 type Checker = GenericValueTypeOrNoneChecker<Self>;
971
972 #[inline]
973 unsafe fn from_value(value: &'a Value) -> Self {
974 let ptr = gobject_ffi::g_value_get_string(value.to_glib_none().0);
975 CStr::from_ptr(ptr).to_str().expect("Invalid UTF-8")
976 }
977}
978
979impl ToValue for str {
980 fn to_value(&self) -> Value {
981 unsafe {
982 let mut value = Value::for_value_type::<String>();
983
984 gobject_ffi::g_value_take_string(value.to_glib_none_mut().0, self.to_glib_full());
985
986 value
987 }
988 }
989
990 fn value_type(&self) -> Type {
991 String::static_type()
992 }
993}
994
995impl ToValue for &str {
996 fn to_value(&self) -> Value {
997 (*self).to_value()
998 }
999
1000 fn value_type(&self) -> Type {
1001 String::static_type()
1002 }
1003}
1004
1005impl ToValueOptional for str {
1006 fn to_value_optional(s: Option<&Self>) -> Value {
1007 let mut value = Value::for_value_type::<String>();
1008 unsafe {
1009 gobject_ffi::g_value_take_string(value.to_glib_none_mut().0, s.to_glib_full());
1010 }
1011
1012 value
1013 }
1014}
1015
1016impl ValueType for String {
1017 type Type = String;
1018}
1019
1020impl ValueTypeOptional for String {}
1021
1022unsafe impl<'a> FromValue<'a> for String {
1023 type Checker = GenericValueTypeOrNoneChecker<Self>;
1024
1025 unsafe fn from_value(value: &'a Value) -> Self {
1026 String::from(<&str>::from_value(value))
1027 }
1028}
1029
1030impl ToValue for String {
1031 fn to_value(&self) -> Value {
1032 <&str>::to_value(&self.as_str())
1033 }
1034
1035 fn value_type(&self) -> Type {
1036 String::static_type()
1037 }
1038}
1039
1040impl From<String> for Value {
1041 #[inline]
1042 fn from(s: String) -> Self {
1043 s.to_value()
1044 }
1045}
1046
1047impl ToValueOptional for String {
1048 fn to_value_optional(s: Option<&Self>) -> Value {
1049 <str>::to_value_optional(s.as_ref().map(|s| s.as_str()))
1050 }
1051}
1052
1053impl ValueType for Box<str> {
1054 type Type = String;
1055}
1056
1057impl ValueTypeOptional for Box<str> {}
1058
1059unsafe impl<'a> FromValue<'a> for Box<str> {
1060 type Checker = GenericValueTypeOrNoneChecker<Self>;
1061
1062 unsafe fn from_value(value: &'a Value) -> Self {
1063 Box::<str>::from(<&str>::from_value(value))
1064 }
1065}
1066
1067impl StaticType for Box<str> {
1068 fn static_type() -> Type {
1069 String::static_type()
1070 }
1071}
1072
1073impl ToValue for Box<str> {
1074 fn to_value(&self) -> Value {
1075 <&str>::to_value(&self.as_ref())
1076 }
1077
1078 fn value_type(&self) -> Type {
1079 String::static_type()
1080 }
1081}
1082
1083impl From<Box<str>> for Value {
1084 #[inline]
1085 fn from(s: Box<str>) -> Self {
1086 s.to_value()
1087 }
1088}
1089
1090impl ToValueOptional for Box<str> {
1091 fn to_value_optional(s: Option<&Self>) -> Value {
1092 <str>::to_value_optional(s.as_ref().map(|s| s.as_ref()))
1093 }
1094}
1095
1096impl ValueType for Vec<String> {
1097 type Type = Vec<String>;
1098}
1099
1100unsafe impl<'a> FromValue<'a> for Vec<String> {
1101 type Checker = GenericValueTypeChecker<Self>;
1102
1103 unsafe fn from_value(value: &'a Value) -> Self {
1104 let ptr = gobject_ffi::g_value_get_boxed(value.to_glib_none().0) as *const *const c_char;
1105 FromGlibPtrContainer::from_glib_none(ptr)
1106 }
1107}
1108
1109impl ToValue for Vec<String> {
1110 fn to_value(&self) -> Value {
1111 unsafe {
1112 let mut value = Value::for_value_type::<Self>();
1113 let ptr: *mut *mut c_char = self.to_glib_full();
1114 gobject_ffi::g_value_take_boxed(value.to_glib_none_mut().0, ptr as *const c_void);
1115 value
1116 }
1117 }
1118
1119 fn value_type(&self) -> Type {
1120 <Vec<String>>::static_type()
1121 }
1122}
1123
1124impl From<Vec<String>> for Value {
1125 #[inline]
1126 fn from(s: Vec<String>) -> Self {
1127 s.to_value()
1128 }
1129}
1130
1131impl ToValue for [&'_ str] {
1132 fn to_value(&self) -> Value {
1133 unsafe {
1134 let mut value = Value::for_value_type::<Vec<String>>();
1135 let ptr: *mut *mut c_char = self.to_glib_full();
1136 gobject_ffi::g_value_take_boxed(value.to_glib_none_mut().0, ptr as *const c_void);
1137 value
1138 }
1139 }
1140
1141 fn value_type(&self) -> Type {
1142 <Vec<String>>::static_type()
1143 }
1144}
1145
1146impl ToValue for &'_ [&'_ str] {
1147 fn to_value(&self) -> Value {
1148 unsafe {
1149 let mut value = Value::for_value_type::<Vec<String>>();
1150 let ptr: *mut *mut c_char = self.to_glib_full();
1151 gobject_ffi::g_value_take_boxed(value.to_glib_none_mut().0, ptr as *const c_void);
1152 value
1153 }
1154 }
1155
1156 fn value_type(&self) -> Type {
1157 <Vec<String>>::static_type()
1158 }
1159}
1160
1161impl ToValue for Path {
1162 fn to_value(&self) -> Value {
1163 unsafe {
1164 let mut value = Value::for_value_type::<PathBuf>();
1165
1166 gobject_ffi::g_value_take_string(value.to_glib_none_mut().0, self.to_glib_full());
1167
1168 value
1169 }
1170 }
1171
1172 fn value_type(&self) -> Type {
1173 PathBuf::static_type()
1174 }
1175}
1176
1177impl ToValue for &Path {
1178 fn to_value(&self) -> Value {
1179 (*self).to_value()
1180 }
1181
1182 fn value_type(&self) -> Type {
1183 PathBuf::static_type()
1184 }
1185}
1186
1187impl ToValueOptional for Path {
1188 fn to_value_optional(s: Option<&Self>) -> Value {
1189 let mut value = Value::for_value_type::<PathBuf>();
1190 unsafe {
1191 gobject_ffi::g_value_take_string(value.to_glib_none_mut().0, s.to_glib_full());
1192 }
1193
1194 value
1195 }
1196}
1197
1198impl ValueType for PathBuf {
1199 type Type = PathBuf;
1200}
1201
1202impl ValueTypeOptional for PathBuf {}
1203
1204unsafe impl<'a> FromValue<'a> for PathBuf {
1205 type Checker = GenericValueTypeOrNoneChecker<Self>;
1206
1207 unsafe fn from_value(value: &'a Value) -> Self {
1208 from_glib_none(gobject_ffi::g_value_get_string(value.to_glib_none().0))
1209 }
1210}
1211
1212impl ToValue for PathBuf {
1213 fn to_value(&self) -> Value {
1214 <&Path>::to_value(&self.as_path())
1215 }
1216
1217 fn value_type(&self) -> Type {
1218 PathBuf::static_type()
1219 }
1220}
1221
1222impl From<PathBuf> for Value {
1223 #[inline]
1224 fn from(s: PathBuf) -> Self {
1225 s.to_value()
1226 }
1227}
1228
1229impl ToValueOptional for PathBuf {
1230 fn to_value_optional(s: Option<&Self>) -> Value {
1231 <Path>::to_value_optional(s.as_ref().map(|s| s.as_path()))
1232 }
1233}
1234
1235impl ValueType for bool {
1236 type Type = Self;
1237}
1238
1239unsafe impl<'a> FromValue<'a> for bool {
1240 type Checker = GenericValueTypeChecker<Self>;
1241
1242 #[inline]
1243 unsafe fn from_value(value: &'a Value) -> Self {
1244 from_glib(gobject_ffi::g_value_get_boolean(value.to_glib_none().0))
1245 }
1246}
1247
1248impl ToValue for bool {
1249 #[inline]
1250 fn to_value(&self) -> Value {
1251 let mut value = Value::for_value_type::<Self>();
1252 unsafe {
1253 gobject_ffi::g_value_set_boolean(&mut value.inner, self.into_glib());
1254 }
1255 value
1256 }
1257
1258 #[inline]
1259 fn value_type(&self) -> Type {
1260 Self::static_type()
1261 }
1262}
1263
1264impl From<bool> for Value {
1265 #[inline]
1266 fn from(v: bool) -> Self {
1267 v.to_value()
1268 }
1269}
1270
1271impl ValueType for Pointer {
1272 type Type = Self;
1273}
1274
1275unsafe impl<'a> FromValue<'a> for Pointer {
1276 type Checker = GenericValueTypeChecker<Self>;
1277
1278 #[inline]
1279 unsafe fn from_value(value: &'a Value) -> Self {
1280 gobject_ffi::g_value_get_pointer(value.to_glib_none().0)
1281 }
1282}
1283
1284impl ToValue for Pointer {
1285 #[inline]
1286 fn to_value(&self) -> Value {
1287 let mut value = Value::for_value_type::<Self>();
1288 unsafe {
1289 gobject_ffi::g_value_set_pointer(&mut value.inner, *self);
1290 }
1291 value
1292 }
1293
1294 #[inline]
1295 fn value_type(&self) -> Type {
1296 <<Self as ValueType>::Type as StaticType>::static_type()
1297 }
1298}
1299
1300impl From<Pointer> for Value {
1301 #[inline]
1302 fn from(v: Pointer) -> Self {
1303 v.to_value()
1304 }
1305}
1306
1307impl ValueType for ptr::NonNull<Pointee> {
1308 type Type = Pointer;
1309}
1310
1311unsafe impl<'a> FromValue<'a> for ptr::NonNull<Pointee> {
1312 type Checker = GenericValueTypeOrNoneChecker<Self>;
1313
1314 #[inline]
1315 unsafe fn from_value(value: &'a Value) -> Self {
1316 ptr::NonNull::new_unchecked(Pointer::from_value(value))
1317 }
1318}
1319
1320impl ToValue for ptr::NonNull<Pointee> {
1321 #[inline]
1322 fn to_value(&self) -> Value {
1323 self.as_ptr().to_value()
1324 }
1325
1326 #[inline]
1327 fn value_type(&self) -> Type {
1328 <<Self as ValueType>::Type as StaticType>::static_type()
1329 }
1330}
1331
1332impl From<ptr::NonNull<Pointee>> for Value {
1333 #[inline]
1334 fn from(v: ptr::NonNull<Pointee>) -> Self {
1335 v.to_value()
1336 }
1337}
1338
1339impl ToValueOptional for ptr::NonNull<Pointee> {
1340 #[inline]
1341 fn to_value_optional(p: Option<&Self>) -> Value {
1342 p.map(|p| p.as_ptr()).unwrap_or(ptr::null_mut()).to_value()
1343 }
1344}
1345
1346macro_rules! numeric {
1347 ($name:ty, $get:expr, $set:expr) => {
1348 impl ValueType for $name {
1349 type Type = Self;
1350 }
1351
1352 unsafe impl<'a> FromValue<'a> for $name {
1353 type Checker = GenericValueTypeChecker<Self>;
1354
1355 #[inline]
1356 #[allow(clippy::redundant_closure_call)]
1357 unsafe fn from_value(value: &'a Value) -> Self {
1358 $get(value.to_glib_none().0)
1359 }
1360 }
1361
1362 impl ToValue for $name {
1363 #[inline]
1364 #[allow(clippy::redundant_closure_call)]
1365 fn to_value(&self) -> Value {
1366 let mut value = Value::for_value_type::<Self>();
1367 unsafe {
1368 $set(&mut value.inner, *self);
1369 }
1370 value
1371 }
1372
1373 #[inline]
1374 fn value_type(&self) -> Type {
1375 Self::static_type()
1376 }
1377 }
1378
1379 impl From<$name> for Value {
1380 #[inline]
1381 fn from(v: $name) -> Self {
1382 v.to_value()
1383 }
1384 }
1385 };
1386}
1387macro_rules! not_zero {
1388 ($name:ty, $num:ty) => {
1389 impl ValueType for $name {
1390 type Type = $name;
1391 }
1392
1393 unsafe impl<'a> FromValue<'a> for $name {
1394 type Checker = GenericValueTypeOrNoneChecker<Self>;
1397
1398 #[inline]
1399 unsafe fn from_value(value: &'a Value) -> Self {
1400 let res = <$num>::from_value(value);
1401 Self::try_from(res).unwrap()
1402 }
1403 }
1404
1405 impl ToValue for $name {
1406 #[inline]
1407 fn to_value(&self) -> Value {
1408 <$num>::to_value(&<$num>::from(*self))
1409 }
1410
1411 #[inline]
1412 fn value_type(&self) -> Type {
1413 Self::static_type()
1414 }
1415 }
1416
1417 impl From<$name> for Value {
1418 #[inline]
1419 fn from(v: $name) -> Self {
1420 v.to_value()
1421 }
1422 }
1423
1424 impl ToValueOptional for $name {
1425 fn to_value_optional(s: Option<&Self>) -> Value {
1426 match s {
1427 Some(x) => x.to_value(),
1428 None => <$num>::to_value(&0),
1429 }
1430 }
1431 }
1432 };
1433}
1434
1435numeric!(
1436 i8,
1437 gobject_ffi::g_value_get_schar,
1438 gobject_ffi::g_value_set_schar
1439);
1440not_zero!(NonZeroI8, i8);
1441numeric!(
1442 u8,
1443 gobject_ffi::g_value_get_uchar,
1444 gobject_ffi::g_value_set_uchar
1445);
1446not_zero!(NonZeroU8, u8);
1447numeric!(
1448 i32,
1449 gobject_ffi::g_value_get_int,
1450 gobject_ffi::g_value_set_int
1451);
1452not_zero!(NonZeroI32, i32);
1453numeric!(
1454 u32,
1455 gobject_ffi::g_value_get_uint,
1456 gobject_ffi::g_value_set_uint
1457);
1458not_zero!(NonZeroU32, u32);
1459numeric!(
1460 i64,
1461 gobject_ffi::g_value_get_int64,
1462 gobject_ffi::g_value_set_int64
1463);
1464not_zero!(NonZeroI64, i64);
1465numeric!(
1466 u64,
1467 gobject_ffi::g_value_get_uint64,
1468 gobject_ffi::g_value_set_uint64
1469);
1470not_zero!(NonZeroU64, u64);
1471numeric!(
1472 crate::ILong,
1473 |v| gobject_ffi::g_value_get_long(v).into(),
1474 |v, i: crate::ILong| gobject_ffi::g_value_set_long(v, i.0)
1475);
1476numeric!(
1477 crate::ULong,
1478 |v| gobject_ffi::g_value_get_ulong(v).into(),
1479 |v, i: crate::ULong| gobject_ffi::g_value_set_ulong(v, i.0)
1480);
1481numeric!(
1482 f32,
1483 gobject_ffi::g_value_get_float,
1484 gobject_ffi::g_value_set_float
1485);
1486numeric!(
1487 f64,
1488 gobject_ffi::g_value_get_double,
1489 gobject_ffi::g_value_set_double
1490);
1491
1492impl ValueType for char {
1493 type Type = u32;
1494}
1495
1496unsafe impl<'a> FromValue<'a> for char {
1497 type Checker = CharTypeChecker;
1498
1499 #[inline]
1500 unsafe fn from_value(value: &'a Value) -> Self {
1501 let res: u32 = gobject_ffi::g_value_get_uint(value.to_glib_none().0);
1502 char::from_u32_unchecked(res)
1504 }
1505}
1506
1507impl ToValue for char {
1508 #[inline]
1509 fn to_value(&self) -> Value {
1510 let mut value = Value::for_value_type::<Self>();
1511 unsafe {
1512 gobject_ffi::g_value_set_uint(&mut value.inner, *self as u32);
1513 }
1514 value
1515 }
1516
1517 #[inline]
1518 fn value_type(&self) -> Type {
1519 crate::Type::U32
1520 }
1521}
1522
1523impl From<char> for Value {
1524 #[inline]
1525 fn from(v: char) -> Self {
1526 v.to_value()
1527 }
1528}
1529
1530pub struct BoxedValue(pub Value);
1533
1534impl Deref for BoxedValue {
1535 type Target = Value;
1536
1537 #[inline]
1538 fn deref(&self) -> &Value {
1539 &self.0
1540 }
1541}
1542
1543impl ValueType for BoxedValue {
1544 type Type = BoxedValue;
1545}
1546
1547impl ValueTypeOptional for BoxedValue {}
1548
1549unsafe impl<'a> FromValue<'a> for BoxedValue {
1550 type Checker = GenericValueTypeOrNoneChecker<Self>;
1551
1552 #[inline]
1553 unsafe fn from_value(value: &'a Value) -> Self {
1554 let ptr = gobject_ffi::g_value_get_boxed(value.to_glib_none().0);
1555 BoxedValue(from_glib_none(ptr as *const gobject_ffi::GValue))
1556 }
1557}
1558
1559impl ToValue for BoxedValue {
1560 #[inline]
1561 fn to_value(&self) -> Value {
1562 unsafe {
1563 let mut value = Value::for_value_type::<BoxedValue>();
1564
1565 gobject_ffi::g_value_set_boxed(
1566 value.to_glib_none_mut().0,
1567 self.0.to_glib_none().0 as ffi::gconstpointer,
1568 );
1569
1570 value
1571 }
1572 }
1573
1574 #[inline]
1575 fn value_type(&self) -> Type {
1576 BoxedValue::static_type()
1577 }
1578}
1579
1580impl From<BoxedValue> for Value {
1581 #[inline]
1582 fn from(v: BoxedValue) -> Self {
1583 unsafe {
1584 let mut value = Value::for_value_type::<BoxedValue>();
1585
1586 gobject_ffi::g_value_take_boxed(
1587 value.to_glib_none_mut().0,
1588 v.0.to_glib_full() as ffi::gconstpointer,
1589 );
1590
1591 value
1592 }
1593 }
1594}
1595
1596impl ToValueOptional for BoxedValue {
1597 #[inline]
1598 fn to_value_optional(s: Option<&Self>) -> Value {
1599 let mut value = Value::for_value_type::<Self>();
1600 unsafe {
1601 gobject_ffi::g_value_set_boxed(
1602 value.to_glib_none_mut().0,
1603 s.map(|s| &s.0).to_glib_none().0 as ffi::gconstpointer,
1604 );
1605 }
1606
1607 value
1608 }
1609}
1610
1611#[cfg(test)]
1612mod tests {
1613 use std::num::NonZeroI32;
1614
1615 use super::*;
1616
1617 #[test]
1618 fn test_send_value() {
1619 use std::thread;
1620
1621 let v = SendValue::from(&1i32);
1622
1623 thread::spawn(move || drop(v)).join().unwrap();
1625 }
1626
1627 #[test]
1628 fn test_strv() {
1629 let v = ["123", "456"].to_value();
1630 assert_eq!(
1631 v.get::<Vec<GString>>(),
1632 Ok(vec![GString::from("123"), GString::from("456")])
1633 );
1634
1635 let v = vec![String::from("123"), String::from("456")].to_value();
1636 assert_eq!(
1637 v.get::<Vec<GString>>(),
1638 Ok(vec![GString::from("123"), GString::from("456")])
1639 );
1640 }
1641
1642 #[test]
1643 fn test_from_to_value() {
1644 let v = 123.to_value();
1645 assert_eq!(v.get(), Ok(123));
1646 assert_eq!(
1647 v.get::<&str>(),
1648 Err(ValueTypeMismatchError::new(Type::I32, Type::STRING).into())
1649 );
1650 assert_eq!(
1651 v.get::<bool>(),
1652 Err(ValueTypeMismatchError::new(Type::I32, Type::BOOL))
1653 );
1654
1655 let v_str = "test".to_value();
1657 assert_eq!(v_str.get::<&str>(), Ok("test"));
1658 assert_eq!(v_str.get::<Option<&str>>(), Ok(Some("test")));
1659 assert_eq!(
1660 v_str.get::<i32>(),
1661 Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1662 );
1663
1664 let some_v = Some("test").to_value();
1665 assert_eq!(some_v.get::<&str>(), Ok("test"));
1666 assert_eq!(some_v.get_owned::<String>(), Ok("test".to_string()));
1667 assert_eq!(
1668 some_v.get_owned::<Option<String>>(),
1669 Ok(Some("test".to_string()))
1670 );
1671 assert_eq!(some_v.get::<Option<&str>>(), Ok(Some("test")));
1672 assert_eq!(
1673 some_v.get::<i32>(),
1674 Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1675 );
1676
1677 let none_str: Option<&str> = None;
1678 let none_v = none_str.to_value();
1679 assert_eq!(none_v.get::<Option<&str>>(), Ok(None));
1680 assert_eq!(
1681 none_v.get::<i32>(),
1682 Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1683 );
1684
1685 let v_str = String::from("test").to_value();
1687 assert_eq!(v_str.get::<String>(), Ok(String::from("test")));
1688 assert_eq!(
1689 v_str.get::<Option<String>>(),
1690 Ok(Some(String::from("test")))
1691 );
1692 assert_eq!(
1693 v_str.get::<i32>(),
1694 Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1695 );
1696
1697 let some_v = Some(String::from("test")).to_value();
1698 assert_eq!(some_v.get::<String>(), Ok(String::from("test")));
1699 assert_eq!(
1700 some_v.get::<Option<String>>(),
1701 Ok(Some(String::from("test")))
1702 );
1703 assert_eq!(
1704 some_v.get::<i32>(),
1705 Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1706 );
1707
1708 let none_str: Option<String> = None;
1709 let none_v = none_str.to_value();
1710 assert_eq!(none_v.get::<Option<String>>(), Ok(None));
1711 assert_eq!(
1712 none_v.get::<i32>(),
1713 Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1714 );
1715
1716 let c_v = 'c'.to_value();
1717 assert_eq!(c_v.get::<char>(), Ok('c'));
1718
1719 let c_v = 0xFFFFFFFFu32.to_value();
1720 assert_eq!(
1721 c_v.get::<char>(),
1722 Err(InvalidCharError::CharConversionError)
1723 );
1724
1725 let v_str = String::from("test").to_value();
1727 assert_eq!(v_str.get::<String>(), Ok(String::from("test")));
1728 assert_eq!(
1729 v_str.get::<Option<String>>(),
1730 Ok(Some(String::from("test")))
1731 );
1732 assert_eq!(
1733 v_str.get::<i32>(),
1734 Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1735 );
1736
1737 let some_v = Some(&String::from("test")).to_value();
1738 assert_eq!(some_v.get::<String>(), Ok(String::from("test")));
1739 assert_eq!(
1740 some_v.get::<Option<String>>(),
1741 Ok(Some(String::from("test")))
1742 );
1743 assert_eq!(
1744 some_v.get::<i32>(),
1745 Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1746 );
1747
1748 let none_str: Option<&String> = None;
1749 let none_v = none_str.to_value();
1750 assert_eq!(none_v.get::<Option<String>>(), Ok(None));
1751 assert_eq!(
1752 none_v.get::<i32>(),
1753 Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1754 );
1755
1756 let v = NonZeroI32::new(123).unwrap().to_value();
1758 assert_eq!(v.get::<NonZeroI32>(), Ok(NonZeroI32::new(123).unwrap()));
1759
1760 let v = 123i32.to_value();
1761 assert_eq!(v.get::<NonZeroI32>(), Ok(NonZeroI32::new(123).unwrap()));
1762
1763 let v = 0i32.to_value();
1764 assert_eq!(
1765 v.get::<NonZeroI32>(),
1766 Err(ValueTypeMismatchOrNoneError::UnexpectedNone)
1767 );
1768
1769 assert_eq!(v.get::<Option<NonZeroI32>>(), Ok(None));
1770 }
1771
1772 #[test]
1773 fn test_transform() {
1774 let v = 123.to_value();
1775 let v2 = v
1776 .transform::<String>()
1777 .expect("Failed to transform to string");
1778 assert_eq!(v2.get::<&str>(), Ok("123"));
1779 }
1780
1781 #[test]
1782 fn test_into_raw() {
1783 unsafe {
1784 let mut v = 123.to_value().into_raw();
1785 assert_eq!(gobject_ffi::g_type_check_value(&v), ffi::GTRUE);
1786 assert_eq!(gobject_ffi::g_value_get_int(&v), 123);
1787 gobject_ffi::g_value_unset(&mut v);
1788 }
1789 }
1790
1791 #[test]
1792 fn test_debug() {
1793 fn value_debug_string<T: ToValue>(val: T) -> String {
1794 format!("{:?}", val.to_value())
1795 }
1796
1797 assert_eq!(value_debug_string(1u32), "(guint) 1");
1798 assert_eq!(value_debug_string(2i32), "(gint) 2");
1799 assert_eq!(value_debug_string(false), "(gboolean) FALSE");
1800 assert_eq!(value_debug_string("FooBar"), r#"(gchararray) "FooBar""#);
1801 }
1802}