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")]
503 pub struct Value(BoxedInline<gobject_ffi::GValue>);
504
505 match fn {
506 copy => |ptr| copy_value(ptr),
507 free => |ptr| free_value(ptr),
508 init => |ptr| init_value(ptr),
509 copy_into => |dest, src| copy_into_value(dest, src),
510 clear => |ptr| clear_value(ptr),
511 }
512}
513
514impl Value {
515 pub fn from_type(type_: Type) -> Self {
522 unsafe {
523 assert_eq!(
524 gobject_ffi::g_type_check_is_value_type(type_.into_glib()),
525 ffi::GTRUE
526 );
527 Self::from_type_unchecked(type_)
528 }
529 }
530
531 #[inline]
538 pub unsafe fn from_type_unchecked(type_: Type) -> Self {
539 unsafe {
540 let mut value = Value::uninitialized();
541 gobject_ffi::g_value_init(value.to_glib_none_mut().0, type_.into_glib());
542 value
543 }
544 }
545
546 #[inline]
549 pub fn for_value_type<T: ValueType>() -> Self {
550 unsafe { Value::from_type_unchecked(T::Type::static_type()) }
551 }
552
553 #[inline]
556 #[doc(alias = "g_value_set_static_string")]
557 pub fn from_static_str(s: &'static GStr) -> Self {
558 unsafe {
559 let mut v = Self::from_type_unchecked(Type::STRING);
560 gobject_ffi::g_value_set_static_string(v.to_glib_none_mut().0, s.as_ptr());
561 v
562 }
563 }
564
565 #[cfg(feature = "v2_66")]
566 #[cfg_attr(docsrs, doc(cfg(feature = "v2_66")))]
567 #[inline]
571 #[doc(alias = "g_value_set_interned_string")]
572 pub fn from_interned_str(s: &'static GStr) -> Self {
573 unsafe {
574 let mut v = Self::from_type_unchecked(Type::STRING);
575 gobject_ffi::g_value_set_interned_string(v.to_glib_none_mut().0, s.as_ptr());
576 v
577 }
578 }
579
580 #[inline]
585 pub fn get<'a, T>(
586 &'a self,
587 ) -> Result<T, <<T as FromValue<'a>>::Checker as ValueTypeChecker>::Error>
588 where
589 T: FromValue<'a>,
590 {
591 unsafe {
592 T::Checker::check(self)?;
593 Ok(T::from_value(self))
594 }
595 }
596
597 #[inline]
600 pub fn get_owned<T>(&self) -> Result<T, <<T as FromValue>::Checker as ValueTypeChecker>::Error>
601 where
602 T: for<'b> FromValue<'b> + 'static,
603 {
604 unsafe {
605 T::Checker::check(self)?;
606 Ok(FromValue::from_value(self))
607 }
608 }
609
610 #[inline]
614 pub fn is<T: StaticType>(&self) -> bool {
615 self.is_type(T::static_type())
616 }
617
618 #[inline]
622 pub fn is_type(&self, type_: Type) -> bool {
623 self.type_().is_a(type_)
624 }
625
626 #[inline]
629 pub fn type_(&self) -> Type {
630 unsafe { from_glib(self.inner.g_type) }
631 }
632
633 #[doc(alias = "g_value_type_transformable")]
686 pub fn type_transformable(src: Type, dst: Type) -> bool {
687 unsafe {
688 from_glib(gobject_ffi::g_value_type_transformable(
689 src.into_glib(),
690 dst.into_glib(),
691 ))
692 }
693 }
694
695 #[doc(alias = "g_value_transform")]
713 pub fn transform<T: ValueType>(&self) -> Result<Value, crate::BoolError> {
714 self.transform_with_type(T::Type::static_type())
715 }
716
717 #[doc(alias = "g_value_transform")]
720 pub fn transform_with_type(&self, type_: Type) -> Result<Value, crate::BoolError> {
721 unsafe {
722 let mut dest = Value::from_type(type_);
723 if from_glib(gobject_ffi::g_value_transform(
724 self.to_glib_none().0,
725 dest.to_glib_none_mut().0,
726 )) {
727 Ok(dest)
728 } else {
729 Err(crate::bool_error!(
730 "Can't transform value of type '{}' into '{}'",
731 self.type_(),
732 type_
733 ))
734 }
735 }
736 }
737
738 #[inline]
741 pub fn into_raw(self) -> gobject_ffi::GValue {
742 unsafe {
743 let s = mem::ManuallyDrop::new(self);
744 ptr::read(&s.inner)
745 }
746 }
747
748 #[inline]
752 pub fn try_into_send_value<T: Send + StaticType>(self) -> Result<SendValue, Self> {
753 if self.type_().is_a(T::static_type()) {
754 unsafe { Ok(SendValue::unsafe_from(self.into_raw())) }
755 } else {
756 Err(self)
757 }
758 }
759
760 #[inline]
767 pub unsafe fn into_send_value(self) -> SendValue {
768 SendValue::unsafe_from(self.into_raw())
769 }
770
771 fn content_debug_string(&self) -> GString {
772 unsafe { from_glib_full(gobject_ffi::g_strdup_value_contents(self.to_glib_none().0)) }
773 }
774}
775
776impl fmt::Debug for Value {
777 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
778 write!(f, "({}) {}", self.type_(), self.content_debug_string())
779 }
780}
781
782impl<'a, T: ?Sized + ToValue> From<&'a T> for Value {
783 #[inline]
784 fn from(value: &'a T) -> Self {
785 value.to_value()
786 }
787}
788
789impl From<SendValue> for Value {
790 #[inline]
791 fn from(value: SendValue) -> Self {
792 unsafe { Value::unsafe_from(value.into_raw()) }
793 }
794}
795
796impl ToValue for Value {
797 #[inline]
798 fn to_value(&self) -> Value {
799 self.clone()
800 }
801
802 #[inline]
803 fn value_type(&self) -> Type {
804 self.type_()
805 }
806}
807
808impl ToValue for &Value {
809 #[inline]
810 fn to_value(&self) -> Value {
811 (*self).clone()
812 }
813
814 #[inline]
815 fn value_type(&self) -> Type {
816 self.type_()
817 }
818}
819
820pub struct NopChecker;
821
822unsafe impl ValueTypeChecker for NopChecker {
823 type Error = Infallible;
824
825 #[inline]
826 fn check(_value: &Value) -> Result<(), Self::Error> {
827 Ok(())
828 }
829}
830
831unsafe impl<'a> FromValue<'a> for Value {
832 type Checker = NopChecker;
833
834 #[inline]
835 unsafe fn from_value(value: &'a Value) -> Self {
836 value.clone()
837 }
838}
839
840unsafe impl<'a> FromValue<'a> for &'a Value {
841 type Checker = NopChecker;
842
843 #[inline]
844 unsafe fn from_value(value: &'a Value) -> Self {
845 value
846 }
847}
848
849impl ToValue for SendValue {
850 #[inline]
851 fn to_value(&self) -> Value {
852 unsafe { from_glib_none(self.to_glib_none().0) }
853 }
854
855 #[inline]
856 fn value_type(&self) -> Type {
857 self.type_()
858 }
859}
860
861impl ToValue for &SendValue {
862 #[inline]
863 fn to_value(&self) -> Value {
864 unsafe { from_glib_none(self.to_glib_none().0) }
865 }
866
867 #[inline]
868 fn value_type(&self) -> Type {
869 self.type_()
870 }
871}
872
873impl StaticType for BoxedValue {
874 #[inline]
875 fn static_type() -> Type {
876 unsafe { from_glib(gobject_ffi::g_value_get_type()) }
877 }
878}
879
880crate::wrapper! {
881 #[doc(alias = "GValue")]
887 pub struct SendValue(BoxedInline<gobject_ffi::GValue>);
888
889 match fn {
890 copy => |ptr| copy_value(ptr),
891 free => |ptr| free_value(ptr),
892 init => |ptr| init_value(ptr),
893 copy_into => |dest, src| copy_into_value(dest, src),
894 clear => |ptr| clear_value(ptr),
895 }
896}
897
898unsafe impl Send for SendValue {}
899
900impl SendValue {
901 #[inline]
904 pub fn into_raw(self) -> gobject_ffi::GValue {
905 unsafe {
906 let s = mem::ManuallyDrop::new(self);
907 ptr::read(&s.inner)
908 }
909 }
910 #[inline]
911 pub fn from_owned<T: Send + Into<Value>>(t: T) -> Self {
912 unsafe { Self::unsafe_from(t.into().into_raw()) }
913 }
914}
915
916impl fmt::Debug for SendValue {
917 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
918 write!(f, "({}) {}", self.type_(), self.content_debug_string())
919 }
920}
921
922impl Deref for SendValue {
923 type Target = Value;
924
925 #[inline]
926 fn deref(&self) -> &Value {
927 unsafe { &*(self as *const SendValue as *const Value) }
928 }
929}
930
931impl<'a, T: ?Sized + ToSendValue> From<&'a T> for SendValue {
932 #[inline]
933 fn from(value: &'a T) -> Self {
934 value.to_send_value()
935 }
936}
937
938pub trait ToSendValue: Send + ToValue {
941 fn to_send_value(&self) -> SendValue;
944}
945
946impl<T: Send + ToValue + ?Sized> ToSendValue for T {
947 #[inline]
948 fn to_send_value(&self) -> SendValue {
949 unsafe { SendValue::unsafe_from(self.to_value().into_raw()) }
950 }
951}
952
953unsafe impl<'a> FromValue<'a> for &'a str {
954 type Checker = GenericValueTypeOrNoneChecker<Self>;
955
956 #[inline]
957 unsafe fn from_value(value: &'a Value) -> Self {
958 let ptr = gobject_ffi::g_value_get_string(value.to_glib_none().0);
959 CStr::from_ptr(ptr).to_str().expect("Invalid UTF-8")
960 }
961}
962
963impl ToValue for str {
964 fn to_value(&self) -> Value {
965 unsafe {
966 let mut value = Value::for_value_type::<String>();
967
968 gobject_ffi::g_value_take_string(value.to_glib_none_mut().0, self.to_glib_full());
969
970 value
971 }
972 }
973
974 fn value_type(&self) -> Type {
975 String::static_type()
976 }
977}
978
979impl ToValue for &str {
980 fn to_value(&self) -> Value {
981 (*self).to_value()
982 }
983
984 fn value_type(&self) -> Type {
985 String::static_type()
986 }
987}
988
989impl ToValueOptional for str {
990 fn to_value_optional(s: Option<&Self>) -> Value {
991 let mut value = Value::for_value_type::<String>();
992 unsafe {
993 gobject_ffi::g_value_take_string(value.to_glib_none_mut().0, s.to_glib_full());
994 }
995
996 value
997 }
998}
999
1000impl ValueType for String {
1001 type Type = String;
1002}
1003
1004impl ValueTypeOptional for String {}
1005
1006unsafe impl<'a> FromValue<'a> for String {
1007 type Checker = GenericValueTypeOrNoneChecker<Self>;
1008
1009 unsafe fn from_value(value: &'a Value) -> Self {
1010 String::from(<&str>::from_value(value))
1011 }
1012}
1013
1014impl ToValue for String {
1015 fn to_value(&self) -> Value {
1016 <&str>::to_value(&self.as_str())
1017 }
1018
1019 fn value_type(&self) -> Type {
1020 String::static_type()
1021 }
1022}
1023
1024impl From<String> for Value {
1025 #[inline]
1026 fn from(s: String) -> Self {
1027 s.to_value()
1028 }
1029}
1030
1031impl ToValueOptional for String {
1032 fn to_value_optional(s: Option<&Self>) -> Value {
1033 <str>::to_value_optional(s.as_ref().map(|s| s.as_str()))
1034 }
1035}
1036
1037impl ValueType for Box<str> {
1038 type Type = String;
1039}
1040
1041impl ValueTypeOptional for Box<str> {}
1042
1043unsafe impl<'a> FromValue<'a> for Box<str> {
1044 type Checker = GenericValueTypeOrNoneChecker<Self>;
1045
1046 unsafe fn from_value(value: &'a Value) -> Self {
1047 Box::<str>::from(<&str>::from_value(value))
1048 }
1049}
1050
1051impl StaticType for Box<str> {
1052 fn static_type() -> Type {
1053 String::static_type()
1054 }
1055}
1056
1057impl ToValue for Box<str> {
1058 fn to_value(&self) -> Value {
1059 <&str>::to_value(&self.as_ref())
1060 }
1061
1062 fn value_type(&self) -> Type {
1063 String::static_type()
1064 }
1065}
1066
1067impl From<Box<str>> for Value {
1068 #[inline]
1069 fn from(s: Box<str>) -> Self {
1070 s.to_value()
1071 }
1072}
1073
1074impl ToValueOptional for Box<str> {
1075 fn to_value_optional(s: Option<&Self>) -> Value {
1076 <str>::to_value_optional(s.as_ref().map(|s| s.as_ref()))
1077 }
1078}
1079
1080impl ValueType for Vec<String> {
1081 type Type = Vec<String>;
1082}
1083
1084unsafe impl<'a> FromValue<'a> for Vec<String> {
1085 type Checker = GenericValueTypeChecker<Self>;
1086
1087 unsafe fn from_value(value: &'a Value) -> Self {
1088 let ptr = gobject_ffi::g_value_get_boxed(value.to_glib_none().0) as *const *const c_char;
1089 FromGlibPtrContainer::from_glib_none(ptr)
1090 }
1091}
1092
1093impl ToValue for Vec<String> {
1094 fn to_value(&self) -> Value {
1095 unsafe {
1096 let mut value = Value::for_value_type::<Self>();
1097 let ptr: *mut *mut c_char = self.to_glib_full();
1098 gobject_ffi::g_value_take_boxed(value.to_glib_none_mut().0, ptr as *const c_void);
1099 value
1100 }
1101 }
1102
1103 fn value_type(&self) -> Type {
1104 <Vec<String>>::static_type()
1105 }
1106}
1107
1108impl From<Vec<String>> for Value {
1109 #[inline]
1110 fn from(s: Vec<String>) -> Self {
1111 s.to_value()
1112 }
1113}
1114
1115impl ToValue for [&'_ str] {
1116 fn to_value(&self) -> Value {
1117 unsafe {
1118 let mut value = Value::for_value_type::<Vec<String>>();
1119 let ptr: *mut *mut c_char = self.to_glib_full();
1120 gobject_ffi::g_value_take_boxed(value.to_glib_none_mut().0, ptr as *const c_void);
1121 value
1122 }
1123 }
1124
1125 fn value_type(&self) -> Type {
1126 <Vec<String>>::static_type()
1127 }
1128}
1129
1130impl ToValue for &'_ [&'_ str] {
1131 fn to_value(&self) -> Value {
1132 unsafe {
1133 let mut value = Value::for_value_type::<Vec<String>>();
1134 let ptr: *mut *mut c_char = self.to_glib_full();
1135 gobject_ffi::g_value_take_boxed(value.to_glib_none_mut().0, ptr as *const c_void);
1136 value
1137 }
1138 }
1139
1140 fn value_type(&self) -> Type {
1141 <Vec<String>>::static_type()
1142 }
1143}
1144
1145impl ToValue for Path {
1146 fn to_value(&self) -> Value {
1147 unsafe {
1148 let mut value = Value::for_value_type::<PathBuf>();
1149
1150 gobject_ffi::g_value_take_string(value.to_glib_none_mut().0, self.to_glib_full());
1151
1152 value
1153 }
1154 }
1155
1156 fn value_type(&self) -> Type {
1157 PathBuf::static_type()
1158 }
1159}
1160
1161impl ToValue for &Path {
1162 fn to_value(&self) -> Value {
1163 (*self).to_value()
1164 }
1165
1166 fn value_type(&self) -> Type {
1167 PathBuf::static_type()
1168 }
1169}
1170
1171impl ToValueOptional for Path {
1172 fn to_value_optional(s: Option<&Self>) -> Value {
1173 let mut value = Value::for_value_type::<PathBuf>();
1174 unsafe {
1175 gobject_ffi::g_value_take_string(value.to_glib_none_mut().0, s.to_glib_full());
1176 }
1177
1178 value
1179 }
1180}
1181
1182impl ValueType for PathBuf {
1183 type Type = PathBuf;
1184}
1185
1186impl ValueTypeOptional for PathBuf {}
1187
1188unsafe impl<'a> FromValue<'a> for PathBuf {
1189 type Checker = GenericValueTypeOrNoneChecker<Self>;
1190
1191 unsafe fn from_value(value: &'a Value) -> Self {
1192 from_glib_none(gobject_ffi::g_value_get_string(value.to_glib_none().0))
1193 }
1194}
1195
1196impl ToValue for PathBuf {
1197 fn to_value(&self) -> Value {
1198 <&Path>::to_value(&self.as_path())
1199 }
1200
1201 fn value_type(&self) -> Type {
1202 PathBuf::static_type()
1203 }
1204}
1205
1206impl From<PathBuf> for Value {
1207 #[inline]
1208 fn from(s: PathBuf) -> Self {
1209 s.to_value()
1210 }
1211}
1212
1213impl ToValueOptional for PathBuf {
1214 fn to_value_optional(s: Option<&Self>) -> Value {
1215 <Path>::to_value_optional(s.as_ref().map(|s| s.as_path()))
1216 }
1217}
1218
1219impl ValueType for bool {
1220 type Type = Self;
1221}
1222
1223unsafe impl<'a> FromValue<'a> for bool {
1224 type Checker = GenericValueTypeChecker<Self>;
1225
1226 #[inline]
1227 unsafe fn from_value(value: &'a Value) -> Self {
1228 from_glib(gobject_ffi::g_value_get_boolean(value.to_glib_none().0))
1229 }
1230}
1231
1232impl ToValue for bool {
1233 #[inline]
1234 fn to_value(&self) -> Value {
1235 let mut value = Value::for_value_type::<Self>();
1236 unsafe {
1237 gobject_ffi::g_value_set_boolean(&mut value.inner, self.into_glib());
1238 }
1239 value
1240 }
1241
1242 #[inline]
1243 fn value_type(&self) -> Type {
1244 Self::static_type()
1245 }
1246}
1247
1248impl From<bool> for Value {
1249 #[inline]
1250 fn from(v: bool) -> Self {
1251 v.to_value()
1252 }
1253}
1254
1255impl ValueType for Pointer {
1256 type Type = Self;
1257}
1258
1259unsafe impl<'a> FromValue<'a> for Pointer {
1260 type Checker = GenericValueTypeChecker<Self>;
1261
1262 #[inline]
1263 unsafe fn from_value(value: &'a Value) -> Self {
1264 gobject_ffi::g_value_get_pointer(value.to_glib_none().0)
1265 }
1266}
1267
1268impl ToValue for Pointer {
1269 #[inline]
1270 fn to_value(&self) -> Value {
1271 let mut value = Value::for_value_type::<Self>();
1272 unsafe {
1273 gobject_ffi::g_value_set_pointer(&mut value.inner, *self);
1274 }
1275 value
1276 }
1277
1278 #[inline]
1279 fn value_type(&self) -> Type {
1280 <<Self as ValueType>::Type as StaticType>::static_type()
1281 }
1282}
1283
1284impl From<Pointer> for Value {
1285 #[inline]
1286 fn from(v: Pointer) -> Self {
1287 v.to_value()
1288 }
1289}
1290
1291impl ValueType for ptr::NonNull<Pointee> {
1292 type Type = Pointer;
1293}
1294
1295unsafe impl<'a> FromValue<'a> for ptr::NonNull<Pointee> {
1296 type Checker = GenericValueTypeOrNoneChecker<Self>;
1297
1298 #[inline]
1299 unsafe fn from_value(value: &'a Value) -> Self {
1300 ptr::NonNull::new_unchecked(Pointer::from_value(value))
1301 }
1302}
1303
1304impl ToValue for ptr::NonNull<Pointee> {
1305 #[inline]
1306 fn to_value(&self) -> Value {
1307 self.as_ptr().to_value()
1308 }
1309
1310 #[inline]
1311 fn value_type(&self) -> Type {
1312 <<Self as ValueType>::Type as StaticType>::static_type()
1313 }
1314}
1315
1316impl From<ptr::NonNull<Pointee>> for Value {
1317 #[inline]
1318 fn from(v: ptr::NonNull<Pointee>) -> Self {
1319 v.to_value()
1320 }
1321}
1322
1323impl ToValueOptional for ptr::NonNull<Pointee> {
1324 #[inline]
1325 fn to_value_optional(p: Option<&Self>) -> Value {
1326 p.map(|p| p.as_ptr()).unwrap_or(ptr::null_mut()).to_value()
1327 }
1328}
1329
1330macro_rules! numeric {
1331 ($name:ty, $get:expr, $set:expr) => {
1332 impl ValueType for $name {
1333 type Type = Self;
1334 }
1335
1336 unsafe impl<'a> FromValue<'a> for $name {
1337 type Checker = GenericValueTypeChecker<Self>;
1338
1339 #[inline]
1340 #[allow(clippy::redundant_closure_call)]
1341 unsafe fn from_value(value: &'a Value) -> Self {
1342 $get(value.to_glib_none().0)
1343 }
1344 }
1345
1346 impl ToValue for $name {
1347 #[inline]
1348 #[allow(clippy::redundant_closure_call)]
1349 fn to_value(&self) -> Value {
1350 let mut value = Value::for_value_type::<Self>();
1351 unsafe {
1352 $set(&mut value.inner, *self);
1353 }
1354 value
1355 }
1356
1357 #[inline]
1358 fn value_type(&self) -> Type {
1359 Self::static_type()
1360 }
1361 }
1362
1363 impl From<$name> for Value {
1364 #[inline]
1365 fn from(v: $name) -> Self {
1366 v.to_value()
1367 }
1368 }
1369 };
1370}
1371macro_rules! not_zero {
1372 ($name:ty, $num:ty) => {
1373 impl ValueType for $name {
1374 type Type = $name;
1375 }
1376
1377 unsafe impl<'a> FromValue<'a> for $name {
1378 type Checker = GenericValueTypeOrNoneChecker<Self>;
1381
1382 #[inline]
1383 unsafe fn from_value(value: &'a Value) -> Self {
1384 let res = <$num>::from_value(value);
1385 Self::try_from(res).unwrap()
1386 }
1387 }
1388
1389 impl ToValue for $name {
1390 #[inline]
1391 fn to_value(&self) -> Value {
1392 <$num>::to_value(&<$num>::from(*self))
1393 }
1394
1395 #[inline]
1396 fn value_type(&self) -> Type {
1397 Self::static_type()
1398 }
1399 }
1400
1401 impl From<$name> for Value {
1402 #[inline]
1403 fn from(v: $name) -> Self {
1404 v.to_value()
1405 }
1406 }
1407
1408 impl ToValueOptional for $name {
1409 fn to_value_optional(s: Option<&Self>) -> Value {
1410 match s {
1411 Some(x) => x.to_value(),
1412 None => <$num>::to_value(&0),
1413 }
1414 }
1415 }
1416 };
1417}
1418
1419numeric!(
1420 i8,
1421 gobject_ffi::g_value_get_schar,
1422 gobject_ffi::g_value_set_schar
1423);
1424not_zero!(NonZeroI8, i8);
1425numeric!(
1426 u8,
1427 gobject_ffi::g_value_get_uchar,
1428 gobject_ffi::g_value_set_uchar
1429);
1430not_zero!(NonZeroU8, u8);
1431numeric!(
1432 i32,
1433 gobject_ffi::g_value_get_int,
1434 gobject_ffi::g_value_set_int
1435);
1436not_zero!(NonZeroI32, i32);
1437numeric!(
1438 u32,
1439 gobject_ffi::g_value_get_uint,
1440 gobject_ffi::g_value_set_uint
1441);
1442not_zero!(NonZeroU32, u32);
1443numeric!(
1444 i64,
1445 gobject_ffi::g_value_get_int64,
1446 gobject_ffi::g_value_set_int64
1447);
1448not_zero!(NonZeroI64, i64);
1449numeric!(
1450 u64,
1451 gobject_ffi::g_value_get_uint64,
1452 gobject_ffi::g_value_set_uint64
1453);
1454not_zero!(NonZeroU64, u64);
1455numeric!(
1456 crate::ILong,
1457 |v| gobject_ffi::g_value_get_long(v).into(),
1458 |v, i: crate::ILong| gobject_ffi::g_value_set_long(v, i.0)
1459);
1460numeric!(
1461 crate::ULong,
1462 |v| gobject_ffi::g_value_get_ulong(v).into(),
1463 |v, i: crate::ULong| gobject_ffi::g_value_set_ulong(v, i.0)
1464);
1465numeric!(
1466 f32,
1467 gobject_ffi::g_value_get_float,
1468 gobject_ffi::g_value_set_float
1469);
1470numeric!(
1471 f64,
1472 gobject_ffi::g_value_get_double,
1473 gobject_ffi::g_value_set_double
1474);
1475
1476impl ValueType for char {
1477 type Type = u32;
1478}
1479
1480unsafe impl<'a> FromValue<'a> for char {
1481 type Checker = CharTypeChecker;
1482
1483 #[inline]
1484 unsafe fn from_value(value: &'a Value) -> Self {
1485 let res: u32 = gobject_ffi::g_value_get_uint(value.to_glib_none().0);
1486 char::from_u32_unchecked(res)
1488 }
1489}
1490
1491impl ToValue for char {
1492 #[inline]
1493 fn to_value(&self) -> Value {
1494 let mut value = Value::for_value_type::<Self>();
1495 unsafe {
1496 gobject_ffi::g_value_set_uint(&mut value.inner, *self as u32);
1497 }
1498 value
1499 }
1500
1501 #[inline]
1502 fn value_type(&self) -> Type {
1503 crate::Type::U32
1504 }
1505}
1506
1507impl From<char> for Value {
1508 #[inline]
1509 fn from(v: char) -> Self {
1510 v.to_value()
1511 }
1512}
1513
1514pub struct BoxedValue(pub Value);
1517
1518impl Deref for BoxedValue {
1519 type Target = Value;
1520
1521 #[inline]
1522 fn deref(&self) -> &Value {
1523 &self.0
1524 }
1525}
1526
1527impl ValueType for BoxedValue {
1528 type Type = BoxedValue;
1529}
1530
1531impl ValueTypeOptional for BoxedValue {}
1532
1533unsafe impl<'a> FromValue<'a> for BoxedValue {
1534 type Checker = GenericValueTypeOrNoneChecker<Self>;
1535
1536 #[inline]
1537 unsafe fn from_value(value: &'a Value) -> Self {
1538 let ptr = gobject_ffi::g_value_get_boxed(value.to_glib_none().0);
1539 BoxedValue(from_glib_none(ptr as *const gobject_ffi::GValue))
1540 }
1541}
1542
1543impl ToValue for BoxedValue {
1544 #[inline]
1545 fn to_value(&self) -> Value {
1546 unsafe {
1547 let mut value = Value::for_value_type::<BoxedValue>();
1548
1549 gobject_ffi::g_value_set_boxed(
1550 value.to_glib_none_mut().0,
1551 self.0.to_glib_none().0 as ffi::gconstpointer,
1552 );
1553
1554 value
1555 }
1556 }
1557
1558 #[inline]
1559 fn value_type(&self) -> Type {
1560 BoxedValue::static_type()
1561 }
1562}
1563
1564impl From<BoxedValue> for Value {
1565 #[inline]
1566 fn from(v: BoxedValue) -> Self {
1567 unsafe {
1568 let mut value = Value::for_value_type::<BoxedValue>();
1569
1570 gobject_ffi::g_value_take_boxed(
1571 value.to_glib_none_mut().0,
1572 v.0.to_glib_full() as ffi::gconstpointer,
1573 );
1574
1575 value
1576 }
1577 }
1578}
1579
1580impl ToValueOptional for BoxedValue {
1581 #[inline]
1582 fn to_value_optional(s: Option<&Self>) -> Value {
1583 let mut value = Value::for_value_type::<Self>();
1584 unsafe {
1585 gobject_ffi::g_value_set_boxed(
1586 value.to_glib_none_mut().0,
1587 s.map(|s| &s.0).to_glib_none().0 as ffi::gconstpointer,
1588 );
1589 }
1590
1591 value
1592 }
1593}
1594
1595#[cfg(test)]
1596mod tests {
1597 use std::num::NonZeroI32;
1598
1599 use super::*;
1600
1601 #[test]
1602 fn test_send_value() {
1603 use std::thread;
1604
1605 let v = SendValue::from(&1i32);
1606
1607 thread::spawn(move || drop(v)).join().unwrap();
1609 }
1610
1611 #[test]
1612 fn test_strv() {
1613 let v = ["123", "456"].to_value();
1614 assert_eq!(
1615 v.get::<Vec<GString>>(),
1616 Ok(vec![GString::from("123"), GString::from("456")])
1617 );
1618
1619 let v = vec![String::from("123"), String::from("456")].to_value();
1620 assert_eq!(
1621 v.get::<Vec<GString>>(),
1622 Ok(vec![GString::from("123"), GString::from("456")])
1623 );
1624 }
1625
1626 #[test]
1627 fn test_from_to_value() {
1628 let v = 123.to_value();
1629 assert_eq!(v.get(), Ok(123));
1630 assert_eq!(
1631 v.get::<&str>(),
1632 Err(ValueTypeMismatchError::new(Type::I32, Type::STRING).into())
1633 );
1634 assert_eq!(
1635 v.get::<bool>(),
1636 Err(ValueTypeMismatchError::new(Type::I32, Type::BOOL))
1637 );
1638
1639 let v_str = "test".to_value();
1641 assert_eq!(v_str.get::<&str>(), Ok("test"));
1642 assert_eq!(v_str.get::<Option<&str>>(), Ok(Some("test")));
1643 assert_eq!(
1644 v_str.get::<i32>(),
1645 Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1646 );
1647
1648 let some_v = Some("test").to_value();
1649 assert_eq!(some_v.get::<&str>(), Ok("test"));
1650 assert_eq!(some_v.get_owned::<String>(), Ok("test".to_string()));
1651 assert_eq!(
1652 some_v.get_owned::<Option<String>>(),
1653 Ok(Some("test".to_string()))
1654 );
1655 assert_eq!(some_v.get::<Option<&str>>(), Ok(Some("test")));
1656 assert_eq!(
1657 some_v.get::<i32>(),
1658 Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1659 );
1660
1661 let none_str: Option<&str> = None;
1662 let none_v = none_str.to_value();
1663 assert_eq!(none_v.get::<Option<&str>>(), Ok(None));
1664 assert_eq!(
1665 none_v.get::<i32>(),
1666 Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1667 );
1668
1669 let v_str = String::from("test").to_value();
1671 assert_eq!(v_str.get::<String>(), Ok(String::from("test")));
1672 assert_eq!(
1673 v_str.get::<Option<String>>(),
1674 Ok(Some(String::from("test")))
1675 );
1676 assert_eq!(
1677 v_str.get::<i32>(),
1678 Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1679 );
1680
1681 let some_v = Some(String::from("test")).to_value();
1682 assert_eq!(some_v.get::<String>(), Ok(String::from("test")));
1683 assert_eq!(
1684 some_v.get::<Option<String>>(),
1685 Ok(Some(String::from("test")))
1686 );
1687 assert_eq!(
1688 some_v.get::<i32>(),
1689 Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1690 );
1691
1692 let none_str: Option<String> = None;
1693 let none_v = none_str.to_value();
1694 assert_eq!(none_v.get::<Option<String>>(), Ok(None));
1695 assert_eq!(
1696 none_v.get::<i32>(),
1697 Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1698 );
1699
1700 let c_v = 'c'.to_value();
1701 assert_eq!(c_v.get::<char>(), Ok('c'));
1702
1703 let c_v = 0xFFFFFFFFu32.to_value();
1704 assert_eq!(
1705 c_v.get::<char>(),
1706 Err(InvalidCharError::CharConversionError)
1707 );
1708
1709 let v_str = String::from("test").to_value();
1711 assert_eq!(v_str.get::<String>(), Ok(String::from("test")));
1712 assert_eq!(
1713 v_str.get::<Option<String>>(),
1714 Ok(Some(String::from("test")))
1715 );
1716 assert_eq!(
1717 v_str.get::<i32>(),
1718 Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1719 );
1720
1721 let some_v = Some(&String::from("test")).to_value();
1722 assert_eq!(some_v.get::<String>(), Ok(String::from("test")));
1723 assert_eq!(
1724 some_v.get::<Option<String>>(),
1725 Ok(Some(String::from("test")))
1726 );
1727 assert_eq!(
1728 some_v.get::<i32>(),
1729 Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1730 );
1731
1732 let none_str: Option<&String> = None;
1733 let none_v = none_str.to_value();
1734 assert_eq!(none_v.get::<Option<String>>(), Ok(None));
1735 assert_eq!(
1736 none_v.get::<i32>(),
1737 Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1738 );
1739
1740 let v = NonZeroI32::new(123).unwrap().to_value();
1742 assert_eq!(v.get::<NonZeroI32>(), Ok(NonZeroI32::new(123).unwrap()));
1743
1744 let v = 123i32.to_value();
1745 assert_eq!(v.get::<NonZeroI32>(), Ok(NonZeroI32::new(123).unwrap()));
1746
1747 let v = 0i32.to_value();
1748 assert_eq!(
1749 v.get::<NonZeroI32>(),
1750 Err(ValueTypeMismatchOrNoneError::UnexpectedNone)
1751 );
1752
1753 assert_eq!(v.get::<Option<NonZeroI32>>(), Ok(None));
1754 }
1755
1756 #[test]
1757 fn test_transform() {
1758 let v = 123.to_value();
1759 let v2 = v
1760 .transform::<String>()
1761 .expect("Failed to transform to string");
1762 assert_eq!(v2.get::<&str>(), Ok("123"));
1763 }
1764
1765 #[test]
1766 fn test_into_raw() {
1767 unsafe {
1768 let mut v = 123.to_value().into_raw();
1769 assert_eq!(gobject_ffi::g_type_check_value(&v), ffi::GTRUE);
1770 assert_eq!(gobject_ffi::g_value_get_int(&v), 123);
1771 gobject_ffi::g_value_unset(&mut v);
1772 }
1773 }
1774
1775 #[test]
1776 fn test_debug() {
1777 fn value_debug_string<T: ToValue>(val: T) -> String {
1778 format!("{:?}", val.to_value())
1779 }
1780
1781 assert_eq!(value_debug_string(1u32), "(guint) 1");
1782 assert_eq!(value_debug_string(2i32), "(gint) 2");
1783 assert_eq!(value_debug_string(false), "(gboolean) FALSE");
1784 assert_eq!(value_debug_string("FooBar"), r#"(gchararray) "FooBar""#);
1785 }
1786}