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    // rustdoc-stripper-ignore-next-stop
492    /// An opaque structure used to hold different types of values.
493    ///
494    /// The data within the structure has protected scope: it is accessible only
495    /// to functions within a [`TypeValueTable`][crate::TypeValueTable] structure, or implementations of
496    /// the g_value_*() API. That is, code portions which implement new fundamental
497    /// types.
498    ///
499    /// [`Value`][crate::Value] users cannot make any assumptions about how data is stored
500    /// within the 2 element `data` union, and the `g_type` member should
501    /// only be accessed through the G_VALUE_TYPE() macro.
502    #[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    // rustdoc-stripper-ignore-next
516    /// Creates a new `Value` that is initialized with `type_`.
517    ///
518    /// # Panics
519    ///
520    /// If `type_` can't be stored in a `Value` this function panics.
521    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    // rustdoc-stripper-ignore-next
532    /// Creates a new `Value` that is initialized with `type_`.
533    ///
534    /// # SAFETY
535    ///
536    /// This must be called with a valid `type_` that can be stored in `Value`s.
537    #[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    // rustdoc-stripper-ignore-next
547    /// Creates a new `Value` that is initialized for a given `ValueType`.
548    #[inline]
549    pub fn for_value_type<T: ValueType>() -> Self {
550        unsafe { Value::from_type_unchecked(T::Type::static_type()) }
551    }
552
553    // rustdoc-stripper-ignore-next
554    /// Creates a new `String`-typed `Value` from a `'static` string.
555    #[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    // rustdoc-stripper-ignore-next
568    /// Creates a new `String`-typed `Value` from a `'static` string that is also assumed to be
569    /// interned.
570    #[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    // rustdoc-stripper-ignore-next
581    /// Tries to get a value of type `T`.
582    ///
583    /// Returns `Ok` if the type is correct.
584    #[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    // rustdoc-stripper-ignore-next
598    /// Tries to get a value of an owned type `T`.
599    #[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    // rustdoc-stripper-ignore-next
611    /// Returns `true` if the type of the value corresponds to `T`
612    /// or is a sub-type of `T`.
613    #[inline]
614    pub fn is<T: StaticType>(&self) -> bool {
615        self.is_type(T::static_type())
616    }
617
618    // rustdoc-stripper-ignore-next
619    /// Returns `true` if the type of the value corresponds to `type_`
620    /// or is a sub-type of `type_`.
621    #[inline]
622    pub fn is_type(&self, type_: Type) -> bool {
623        self.type_().is_a(type_)
624    }
625
626    // rustdoc-stripper-ignore-next
627    /// Returns the type of the value.
628    #[inline]
629    pub fn type_(&self) -> Type {
630        unsafe { from_glib(self.inner.g_type) }
631    }
632
633    // rustdoc-stripper-ignore-next
634    /// Returns whether `Value`s of type `src` can be transformed to type `dst`.
635    // rustdoc-stripper-ignore-next-stop
636    /// Check whether [`transform()`][Self::transform()] is able to transform values
637    /// of type `src_type` into values of type `dest_type`. Note that for
638    /// the types to be transformable, they must be compatible or a
639    /// transformation function must be registered.
640    /// ## `src_type`
641    /// Source type.
642    /// ## `dest_type`
643    /// Target type.
644    ///
645    /// # Returns
646    ///
647    /// [`true`] if the transformation is possible, [`false`] otherwise.
648    /// tform-specific APIs, which is problematic
649    /// for software using GLib as a cross-platform layer.
650    ///
651    /// Additionally, many programs simply want to determine whether or not
652    /// the child exited successfully, and either propagate a #GError or
653    /// print a message to standard error. In that common case, this function
654    /// can be used. Note that the error message in @error will contain
655    /// human-readable information about the wait status.
656    ///
657    /// The @domain and @code of @error have special semantics in the case
658    /// where the process has an "exit code", as opposed to being killed by
659    /// a signal. On Unix, this happens if WIFEXITED() would be true of
660    /// @wait_status. On Windows, it is always the case.
661    ///
662    /// The special semantics are that the actual exit code will be the
663    /// code set in @error, and the domain will be `G_SPAWN_EXIT_ERROR`.
664    /// This allows you to differentiate between different exit codes.
665    ///
666    /// If the process was terminated by some means other than an exit
667    /// status (for example if it was killed by a signal), the domain will be
668    /// `G_SPAWN_ERROR` and the code will be `G_SPAWN_ERROR_FAILED`.
669    ///
670    /// This function just offers convenience; you can of course also check
671    /// the available platform via a macro such as `G_OS_UNIX`, and use
672    /// WIFEXITED() and WEXITSTATUS() on @wait_status directly. Do not attempt
673    /// to scan or parse the error message string; it may be translated and/or
674    /// change in future versions of GLib.
675    ///
676    /// Prior to version 2.70, g_spawn_check_exit_status() provides the same
677    /// functionality, although under a misleading name.
678    /// ## `wait_status`
679    /// A platform-specific wait status as returned from g_spawn_sync()
680    ///
681    /// # Returns
682    ///
683    /// [`true`] if child exited successfully, [`false`] otherwise (and
684    ///   @error will be set)
685    #[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    // rustdoc-stripper-ignore-next
696    /// Tries to transform the value into a value of the target type
697    // rustdoc-stripper-ignore-next-stop
698    /// Tries to cast the contents of `self` into a type appropriate
699    /// to store in `dest_value`, e.g. to transform a `G_TYPE_INT` value
700    /// into a `G_TYPE_FLOAT` value. Performing transformations between
701    /// value types might incur precision lossage. Especially
702    /// transformations into strings might reveal seemingly arbitrary
703    /// results and shouldn't be relied upon for production code (such
704    /// as rcfile value or object property serialization).
705    /// ## `dest_value`
706    /// Target value.
707    ///
708    /// # Returns
709    ///
710    /// Whether a transformation rule was found and could be applied.
711    ///  Upon failing transformations, `dest_value` is left untouched.
712    #[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    // rustdoc-stripper-ignore-next
718    /// Tries to transform the value into a value of the target type
719    #[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    // rustdoc-stripper-ignore-next
739    /// Consumes `Value` and returns the corresponding `GValue`.
740    #[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    // rustdoc-stripper-ignore-next
749    /// Converts a `Value` into a `SendValue`. This fails if `self` does not store a value of type
750    /// `T`. It is required for `T` to be `Send` to call this function.
751    #[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    // rustdoc-stripper-ignore-next
761    /// Converts a `Value` into a `SendValue`.
762    ///
763    /// # Safety
764    ///
765    /// The type of the value contained in `self` must be `Send`.
766    #[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    // rustdoc-stripper-ignore-next
882    /// A version of [`Value`](struct.Value.html) for storing `Send` types, that implements Send
883    /// itself.
884    ///
885    /// See the [module documentation](index.html) for more details.
886    #[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    // rustdoc-stripper-ignore-next
902    /// Consumes `SendValue` and returns the corresponding `GValue`.
903    #[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
938// rustdoc-stripper-ignore-next
939/// Converts to `SendValue`.
940pub trait ToSendValue: Send + ToValue {
941    // rustdoc-stripper-ignore-next
942    /// Returns a `SendValue` clone of `self`.
943    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            // Works because it returns `UnexpectedNone` if the value is NULL
1379            // by checking it against `0`.
1380            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        // safe because the check is done by `Self::Checker`
1487        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
1514// rustdoc-stripper-ignore-next
1515/// A [`Value`] containing another [`Value`].
1516pub 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        // Must compile, while it must fail with Value
1608        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        // Check if &str / str / Option<&str> etc can be converted and retrieved
1640        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        // Check if owned T and Option<T> can be converted and retrieved
1670        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        // Check if &T and Option<&T> can be converted and retrieved
1710        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        // Check handling of NonZeroT
1741        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}