glib/
value.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3// rustdoc-stripper-ignore-next
4//! `Value` binding and helper traits.
5//!
6//! The type of a [`Value`](struct.Value.html) is dynamic in that it generally
7//! isn't known at compile time but once created a `Value` can't change its
8//! type.
9//!
10//! [`SendValue`](struct.SendValue.html) is a version of [`Value`](struct.Value.html)
11//! that can only store types that implement `Send` and as such implements `Send` itself. It
12//! dereferences to `Value` so it can be used everywhere `Value` references are accepted.
13//!
14//! Supported types are `bool`, `i8`, `u8`, `i32`, `u32`, `i64`, `u64`, `f32`,
15//! `f64`, `String` and objects (`T: IsA<Object>`).
16//!
17//! # Examples
18//!
19//! ```
20//! use glib::prelude::*; // or `use gtk::prelude::*;`
21//! use glib::Value;
22//!
23//! // Value implement From<&i32>, From<&str> and From<Option<&str>>.
24//! // Another option is the `ToValue` trait.
25//! let mut num = 10.to_value();
26//! let mut hello = Value::from("Hello!");
27//! let none: Option<&str> = None;
28//! let str_none = none.to_value();
29//!
30//! // `is` tests the type of the value.
31//! assert!(num.is::<i32>());
32//! assert!(hello.is::<String>());
33//!
34//! // `get` tries to get an optional value of the specified type
35//! // and returns an `Err` if the type doesn't match.
36//! assert_eq!(num.get(), Ok(10));
37//! assert!(num.get::<String>().is_err());
38//! assert_eq!(hello.get(), Ok(String::from("Hello!")));
39//! assert_eq!(hello.get::<String>(), Ok(String::from("Hello!")));
40//! assert_eq!(str_none.get::<Option<String>>(), Ok(None));
41//! ```
42
43use 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
65// rustdoc-stripper-ignore-next
66/// A type that can be stored in `Value`s.
67pub trait ValueType: ToValue + for<'a> FromValue<'a> + 'static {
68    // rustdoc-stripper-ignore-next
69    /// Type to get the `Type` from.
70    ///
71    /// This exists only for handling optional types.
72    // FIXME: Should default to Self once associated type defaults are stabilized
73    // https://github.com/rust-lang/rust/issues/29661
74    type Type: StaticType;
75}
76
77// rustdoc-stripper-ignore-next
78/// A type that can be stored in `Value`s and is optional.
79///
80/// These are types were storing an `Option` is valid. Examples are `String` and all object types.
81pub 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
95// rustdoc-stripper-ignore-next
96/// Trait for `Value` type checkers.
97pub unsafe trait ValueTypeChecker {
98    type Error: error::Error + Send + Sized + 'static;
99
100    fn check(value: &Value) -> Result<(), Self::Error>;
101}
102
103// rustdoc-stripper-ignore-next
104/// An error returned from the [`get`](struct.Value.html#method.get) function
105/// on a [`Value`](struct.Value.html) for non-optional types an `Option`.
106#[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
147// rustdoc-stripper-ignore-next
148/// Generic `Value` type checker for types.
149pub 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// rustdoc-stripper-ignore-next
187/// An error returned from the [`get`](struct.Value.html#method.get) function
188/// on a [`Value`](struct.Value.html) for char (which are internally u32) types.
189#[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// rustdoc-stripper-ignore-next
219/// An error returned from the [`get`](struct.Value.html#method.get)
220/// function on a [`Value`](struct.Value.html) for optional types.
221#[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
244// rustdoc-stripper-ignore-next
245/// Generic `Value` type checker for optional types.
246pub 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            // Values are always zero-initialized so even if pointers are only 32 bits then the
257            // whole 64 bit value will be 0 for NULL pointers.
258            if value.inner.data[0].v_uint64 == 0 {
259                return Err(Self::Error::UnexpectedNone);
260            }
261        }
262
263        Ok(())
264    }
265}
266
267// rustdoc-stripper-ignore-next
268/// Trait to retrieve the contained value from a `Value`.
269///
270/// Usually this would not be used directly but from the [`get`](struct.Value.html#method.get)
271/// function on a [`Value`](struct.Value.html)
272pub unsafe trait FromValue<'a>: Sized {
273    // rustdoc-stripper-ignore-next
274    /// Value type checker.
275    type Checker: ValueTypeChecker;
276
277    // rustdoc-stripper-ignore-next
278    /// Get the contained value from a `Value`.
279    ///
280    /// # Safety
281    /// `Self::Checker::check()` must be called first and must not fail.
282    unsafe fn from_value(value: &'a Value) -> Self;
283}
284
285// rustdoc-stripper-ignore-next
286/// Trait for types that implement `FromValue` and are Optional.
287///
288/// This trait is auto-implemented for the appropriate types and is sealed.
289pub 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
311// rustdoc-stripper-ignore-next
312/// Wrapped `Value` type checker for optional types.
313pub 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
333// rustdoc-stripper-ignore-next
334/// Blanket implementation for all optional types.
335unsafe 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                // This should've been caught by the caller already.
349                unreachable!();
350            }
351            Ok(_) => Some(T::from_value(value)),
352        }
353    }
354}
355
356// rustdoc-stripper-ignore-next
357/// Trait to convert a value to a `Value`.
358///
359/// Similar to other common conversion traits, the following invariants are guaranteed:
360///
361/// - **Invertibility**: `x.to_value().get().unwrap() == x`. In words, [`FromValue`] is the inverse of `ToValue`.
362/// - **Idempotence**: `x.to_value() == x.to_value().to_value()`.
363///   In words, applying `ToValue` multiple times yields the same result as applying it once.
364///   Idempotence also applies the other way around: `value.get::<Value>()` is a no-op.
365///
366/// There is also the possibility to wrap values within values, see [`BoxedValue`]. All (un-)boxing needs to be done
367/// manually, and will be preserved under the conversion methods.
368///
369/// The conversion methods may cause values to be cloned, which may result in reference counter changes or heap allocations depending
370/// on the source and target type.
371pub trait ToValue {
372    // rustdoc-stripper-ignore-next
373    /// Convert a value to a `Value`.
374    fn to_value(&self) -> Value;
375
376    // rustdoc-stripper-ignore-next
377    /// Returns the type identifier of `self`.
378    ///
379    /// This is the type of the value to be returned by `to_value`.
380    fn value_type(&self) -> Type;
381}
382
383// rustdoc-stripper-ignore-next
384/// Blanket implementation for all references.
385impl<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
397// rustdoc-stripper-ignore-next
398/// Trait to convert an `Option` to a `Value` for optional types.
399pub trait ToValueOptional {
400    // rustdoc-stripper-ignore-next
401    /// Convert an `Option` to a `Value`.
402    #[allow(clippy::wrong_self_convention)]
403    fn to_value_optional(s: Option<&Self>) -> Value;
404}
405
406// rustdoc-stripper-ignore-next
407/// Blanket implementation for all optional types.
408impl<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    // Before GLib 2.48, unsetting a zeroed GValue would give critical warnings
471    // https://bugzilla.gnome.org/show_bug.cgi?id=755766
472    if (*value).g_type != gobject_ffi::G_TYPE_INVALID {
473        gobject_ffi::g_value_unset(value);
474    }
475}
476
477// TODO: Should use impl !Send for Value {} once stable
478crate::wrapper! {
479    // rustdoc-stripper-ignore-next
480    /// A generic value capable of carrying various types.
481    ///
482    /// Once created the type of the value can't be changed.
483    ///
484    /// Some types (e.g. `String` and objects) support `None` values while others
485    /// (e.g. numeric types) don't.
486    ///
487    /// `Value` does not implement the `Send` trait, but [`SendValue`](struct.SendValue.html) can be
488    /// used instead.
489    ///
490    /// See the [module documentation](index.html) for more details.
491    #[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    // rustdoc-stripper-ignore-next
505    /// Creates a new `Value` that is initialized with `type_`.
506    ///
507    /// # Panics
508    ///
509    /// If `type_` can't be stored in a `Value` this function panics.
510    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    // rustdoc-stripper-ignore-next
521    /// Creates a new `Value` that is initialized with `type_`.
522    ///
523    /// # SAFETY
524    ///
525    /// This must be called with a valid `type_` that can be stored in `Value`s.
526    #[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    // rustdoc-stripper-ignore-next
536    /// Creates a new `Value` that is initialized for a given `ValueType`.
537    #[inline]
538    pub fn for_value_type<T: ValueType>() -> Self {
539        unsafe { Value::from_type_unchecked(T::Type::static_type()) }
540    }
541
542    // rustdoc-stripper-ignore-next
543    /// Creates a new `String`-typed `Value` from a `'static` string.
544    #[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    // rustdoc-stripper-ignore-next
557    /// Creates a new `String`-typed `Value` from a `'static` string that is also assumed to be
558    /// interned.
559    #[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    // rustdoc-stripper-ignore-next
570    /// Tries to get a value of type `T`.
571    ///
572    /// Returns `Ok` if the type is correct.
573    #[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    // rustdoc-stripper-ignore-next
587    /// Tries to get a value of an owned type `T`.
588    #[inline]
589    pub fn get_owned<T>(&self) -> Result<T, <<T as FromValue>::Checker as ValueTypeChecker>::Error>
590    where
591        T: for<'b> FromValue<'b> + 'static,
592    {
593        unsafe {
594            T::Checker::check(self)?;
595            Ok(FromValue::from_value(self))
596        }
597    }
598
599    // rustdoc-stripper-ignore-next
600    /// Returns `true` if the type of the value corresponds to `T`
601    /// or is a sub-type of `T`.
602    #[inline]
603    pub fn is<T: StaticType>(&self) -> bool {
604        self.is_type(T::static_type())
605    }
606
607    // rustdoc-stripper-ignore-next
608    /// Returns `true` if the type of the value corresponds to `type_`
609    /// or is a sub-type of `type_`.
610    #[inline]
611    pub fn is_type(&self, type_: Type) -> bool {
612        self.type_().is_a(type_)
613    }
614
615    // rustdoc-stripper-ignore-next
616    /// Returns the type of the value.
617    #[inline]
618    pub fn type_(&self) -> Type {
619        unsafe { from_glib(self.inner.g_type) }
620    }
621
622    // rustdoc-stripper-ignore-next
623    /// Returns whether `Value`s of type `src` can be transformed to type `dst`.
624    #[doc(alias = "g_value_type_transformable")]
625    pub fn type_transformable(src: Type, dst: Type) -> bool {
626        unsafe {
627            from_glib(gobject_ffi::g_value_type_transformable(
628                src.into_glib(),
629                dst.into_glib(),
630            ))
631        }
632    }
633
634    // rustdoc-stripper-ignore-next
635    /// Tries to transform the value into a value of the target type
636    #[doc(alias = "g_value_transform")]
637    pub fn transform<T: ValueType>(&self) -> Result<Value, crate::BoolError> {
638        self.transform_with_type(T::Type::static_type())
639    }
640
641    // rustdoc-stripper-ignore-next
642    /// Tries to transform the value into a value of the target type
643    #[doc(alias = "g_value_transform")]
644    pub fn transform_with_type(&self, type_: Type) -> Result<Value, crate::BoolError> {
645        unsafe {
646            let mut dest = Value::from_type(type_);
647            if from_glib(gobject_ffi::g_value_transform(
648                self.to_glib_none().0,
649                dest.to_glib_none_mut().0,
650            )) {
651                Ok(dest)
652            } else {
653                Err(crate::bool_error!(
654                    "Can't transform value of type '{}' into '{}'",
655                    self.type_(),
656                    type_
657                ))
658            }
659        }
660    }
661
662    // rustdoc-stripper-ignore-next
663    /// Consumes `Value` and returns the corresponding `GValue`.
664    #[inline]
665    pub fn into_raw(self) -> gobject_ffi::GValue {
666        unsafe {
667            let s = mem::ManuallyDrop::new(self);
668            ptr::read(&s.inner)
669        }
670    }
671
672    // rustdoc-stripper-ignore-next
673    /// Converts a `Value` into a `SendValue`. This fails if `self` does not store a value of type
674    /// `T`. It is required for `T` to be `Send` to call this function.
675    #[inline]
676    pub fn try_into_send_value<T: Send + StaticType>(self) -> Result<SendValue, Self> {
677        if self.type_().is_a(T::static_type()) {
678            unsafe { Ok(SendValue::unsafe_from(self.into_raw())) }
679        } else {
680            Err(self)
681        }
682    }
683
684    // rustdoc-stripper-ignore-next
685    /// Converts a `Value` into a `SendValue`.
686    ///
687    /// # Safety
688    ///
689    /// The type of the value contained in `self` must be `Send`.
690    #[inline]
691    pub unsafe fn into_send_value(self) -> SendValue {
692        SendValue::unsafe_from(self.into_raw())
693    }
694
695    fn content_debug_string(&self) -> GString {
696        unsafe { from_glib_full(gobject_ffi::g_strdup_value_contents(self.to_glib_none().0)) }
697    }
698}
699
700impl fmt::Debug for Value {
701    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
702        write!(f, "({}) {}", self.type_(), self.content_debug_string())
703    }
704}
705
706impl<'a, T: ?Sized + ToValue> From<&'a T> for Value {
707    #[inline]
708    fn from(value: &'a T) -> Self {
709        value.to_value()
710    }
711}
712
713impl From<SendValue> for Value {
714    #[inline]
715    fn from(value: SendValue) -> Self {
716        unsafe { Value::unsafe_from(value.into_raw()) }
717    }
718}
719
720impl ToValue for Value {
721    #[inline]
722    fn to_value(&self) -> Value {
723        self.clone()
724    }
725
726    #[inline]
727    fn value_type(&self) -> Type {
728        self.type_()
729    }
730}
731
732impl ToValue for &Value {
733    #[inline]
734    fn to_value(&self) -> Value {
735        (*self).clone()
736    }
737
738    #[inline]
739    fn value_type(&self) -> Type {
740        self.type_()
741    }
742}
743
744pub struct NopChecker;
745
746unsafe impl ValueTypeChecker for NopChecker {
747    type Error = Infallible;
748
749    #[inline]
750    fn check(_value: &Value) -> Result<(), Self::Error> {
751        Ok(())
752    }
753}
754
755unsafe impl<'a> FromValue<'a> for Value {
756    type Checker = NopChecker;
757
758    #[inline]
759    unsafe fn from_value(value: &'a Value) -> Self {
760        value.clone()
761    }
762}
763
764unsafe impl<'a> FromValue<'a> for &'a Value {
765    type Checker = NopChecker;
766
767    #[inline]
768    unsafe fn from_value(value: &'a Value) -> Self {
769        value
770    }
771}
772
773impl ToValue for SendValue {
774    #[inline]
775    fn to_value(&self) -> Value {
776        unsafe { from_glib_none(self.to_glib_none().0) }
777    }
778
779    #[inline]
780    fn value_type(&self) -> Type {
781        self.type_()
782    }
783}
784
785impl ToValue for &SendValue {
786    #[inline]
787    fn to_value(&self) -> Value {
788        unsafe { from_glib_none(self.to_glib_none().0) }
789    }
790
791    #[inline]
792    fn value_type(&self) -> Type {
793        self.type_()
794    }
795}
796
797impl StaticType for BoxedValue {
798    #[inline]
799    fn static_type() -> Type {
800        unsafe { from_glib(gobject_ffi::g_value_get_type()) }
801    }
802}
803
804crate::wrapper! {
805    // rustdoc-stripper-ignore-next
806    /// A version of [`Value`](struct.Value.html) for storing `Send` types, that implements Send
807    /// itself.
808    ///
809    /// See the [module documentation](index.html) for more details.
810    #[doc(alias = "GValue")]
811    pub struct SendValue(BoxedInline<gobject_ffi::GValue>);
812
813    match fn {
814        copy => |ptr| copy_value(ptr),
815        free => |ptr| free_value(ptr),
816        init => |ptr| init_value(ptr),
817        copy_into => |dest, src| copy_into_value(dest, src),
818        clear => |ptr| clear_value(ptr),
819    }
820}
821
822unsafe impl Send for SendValue {}
823
824impl SendValue {
825    // rustdoc-stripper-ignore-next
826    /// Consumes `SendValue` and returns the corresponding `GValue`.
827    #[inline]
828    pub fn into_raw(self) -> gobject_ffi::GValue {
829        unsafe {
830            let s = mem::ManuallyDrop::new(self);
831            ptr::read(&s.inner)
832        }
833    }
834    #[inline]
835    pub fn from_owned<T: Send + Into<Value>>(t: T) -> Self {
836        unsafe { Self::unsafe_from(t.into().into_raw()) }
837    }
838}
839
840impl fmt::Debug for SendValue {
841    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
842        write!(f, "({}) {}", self.type_(), self.content_debug_string())
843    }
844}
845
846impl Deref for SendValue {
847    type Target = Value;
848
849    #[inline]
850    fn deref(&self) -> &Value {
851        unsafe { &*(self as *const SendValue as *const Value) }
852    }
853}
854
855impl<'a, T: ?Sized + ToSendValue> From<&'a T> for SendValue {
856    #[inline]
857    fn from(value: &'a T) -> Self {
858        value.to_send_value()
859    }
860}
861
862// rustdoc-stripper-ignore-next
863/// Converts to `SendValue`.
864pub trait ToSendValue: Send + ToValue {
865    // rustdoc-stripper-ignore-next
866    /// Returns a `SendValue` clone of `self`.
867    fn to_send_value(&self) -> SendValue;
868}
869
870impl<T: Send + ToValue + ?Sized> ToSendValue for T {
871    #[inline]
872    fn to_send_value(&self) -> SendValue {
873        unsafe { SendValue::unsafe_from(self.to_value().into_raw()) }
874    }
875}
876
877unsafe impl<'a> FromValue<'a> for &'a str {
878    type Checker = GenericValueTypeOrNoneChecker<Self>;
879
880    #[inline]
881    unsafe fn from_value(value: &'a Value) -> Self {
882        let ptr = gobject_ffi::g_value_get_string(value.to_glib_none().0);
883        CStr::from_ptr(ptr).to_str().expect("Invalid UTF-8")
884    }
885}
886
887impl ToValue for str {
888    fn to_value(&self) -> Value {
889        unsafe {
890            let mut value = Value::for_value_type::<String>();
891
892            gobject_ffi::g_value_take_string(value.to_glib_none_mut().0, self.to_glib_full());
893
894            value
895        }
896    }
897
898    fn value_type(&self) -> Type {
899        String::static_type()
900    }
901}
902
903impl ToValue for &str {
904    fn to_value(&self) -> Value {
905        (*self).to_value()
906    }
907
908    fn value_type(&self) -> Type {
909        String::static_type()
910    }
911}
912
913impl ToValueOptional for str {
914    fn to_value_optional(s: Option<&Self>) -> Value {
915        let mut value = Value::for_value_type::<String>();
916        unsafe {
917            gobject_ffi::g_value_take_string(value.to_glib_none_mut().0, s.to_glib_full());
918        }
919
920        value
921    }
922}
923
924impl ValueType for String {
925    type Type = String;
926}
927
928impl ValueTypeOptional for String {}
929
930unsafe impl<'a> FromValue<'a> for String {
931    type Checker = GenericValueTypeOrNoneChecker<Self>;
932
933    unsafe fn from_value(value: &'a Value) -> Self {
934        String::from(<&str>::from_value(value))
935    }
936}
937
938impl ToValue for String {
939    fn to_value(&self) -> Value {
940        <&str>::to_value(&self.as_str())
941    }
942
943    fn value_type(&self) -> Type {
944        String::static_type()
945    }
946}
947
948impl From<String> for Value {
949    #[inline]
950    fn from(s: String) -> Self {
951        s.to_value()
952    }
953}
954
955impl ToValueOptional for String {
956    fn to_value_optional(s: Option<&Self>) -> Value {
957        <str>::to_value_optional(s.as_ref().map(|s| s.as_str()))
958    }
959}
960
961impl ValueType for Box<str> {
962    type Type = String;
963}
964
965impl ValueTypeOptional for Box<str> {}
966
967unsafe impl<'a> FromValue<'a> for Box<str> {
968    type Checker = GenericValueTypeOrNoneChecker<Self>;
969
970    unsafe fn from_value(value: &'a Value) -> Self {
971        Box::<str>::from(<&str>::from_value(value))
972    }
973}
974
975impl StaticType for Box<str> {
976    fn static_type() -> Type {
977        String::static_type()
978    }
979}
980
981impl ToValue for Box<str> {
982    fn to_value(&self) -> Value {
983        <&str>::to_value(&self.as_ref())
984    }
985
986    fn value_type(&self) -> Type {
987        String::static_type()
988    }
989}
990
991impl From<Box<str>> for Value {
992    #[inline]
993    fn from(s: Box<str>) -> Self {
994        s.to_value()
995    }
996}
997
998impl ToValueOptional for Box<str> {
999    fn to_value_optional(s: Option<&Self>) -> Value {
1000        <str>::to_value_optional(s.as_ref().map(|s| s.as_ref()))
1001    }
1002}
1003
1004impl ValueType for Vec<String> {
1005    type Type = Vec<String>;
1006}
1007
1008unsafe impl<'a> FromValue<'a> for Vec<String> {
1009    type Checker = GenericValueTypeChecker<Self>;
1010
1011    unsafe fn from_value(value: &'a Value) -> Self {
1012        let ptr = gobject_ffi::g_value_get_boxed(value.to_glib_none().0) as *const *const c_char;
1013        FromGlibPtrContainer::from_glib_none(ptr)
1014    }
1015}
1016
1017impl ToValue for Vec<String> {
1018    fn to_value(&self) -> Value {
1019        unsafe {
1020            let mut value = Value::for_value_type::<Self>();
1021            let ptr: *mut *mut c_char = self.to_glib_full();
1022            gobject_ffi::g_value_take_boxed(value.to_glib_none_mut().0, ptr as *const c_void);
1023            value
1024        }
1025    }
1026
1027    fn value_type(&self) -> Type {
1028        <Vec<String>>::static_type()
1029    }
1030}
1031
1032impl From<Vec<String>> for Value {
1033    #[inline]
1034    fn from(s: Vec<String>) -> Self {
1035        s.to_value()
1036    }
1037}
1038
1039impl ToValue for [&'_ str] {
1040    fn to_value(&self) -> Value {
1041        unsafe {
1042            let mut value = Value::for_value_type::<Vec<String>>();
1043            let ptr: *mut *mut c_char = self.to_glib_full();
1044            gobject_ffi::g_value_take_boxed(value.to_glib_none_mut().0, ptr as *const c_void);
1045            value
1046        }
1047    }
1048
1049    fn value_type(&self) -> Type {
1050        <Vec<String>>::static_type()
1051    }
1052}
1053
1054impl ToValue for &'_ [&'_ str] {
1055    fn to_value(&self) -> Value {
1056        unsafe {
1057            let mut value = Value::for_value_type::<Vec<String>>();
1058            let ptr: *mut *mut c_char = self.to_glib_full();
1059            gobject_ffi::g_value_take_boxed(value.to_glib_none_mut().0, ptr as *const c_void);
1060            value
1061        }
1062    }
1063
1064    fn value_type(&self) -> Type {
1065        <Vec<String>>::static_type()
1066    }
1067}
1068
1069impl ToValue for Path {
1070    fn to_value(&self) -> Value {
1071        unsafe {
1072            let mut value = Value::for_value_type::<PathBuf>();
1073
1074            gobject_ffi::g_value_take_string(value.to_glib_none_mut().0, self.to_glib_full());
1075
1076            value
1077        }
1078    }
1079
1080    fn value_type(&self) -> Type {
1081        PathBuf::static_type()
1082    }
1083}
1084
1085impl ToValue for &Path {
1086    fn to_value(&self) -> Value {
1087        (*self).to_value()
1088    }
1089
1090    fn value_type(&self) -> Type {
1091        PathBuf::static_type()
1092    }
1093}
1094
1095impl ToValueOptional for Path {
1096    fn to_value_optional(s: Option<&Self>) -> Value {
1097        let mut value = Value::for_value_type::<PathBuf>();
1098        unsafe {
1099            gobject_ffi::g_value_take_string(value.to_glib_none_mut().0, s.to_glib_full());
1100        }
1101
1102        value
1103    }
1104}
1105
1106impl ValueType for PathBuf {
1107    type Type = PathBuf;
1108}
1109
1110impl ValueTypeOptional for PathBuf {}
1111
1112unsafe impl<'a> FromValue<'a> for PathBuf {
1113    type Checker = GenericValueTypeOrNoneChecker<Self>;
1114
1115    unsafe fn from_value(value: &'a Value) -> Self {
1116        from_glib_none(gobject_ffi::g_value_get_string(value.to_glib_none().0))
1117    }
1118}
1119
1120impl ToValue for PathBuf {
1121    fn to_value(&self) -> Value {
1122        <&Path>::to_value(&self.as_path())
1123    }
1124
1125    fn value_type(&self) -> Type {
1126        PathBuf::static_type()
1127    }
1128}
1129
1130impl From<PathBuf> for Value {
1131    #[inline]
1132    fn from(s: PathBuf) -> Self {
1133        s.to_value()
1134    }
1135}
1136
1137impl ToValueOptional for PathBuf {
1138    fn to_value_optional(s: Option<&Self>) -> Value {
1139        <Path>::to_value_optional(s.as_ref().map(|s| s.as_path()))
1140    }
1141}
1142
1143impl ValueType for bool {
1144    type Type = Self;
1145}
1146
1147unsafe impl<'a> FromValue<'a> for bool {
1148    type Checker = GenericValueTypeChecker<Self>;
1149
1150    #[inline]
1151    unsafe fn from_value(value: &'a Value) -> Self {
1152        from_glib(gobject_ffi::g_value_get_boolean(value.to_glib_none().0))
1153    }
1154}
1155
1156impl ToValue for bool {
1157    #[inline]
1158    fn to_value(&self) -> Value {
1159        let mut value = Value::for_value_type::<Self>();
1160        unsafe {
1161            gobject_ffi::g_value_set_boolean(&mut value.inner, self.into_glib());
1162        }
1163        value
1164    }
1165
1166    #[inline]
1167    fn value_type(&self) -> Type {
1168        Self::static_type()
1169    }
1170}
1171
1172impl From<bool> for Value {
1173    #[inline]
1174    fn from(v: bool) -> Self {
1175        v.to_value()
1176    }
1177}
1178
1179impl ValueType for Pointer {
1180    type Type = Self;
1181}
1182
1183unsafe impl<'a> FromValue<'a> for Pointer {
1184    type Checker = GenericValueTypeChecker<Self>;
1185
1186    #[inline]
1187    unsafe fn from_value(value: &'a Value) -> Self {
1188        gobject_ffi::g_value_get_pointer(value.to_glib_none().0)
1189    }
1190}
1191
1192impl ToValue for Pointer {
1193    #[inline]
1194    fn to_value(&self) -> Value {
1195        let mut value = Value::for_value_type::<Self>();
1196        unsafe {
1197            gobject_ffi::g_value_set_pointer(&mut value.inner, *self);
1198        }
1199        value
1200    }
1201
1202    #[inline]
1203    fn value_type(&self) -> Type {
1204        <<Self as ValueType>::Type as StaticType>::static_type()
1205    }
1206}
1207
1208impl From<Pointer> for Value {
1209    #[inline]
1210    fn from(v: Pointer) -> Self {
1211        v.to_value()
1212    }
1213}
1214
1215impl ValueType for ptr::NonNull<Pointee> {
1216    type Type = Pointer;
1217}
1218
1219unsafe impl<'a> FromValue<'a> for ptr::NonNull<Pointee> {
1220    type Checker = GenericValueTypeOrNoneChecker<Self>;
1221
1222    #[inline]
1223    unsafe fn from_value(value: &'a Value) -> Self {
1224        ptr::NonNull::new_unchecked(Pointer::from_value(value))
1225    }
1226}
1227
1228impl ToValue for ptr::NonNull<Pointee> {
1229    #[inline]
1230    fn to_value(&self) -> Value {
1231        self.as_ptr().to_value()
1232    }
1233
1234    #[inline]
1235    fn value_type(&self) -> Type {
1236        <<Self as ValueType>::Type as StaticType>::static_type()
1237    }
1238}
1239
1240impl From<ptr::NonNull<Pointee>> for Value {
1241    #[inline]
1242    fn from(v: ptr::NonNull<Pointee>) -> Self {
1243        v.to_value()
1244    }
1245}
1246
1247impl ToValueOptional for ptr::NonNull<Pointee> {
1248    #[inline]
1249    fn to_value_optional(p: Option<&Self>) -> Value {
1250        p.map(|p| p.as_ptr()).unwrap_or(ptr::null_mut()).to_value()
1251    }
1252}
1253
1254macro_rules! numeric {
1255    ($name:ty, $get:expr, $set:expr) => {
1256        impl ValueType for $name {
1257            type Type = Self;
1258        }
1259
1260        unsafe impl<'a> FromValue<'a> for $name {
1261            type Checker = GenericValueTypeChecker<Self>;
1262
1263            #[inline]
1264            #[allow(clippy::redundant_closure_call)]
1265            unsafe fn from_value(value: &'a Value) -> Self {
1266                $get(value.to_glib_none().0)
1267            }
1268        }
1269
1270        impl ToValue for $name {
1271            #[inline]
1272            #[allow(clippy::redundant_closure_call)]
1273            fn to_value(&self) -> Value {
1274                let mut value = Value::for_value_type::<Self>();
1275                unsafe {
1276                    $set(&mut value.inner, *self);
1277                }
1278                value
1279            }
1280
1281            #[inline]
1282            fn value_type(&self) -> Type {
1283                Self::static_type()
1284            }
1285        }
1286
1287        impl From<$name> for Value {
1288            #[inline]
1289            fn from(v: $name) -> Self {
1290                v.to_value()
1291            }
1292        }
1293    };
1294}
1295macro_rules! not_zero {
1296    ($name:ty, $num:ty) => {
1297        impl ValueType for $name {
1298            type Type = $name;
1299        }
1300
1301        unsafe impl<'a> FromValue<'a> for $name {
1302            // Works because it returns `UnexpectedNone` if the value is NULL
1303            // by checking it against `0`.
1304            type Checker = GenericValueTypeOrNoneChecker<Self>;
1305
1306            #[inline]
1307            unsafe fn from_value(value: &'a Value) -> Self {
1308                let res = <$num>::from_value(value);
1309                Self::try_from(res).unwrap()
1310            }
1311        }
1312
1313        impl ToValue for $name {
1314            #[inline]
1315            fn to_value(&self) -> Value {
1316                <$num>::to_value(&<$num>::from(*self))
1317            }
1318
1319            #[inline]
1320            fn value_type(&self) -> Type {
1321                Self::static_type()
1322            }
1323        }
1324
1325        impl From<$name> for Value {
1326            #[inline]
1327            fn from(v: $name) -> Self {
1328                v.to_value()
1329            }
1330        }
1331
1332        impl ToValueOptional for $name {
1333            fn to_value_optional(s: Option<&Self>) -> Value {
1334                match s {
1335                    Some(x) => x.to_value(),
1336                    None => <$num>::to_value(&0),
1337                }
1338            }
1339        }
1340    };
1341}
1342
1343numeric!(
1344    i8,
1345    gobject_ffi::g_value_get_schar,
1346    gobject_ffi::g_value_set_schar
1347);
1348not_zero!(NonZeroI8, i8);
1349numeric!(
1350    u8,
1351    gobject_ffi::g_value_get_uchar,
1352    gobject_ffi::g_value_set_uchar
1353);
1354not_zero!(NonZeroU8, u8);
1355numeric!(
1356    i32,
1357    gobject_ffi::g_value_get_int,
1358    gobject_ffi::g_value_set_int
1359);
1360not_zero!(NonZeroI32, i32);
1361numeric!(
1362    u32,
1363    gobject_ffi::g_value_get_uint,
1364    gobject_ffi::g_value_set_uint
1365);
1366not_zero!(NonZeroU32, u32);
1367numeric!(
1368    i64,
1369    gobject_ffi::g_value_get_int64,
1370    gobject_ffi::g_value_set_int64
1371);
1372not_zero!(NonZeroI64, i64);
1373numeric!(
1374    u64,
1375    gobject_ffi::g_value_get_uint64,
1376    gobject_ffi::g_value_set_uint64
1377);
1378not_zero!(NonZeroU64, u64);
1379numeric!(
1380    crate::ILong,
1381    |v| gobject_ffi::g_value_get_long(v).into(),
1382    |v, i: crate::ILong| gobject_ffi::g_value_set_long(v, i.0)
1383);
1384numeric!(
1385    crate::ULong,
1386    |v| gobject_ffi::g_value_get_ulong(v).into(),
1387    |v, i: crate::ULong| gobject_ffi::g_value_set_ulong(v, i.0)
1388);
1389numeric!(
1390    f32,
1391    gobject_ffi::g_value_get_float,
1392    gobject_ffi::g_value_set_float
1393);
1394numeric!(
1395    f64,
1396    gobject_ffi::g_value_get_double,
1397    gobject_ffi::g_value_set_double
1398);
1399
1400impl ValueType for char {
1401    type Type = u32;
1402}
1403
1404unsafe impl<'a> FromValue<'a> for char {
1405    type Checker = CharTypeChecker;
1406
1407    #[inline]
1408    unsafe fn from_value(value: &'a Value) -> Self {
1409        let res: u32 = gobject_ffi::g_value_get_uint(value.to_glib_none().0);
1410        // safe because the check is done by `Self::Checker`
1411        char::from_u32_unchecked(res)
1412    }
1413}
1414
1415impl ToValue for char {
1416    #[inline]
1417    fn to_value(&self) -> Value {
1418        let mut value = Value::for_value_type::<Self>();
1419        unsafe {
1420            gobject_ffi::g_value_set_uint(&mut value.inner, *self as u32);
1421        }
1422        value
1423    }
1424
1425    #[inline]
1426    fn value_type(&self) -> Type {
1427        crate::Type::U32
1428    }
1429}
1430
1431impl From<char> for Value {
1432    #[inline]
1433    fn from(v: char) -> Self {
1434        v.to_value()
1435    }
1436}
1437
1438// rustdoc-stripper-ignore-next
1439/// A [`Value`] containing another [`Value`].
1440pub struct BoxedValue(pub Value);
1441
1442impl Deref for BoxedValue {
1443    type Target = Value;
1444
1445    #[inline]
1446    fn deref(&self) -> &Value {
1447        &self.0
1448    }
1449}
1450
1451impl ValueType for BoxedValue {
1452    type Type = BoxedValue;
1453}
1454
1455impl ValueTypeOptional for BoxedValue {}
1456
1457unsafe impl<'a> FromValue<'a> for BoxedValue {
1458    type Checker = GenericValueTypeOrNoneChecker<Self>;
1459
1460    #[inline]
1461    unsafe fn from_value(value: &'a Value) -> Self {
1462        let ptr = gobject_ffi::g_value_get_boxed(value.to_glib_none().0);
1463        BoxedValue(from_glib_none(ptr as *const gobject_ffi::GValue))
1464    }
1465}
1466
1467impl ToValue for BoxedValue {
1468    #[inline]
1469    fn to_value(&self) -> Value {
1470        unsafe {
1471            let mut value = Value::for_value_type::<BoxedValue>();
1472
1473            gobject_ffi::g_value_set_boxed(
1474                value.to_glib_none_mut().0,
1475                self.0.to_glib_none().0 as ffi::gconstpointer,
1476            );
1477
1478            value
1479        }
1480    }
1481
1482    #[inline]
1483    fn value_type(&self) -> Type {
1484        BoxedValue::static_type()
1485    }
1486}
1487
1488impl From<BoxedValue> for Value {
1489    #[inline]
1490    fn from(v: BoxedValue) -> Self {
1491        unsafe {
1492            let mut value = Value::for_value_type::<BoxedValue>();
1493
1494            gobject_ffi::g_value_take_boxed(
1495                value.to_glib_none_mut().0,
1496                v.0.to_glib_full() as ffi::gconstpointer,
1497            );
1498
1499            value
1500        }
1501    }
1502}
1503
1504impl ToValueOptional for BoxedValue {
1505    #[inline]
1506    fn to_value_optional(s: Option<&Self>) -> Value {
1507        let mut value = Value::for_value_type::<Self>();
1508        unsafe {
1509            gobject_ffi::g_value_set_boxed(
1510                value.to_glib_none_mut().0,
1511                s.map(|s| &s.0).to_glib_none().0 as ffi::gconstpointer,
1512            );
1513        }
1514
1515        value
1516    }
1517}
1518
1519#[cfg(test)]
1520mod tests {
1521    use std::num::NonZeroI32;
1522
1523    use super::*;
1524
1525    #[test]
1526    fn test_send_value() {
1527        use std::thread;
1528
1529        let v = SendValue::from(&1i32);
1530
1531        // Must compile, while it must fail with Value
1532        thread::spawn(move || drop(v)).join().unwrap();
1533    }
1534
1535    #[test]
1536    fn test_strv() {
1537        let v = ["123", "456"].to_value();
1538        assert_eq!(
1539            v.get::<Vec<GString>>(),
1540            Ok(vec![GString::from("123"), GString::from("456")])
1541        );
1542
1543        let v = vec![String::from("123"), String::from("456")].to_value();
1544        assert_eq!(
1545            v.get::<Vec<GString>>(),
1546            Ok(vec![GString::from("123"), GString::from("456")])
1547        );
1548    }
1549
1550    #[test]
1551    fn test_from_to_value() {
1552        let v = 123.to_value();
1553        assert_eq!(v.get(), Ok(123));
1554        assert_eq!(
1555            v.get::<&str>(),
1556            Err(ValueTypeMismatchError::new(Type::I32, Type::STRING).into())
1557        );
1558        assert_eq!(
1559            v.get::<bool>(),
1560            Err(ValueTypeMismatchError::new(Type::I32, Type::BOOL))
1561        );
1562
1563        // Check if &str / str / Option<&str> etc can be converted and retrieved
1564        let v_str = "test".to_value();
1565        assert_eq!(v_str.get::<&str>(), Ok("test"));
1566        assert_eq!(v_str.get::<Option<&str>>(), Ok(Some("test")));
1567        assert_eq!(
1568            v_str.get::<i32>(),
1569            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1570        );
1571
1572        let some_v = Some("test").to_value();
1573        assert_eq!(some_v.get::<&str>(), Ok("test"));
1574        assert_eq!(some_v.get_owned::<String>(), Ok("test".to_string()));
1575        assert_eq!(
1576            some_v.get_owned::<Option<String>>(),
1577            Ok(Some("test".to_string()))
1578        );
1579        assert_eq!(some_v.get::<Option<&str>>(), Ok(Some("test")));
1580        assert_eq!(
1581            some_v.get::<i32>(),
1582            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1583        );
1584
1585        let none_str: Option<&str> = None;
1586        let none_v = none_str.to_value();
1587        assert_eq!(none_v.get::<Option<&str>>(), Ok(None));
1588        assert_eq!(
1589            none_v.get::<i32>(),
1590            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1591        );
1592
1593        // Check if owned T and Option<T> can be converted and retrieved
1594        let v_str = String::from("test").to_value();
1595        assert_eq!(v_str.get::<String>(), Ok(String::from("test")));
1596        assert_eq!(
1597            v_str.get::<Option<String>>(),
1598            Ok(Some(String::from("test")))
1599        );
1600        assert_eq!(
1601            v_str.get::<i32>(),
1602            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1603        );
1604
1605        let some_v = Some(String::from("test")).to_value();
1606        assert_eq!(some_v.get::<String>(), Ok(String::from("test")));
1607        assert_eq!(
1608            some_v.get::<Option<String>>(),
1609            Ok(Some(String::from("test")))
1610        );
1611        assert_eq!(
1612            some_v.get::<i32>(),
1613            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1614        );
1615
1616        let none_str: Option<String> = None;
1617        let none_v = none_str.to_value();
1618        assert_eq!(none_v.get::<Option<String>>(), Ok(None));
1619        assert_eq!(
1620            none_v.get::<i32>(),
1621            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1622        );
1623
1624        let c_v = 'c'.to_value();
1625        assert_eq!(c_v.get::<char>(), Ok('c'));
1626
1627        let c_v = 0xFFFFFFFFu32.to_value();
1628        assert_eq!(
1629            c_v.get::<char>(),
1630            Err(InvalidCharError::CharConversionError)
1631        );
1632
1633        // Check if &T and Option<&T> can be converted and retrieved
1634        let v_str = String::from("test").to_value();
1635        assert_eq!(v_str.get::<String>(), Ok(String::from("test")));
1636        assert_eq!(
1637            v_str.get::<Option<String>>(),
1638            Ok(Some(String::from("test")))
1639        );
1640        assert_eq!(
1641            v_str.get::<i32>(),
1642            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1643        );
1644
1645        let some_v = Some(&String::from("test")).to_value();
1646        assert_eq!(some_v.get::<String>(), Ok(String::from("test")));
1647        assert_eq!(
1648            some_v.get::<Option<String>>(),
1649            Ok(Some(String::from("test")))
1650        );
1651        assert_eq!(
1652            some_v.get::<i32>(),
1653            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1654        );
1655
1656        let none_str: Option<&String> = None;
1657        let none_v = none_str.to_value();
1658        assert_eq!(none_v.get::<Option<String>>(), Ok(None));
1659        assert_eq!(
1660            none_v.get::<i32>(),
1661            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1662        );
1663
1664        // Check handling of NonZeroT
1665        let v = NonZeroI32::new(123).unwrap().to_value();
1666        assert_eq!(v.get::<NonZeroI32>(), Ok(NonZeroI32::new(123).unwrap()));
1667
1668        let v = 123i32.to_value();
1669        assert_eq!(v.get::<NonZeroI32>(), Ok(NonZeroI32::new(123).unwrap()));
1670
1671        let v = 0i32.to_value();
1672        assert_eq!(
1673            v.get::<NonZeroI32>(),
1674            Err(ValueTypeMismatchOrNoneError::UnexpectedNone)
1675        );
1676
1677        assert_eq!(v.get::<Option<NonZeroI32>>(), Ok(None));
1678    }
1679
1680    #[test]
1681    fn test_transform() {
1682        let v = 123.to_value();
1683        let v2 = v
1684            .transform::<String>()
1685            .expect("Failed to transform to string");
1686        assert_eq!(v2.get::<&str>(), Ok("123"));
1687    }
1688
1689    #[test]
1690    fn test_into_raw() {
1691        unsafe {
1692            let mut v = 123.to_value().into_raw();
1693            assert_eq!(gobject_ffi::g_type_check_value(&v), ffi::GTRUE);
1694            assert_eq!(gobject_ffi::g_value_get_int(&v), 123);
1695            gobject_ffi::g_value_unset(&mut v);
1696        }
1697    }
1698
1699    #[test]
1700    fn test_debug() {
1701        fn value_debug_string<T: ToValue>(val: T) -> String {
1702            format!("{:?}", val.to_value())
1703        }
1704
1705        assert_eq!(value_debug_string(1u32), "(guint) 1");
1706        assert_eq!(value_debug_string(2i32), "(gint) 2");
1707        assert_eq!(value_debug_string(false), "(gboolean) FALSE");
1708        assert_eq!(value_debug_string("FooBar"), r#"(gchararray) "FooBar""#);
1709    }
1710}