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