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>(
590        &self,
591    ) -> Result<T, <<T as FromValue<'_>>::Checker as ValueTypeChecker>::Error>
592    where
593        T: for<'b> FromValue<'b> + 'static,
594    {
595        unsafe {
596            T::Checker::check(self)?;
597            Ok(FromValue::from_value(self))
598        }
599    }
600
601    // rustdoc-stripper-ignore-next
602    /// Returns `true` if the type of the value corresponds to `T`
603    /// or is a sub-type of `T`.
604    #[inline]
605    pub fn is<T: StaticType>(&self) -> bool {
606        self.is_type(T::static_type())
607    }
608
609    // rustdoc-stripper-ignore-next
610    /// Returns `true` if the type of the value corresponds to `type_`
611    /// or is a sub-type of `type_`.
612    #[inline]
613    pub fn is_type(&self, type_: Type) -> bool {
614        self.type_().is_a(type_)
615    }
616
617    // rustdoc-stripper-ignore-next
618    /// Returns the type of the value.
619    #[inline]
620    pub fn type_(&self) -> Type {
621        unsafe { from_glib(self.inner.g_type) }
622    }
623
624    // rustdoc-stripper-ignore-next
625    /// Returns whether `Value`s of type `src` can be transformed to type `dst`.
626    // rustdoc-stripper-ignore-next-stop
627    /// Check whether [`transform()`][Self::transform()] is able to transform values
628    /// of type `src_type` into values of type `dest_type`. Note that for
629    /// the types to be transformable, they must be compatible or a
630    /// transformation function must be registered.
631    /// ## `src_type`
632    /// Source type.
633    /// ## `dest_type`
634    /// Target type.
635    ///
636    /// # Returns
637    ///
638    /// [`true`] if the transformation is possible, [`false`] otherwise.
639    /// ult of GetExitCodeProcess().
640    ///
641    /// Prior to the introduction of this function in GLib 2.34, interpreting
642    /// @wait_status required use of platform-specific APIs, which is problematic
643    /// for software using GLib as a cross-platform layer.
644    ///
645    /// Additionally, many programs simply want to determine whether or not
646    /// the child exited successfully, and either propagate a #GError or
647    /// print a message to standard error. In that common case, this function
648    /// can be used. Note that the error message in @error will contain
649    /// human-readable information about the wait status.
650    ///
651    /// The @domain and @code of @error have special semantics in the case
652    /// where the process has an "exit code", as opposed to being killed by
653    /// a signal. On Unix, this happens if WIFEXITED() would be true of
654    /// @wait_status. On Windows, it is always the case.
655    ///
656    /// The special semantics are that the actual exit code will be the
657    /// code set in @error, and the domain will be `G_SPAWN_EXIT_ERROR`.
658    /// This allows you to differentiate between different exit codes.
659    ///
660    /// If the process was terminated by some means other than an exit
661    /// status (for example if it was killed by a signal), the domain will be
662    /// `G_SPAWN_ERROR` and the code will be `G_SPAWN_ERROR_FAILED`.
663    ///
664    /// This function just offers convenience; you can of course also check
665    /// the available platform via a macro such as `G_OS_UNIX`, and use
666    /// WIFEXITED() and WEXITSTATUS() on @wait_status directly. Do not attempt
667    /// to scan or parse the error message string; it may be translated and/or
668    /// change in future versions of GLib.
669    ///
670    /// Prior to version 2.70, g_spawn_check_exit_status() provides the same
671    /// functionality, although under a misleading name.
672    /// ## `wait_status`
673    /// A platform-specific wait status as returned from g_spawn_sync()
674    ///
675    /// # Returns
676    ///
677    /// [`true`] if child exited successfully, [`false`] otherwise (and
678    ///   @error will be set)
679    // rustdoc-stripper-ignore-next-stop
680    /// Check whether [`transform()`][Self::transform()] is able to transform values
681    /// of type `src_type` into values of type `dest_type`. Note that for
682    /// the types to be transformable, they must be compatible or a
683    /// transformation function must be registered.
684    /// ## `src_type`
685    /// Source type.
686    /// ## `dest_type`
687    /// Target type.
688    ///
689    /// # Returns
690    ///
691    /// [`true`] if the transformation is possible, [`false`] otherwise.
692    /// ult of GetExitCodeProcess().
693    ///
694    /// Prior to the introduction of this function in GLib 2.34, interpreting
695    /// @wait_status required use of platform-specific APIs, which is problematic
696    /// for software using GLib as a cross-platform layer.
697    ///
698    /// Additionally, many programs simply want to determine whether or not
699    /// the child exited successfully, and either propagate a #GError or
700    /// print a message to standard error. In that common case, this function
701    /// can be used. Note that the error message in @error will contain
702    /// human-readable information about the wait status.
703    ///
704    /// The @domain and @code of @error have special semantics in the case
705    /// where the process has an "exit code", as opposed to being killed by
706    /// a signal. On Unix, this happens if WIFEXITED() would be true of
707    /// @wait_status. On Windows, it is always the case.
708    ///
709    /// The special semantics are that the actual exit code will be the
710    /// code set in @error, and the domain will be `G_SPAWN_EXIT_ERROR`.
711    /// This allows you to differentiate between different exit codes.
712    ///
713    /// If the process was terminated by some means other than an exit
714    /// status (for example if it was killed by a signal), the domain will be
715    /// `G_SPAWN_ERROR` and the code will be `G_SPAWN_ERROR_FAILED`.
716    ///
717    /// This function just offers convenience; you can of course also check
718    /// the available platform via a macro such as `G_OS_UNIX`, and use
719    /// WIFEXITED() and WEXITSTATUS() on @wait_status directly. Do not attempt
720    /// to scan or parse the error message string; it may be translated and/or
721    /// change in future versions of GLib.
722    ///
723    /// Prior to version 2.70, g_spawn_check_exit_status() provides the same
724    /// functionality, although under a misleading name.
725    /// ## `wait_status`
726    /// A platform-specific wait status as returned from g_spawn_sync()
727    ///
728    /// # Returns
729    ///
730    /// [`true`] if child exited successfully, [`false`] otherwise (and
731    ///   @error will be set)
732    #[doc(alias = "g_value_type_transformable")]
733    pub fn type_transformable(src: Type, dst: Type) -> bool {
734        unsafe {
735            from_glib(gobject_ffi::g_value_type_transformable(
736                src.into_glib(),
737                dst.into_glib(),
738            ))
739        }
740    }
741
742    // rustdoc-stripper-ignore-next
743    /// Tries to transform the value into a value of the target type
744    // rustdoc-stripper-ignore-next-stop
745    /// Tries to cast the contents of `self` into a type appropriate
746    /// to store in `dest_value`, e.g. to transform a `G_TYPE_INT` value
747    /// into a `G_TYPE_FLOAT` value. Performing transformations between
748    /// value types might incur precision lossage. Especially
749    /// transformations into strings might reveal seemingly arbitrary
750    /// results and shouldn't be relied upon for production code (such
751    /// as rcfile value or object property serialization).
752    /// ## `dest_value`
753    /// Target value.
754    ///
755    /// # Returns
756    ///
757    /// Whether a transformation rule was found and could be applied.
758    ///  Upon failing transformations, `dest_value` is left untouched.
759    // rustdoc-stripper-ignore-next-stop
760    /// Tries to cast the contents of `self` into a type appropriate
761    /// to store in `dest_value`, e.g. to transform a `G_TYPE_INT` value
762    /// into a `G_TYPE_FLOAT` value. Performing transformations between
763    /// value types might incur precision lossage. Especially
764    /// transformations into strings might reveal seemingly arbitrary
765    /// results and shouldn't be relied upon for production code (such
766    /// as rcfile value or object property serialization).
767    /// ## `dest_value`
768    /// Target value.
769    ///
770    /// # Returns
771    ///
772    /// Whether a transformation rule was found and could be applied.
773    ///  Upon failing transformations, `dest_value` is left untouched.
774    #[doc(alias = "g_value_transform")]
775    pub fn transform<T: ValueType>(&self) -> Result<Value, crate::BoolError> {
776        self.transform_with_type(T::Type::static_type())
777    }
778
779    // rustdoc-stripper-ignore-next
780    /// Tries to transform the value into a value of the target type
781    #[doc(alias = "g_value_transform")]
782    pub fn transform_with_type(&self, type_: Type) -> Result<Value, crate::BoolError> {
783        unsafe {
784            let mut dest = Value::from_type(type_);
785            if from_glib(gobject_ffi::g_value_transform(
786                self.to_glib_none().0,
787                dest.to_glib_none_mut().0,
788            )) {
789                Ok(dest)
790            } else {
791                Err(crate::bool_error!(
792                    "Can't transform value of type '{}' into '{}'",
793                    self.type_(),
794                    type_
795                ))
796            }
797        }
798    }
799
800    // rustdoc-stripper-ignore-next
801    /// Consumes `Value` and returns the corresponding `GValue`.
802    #[inline]
803    pub fn into_raw(self) -> gobject_ffi::GValue {
804        unsafe {
805            let s = mem::ManuallyDrop::new(self);
806            ptr::read(&s.inner)
807        }
808    }
809
810    // rustdoc-stripper-ignore-next
811    /// Converts a `Value` into a `SendValue`. This fails if `self` does not store a value of type
812    /// `T`. It is required for `T` to be `Send` to call this function.
813    #[inline]
814    pub fn try_into_send_value<T: Send + StaticType>(self) -> Result<SendValue, Self> {
815        if self.type_().is_a(T::static_type()) {
816            unsafe { Ok(SendValue::unsafe_from(self.into_raw())) }
817        } else {
818            Err(self)
819        }
820    }
821
822    // rustdoc-stripper-ignore-next
823    /// Converts a `Value` into a `SendValue`.
824    ///
825    /// # Safety
826    ///
827    /// The type of the value contained in `self` must be `Send`.
828    #[inline]
829    pub unsafe fn into_send_value(self) -> SendValue {
830        SendValue::unsafe_from(self.into_raw())
831    }
832
833    fn content_debug_string(&self) -> GString {
834        unsafe { from_glib_full(gobject_ffi::g_strdup_value_contents(self.to_glib_none().0)) }
835    }
836}
837
838impl fmt::Debug for Value {
839    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
840        write!(f, "({}) {}", self.type_(), self.content_debug_string())
841    }
842}
843
844impl<'a, T: ?Sized + ToValue> From<&'a T> for Value {
845    #[inline]
846    fn from(value: &'a T) -> Self {
847        value.to_value()
848    }
849}
850
851impl From<SendValue> for Value {
852    #[inline]
853    fn from(value: SendValue) -> Self {
854        unsafe { Value::unsafe_from(value.into_raw()) }
855    }
856}
857
858impl ToValue for Value {
859    #[inline]
860    fn to_value(&self) -> Value {
861        self.clone()
862    }
863
864    #[inline]
865    fn value_type(&self) -> Type {
866        self.type_()
867    }
868}
869
870impl ToValue for &Value {
871    #[inline]
872    fn to_value(&self) -> Value {
873        (*self).clone()
874    }
875
876    #[inline]
877    fn value_type(&self) -> Type {
878        self.type_()
879    }
880}
881
882pub struct NopChecker;
883
884unsafe impl ValueTypeChecker for NopChecker {
885    type Error = Infallible;
886
887    #[inline]
888    fn check(_value: &Value) -> Result<(), Self::Error> {
889        Ok(())
890    }
891}
892
893unsafe impl<'a> FromValue<'a> for Value {
894    type Checker = NopChecker;
895
896    #[inline]
897    unsafe fn from_value(value: &'a Value) -> Self {
898        value.clone()
899    }
900}
901
902unsafe impl<'a> FromValue<'a> for &'a Value {
903    type Checker = NopChecker;
904
905    #[inline]
906    unsafe fn from_value(value: &'a Value) -> Self {
907        value
908    }
909}
910
911impl ToValue for SendValue {
912    #[inline]
913    fn to_value(&self) -> Value {
914        unsafe { from_glib_none(self.to_glib_none().0) }
915    }
916
917    #[inline]
918    fn value_type(&self) -> Type {
919        self.type_()
920    }
921}
922
923impl ToValue for &SendValue {
924    #[inline]
925    fn to_value(&self) -> Value {
926        unsafe { from_glib_none(self.to_glib_none().0) }
927    }
928
929    #[inline]
930    fn value_type(&self) -> Type {
931        self.type_()
932    }
933}
934
935impl StaticType for BoxedValue {
936    #[inline]
937    fn static_type() -> Type {
938        unsafe { from_glib(gobject_ffi::g_value_get_type()) }
939    }
940}
941
942crate::wrapper! {
943    // rustdoc-stripper-ignore-next
944    /// A version of [`Value`](struct.Value.html) for storing `Send` types, that implements Send
945    /// itself.
946    ///
947    /// See the [module documentation](index.html) for more details.
948    #[doc(alias = "GValue")]
949    pub struct SendValue(BoxedInline<gobject_ffi::GValue>);
950
951    match fn {
952        copy => |ptr| copy_value(ptr),
953        free => |ptr| free_value(ptr),
954        init => |ptr| init_value(ptr),
955        copy_into => |dest, src| copy_into_value(dest, src),
956        clear => |ptr| clear_value(ptr),
957    }
958}
959
960unsafe impl Send for SendValue {}
961
962impl SendValue {
963    // rustdoc-stripper-ignore-next
964    /// Consumes `SendValue` and returns the corresponding `GValue`.
965    #[inline]
966    pub fn into_raw(self) -> gobject_ffi::GValue {
967        unsafe {
968            let s = mem::ManuallyDrop::new(self);
969            ptr::read(&s.inner)
970        }
971    }
972    #[inline]
973    pub fn from_owned<T: Send + Into<Value>>(t: T) -> Self {
974        unsafe { Self::unsafe_from(t.into().into_raw()) }
975    }
976}
977
978impl fmt::Debug for SendValue {
979    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
980        write!(f, "({}) {}", self.type_(), self.content_debug_string())
981    }
982}
983
984impl Deref for SendValue {
985    type Target = Value;
986
987    #[inline]
988    fn deref(&self) -> &Value {
989        unsafe { &*(self as *const SendValue as *const Value) }
990    }
991}
992
993impl<'a, T: ?Sized + ToSendValue> From<&'a T> for SendValue {
994    #[inline]
995    fn from(value: &'a T) -> Self {
996        value.to_send_value()
997    }
998}
999
1000// rustdoc-stripper-ignore-next
1001/// Converts to `SendValue`.
1002pub trait ToSendValue: Send + ToValue {
1003    // rustdoc-stripper-ignore-next
1004    /// Returns a `SendValue` clone of `self`.
1005    fn to_send_value(&self) -> SendValue;
1006}
1007
1008impl<T: Send + ToValue + ?Sized> ToSendValue for T {
1009    #[inline]
1010    fn to_send_value(&self) -> SendValue {
1011        unsafe { SendValue::unsafe_from(self.to_value().into_raw()) }
1012    }
1013}
1014
1015unsafe impl<'a> FromValue<'a> for &'a str {
1016    type Checker = GenericValueTypeOrNoneChecker<Self>;
1017
1018    #[inline]
1019    unsafe fn from_value(value: &'a Value) -> Self {
1020        let ptr = gobject_ffi::g_value_get_string(value.to_glib_none().0);
1021        CStr::from_ptr(ptr).to_str().expect("Invalid UTF-8")
1022    }
1023}
1024
1025impl ToValue for str {
1026    fn to_value(&self) -> Value {
1027        unsafe {
1028            let mut value = Value::for_value_type::<String>();
1029
1030            gobject_ffi::g_value_take_string(value.to_glib_none_mut().0, self.to_glib_full());
1031
1032            value
1033        }
1034    }
1035
1036    fn value_type(&self) -> Type {
1037        String::static_type()
1038    }
1039}
1040
1041impl ToValue for &str {
1042    fn to_value(&self) -> Value {
1043        (*self).to_value()
1044    }
1045
1046    fn value_type(&self) -> Type {
1047        String::static_type()
1048    }
1049}
1050
1051impl ToValueOptional for str {
1052    fn to_value_optional(s: Option<&Self>) -> Value {
1053        let mut value = Value::for_value_type::<String>();
1054        unsafe {
1055            gobject_ffi::g_value_take_string(value.to_glib_none_mut().0, s.to_glib_full());
1056        }
1057
1058        value
1059    }
1060}
1061
1062impl ValueType for String {
1063    type Type = String;
1064}
1065
1066impl ValueTypeOptional for String {}
1067
1068unsafe impl<'a> FromValue<'a> for String {
1069    type Checker = GenericValueTypeOrNoneChecker<Self>;
1070
1071    unsafe fn from_value(value: &'a Value) -> Self {
1072        String::from(<&str>::from_value(value))
1073    }
1074}
1075
1076impl ToValue for String {
1077    fn to_value(&self) -> Value {
1078        <&str>::to_value(&self.as_str())
1079    }
1080
1081    fn value_type(&self) -> Type {
1082        String::static_type()
1083    }
1084}
1085
1086impl From<String> for Value {
1087    #[inline]
1088    fn from(s: String) -> Self {
1089        s.to_value()
1090    }
1091}
1092
1093impl ToValueOptional for String {
1094    fn to_value_optional(s: Option<&Self>) -> Value {
1095        <str>::to_value_optional(s.as_ref().map(|s| s.as_str()))
1096    }
1097}
1098
1099impl ValueType for Box<str> {
1100    type Type = String;
1101}
1102
1103impl ValueTypeOptional for Box<str> {}
1104
1105unsafe impl<'a> FromValue<'a> for Box<str> {
1106    type Checker = GenericValueTypeOrNoneChecker<Self>;
1107
1108    unsafe fn from_value(value: &'a Value) -> Self {
1109        Box::<str>::from(<&str>::from_value(value))
1110    }
1111}
1112
1113impl StaticType for Box<str> {
1114    fn static_type() -> Type {
1115        String::static_type()
1116    }
1117}
1118
1119impl ToValue for Box<str> {
1120    fn to_value(&self) -> Value {
1121        <&str>::to_value(&self.as_ref())
1122    }
1123
1124    fn value_type(&self) -> Type {
1125        String::static_type()
1126    }
1127}
1128
1129impl From<Box<str>> for Value {
1130    #[inline]
1131    fn from(s: Box<str>) -> Self {
1132        s.to_value()
1133    }
1134}
1135
1136impl ToValueOptional for Box<str> {
1137    fn to_value_optional(s: Option<&Self>) -> Value {
1138        <str>::to_value_optional(s.as_ref().map(|s| s.as_ref()))
1139    }
1140}
1141
1142impl ValueType for Vec<String> {
1143    type Type = Vec<String>;
1144}
1145
1146unsafe impl<'a> FromValue<'a> for Vec<String> {
1147    type Checker = GenericValueTypeChecker<Self>;
1148
1149    unsafe fn from_value(value: &'a Value) -> Self {
1150        let ptr = gobject_ffi::g_value_get_boxed(value.to_glib_none().0) as *const *const c_char;
1151        FromGlibPtrContainer::from_glib_none(ptr)
1152    }
1153}
1154
1155impl ToValue for Vec<String> {
1156    fn to_value(&self) -> Value {
1157        unsafe {
1158            let mut value = Value::for_value_type::<Self>();
1159            let ptr: *mut *mut c_char = self.to_glib_full();
1160            gobject_ffi::g_value_take_boxed(value.to_glib_none_mut().0, ptr as *const c_void);
1161            value
1162        }
1163    }
1164
1165    fn value_type(&self) -> Type {
1166        <Vec<String>>::static_type()
1167    }
1168}
1169
1170impl From<Vec<String>> for Value {
1171    #[inline]
1172    fn from(s: Vec<String>) -> Self {
1173        s.to_value()
1174    }
1175}
1176
1177impl ToValue for [&'_ str] {
1178    fn to_value(&self) -> Value {
1179        unsafe {
1180            let mut value = Value::for_value_type::<Vec<String>>();
1181            let ptr: *mut *mut c_char = self.to_glib_full();
1182            gobject_ffi::g_value_take_boxed(value.to_glib_none_mut().0, ptr as *const c_void);
1183            value
1184        }
1185    }
1186
1187    fn value_type(&self) -> Type {
1188        <Vec<String>>::static_type()
1189    }
1190}
1191
1192impl ToValue for &'_ [&'_ str] {
1193    fn to_value(&self) -> Value {
1194        unsafe {
1195            let mut value = Value::for_value_type::<Vec<String>>();
1196            let ptr: *mut *mut c_char = self.to_glib_full();
1197            gobject_ffi::g_value_take_boxed(value.to_glib_none_mut().0, ptr as *const c_void);
1198            value
1199        }
1200    }
1201
1202    fn value_type(&self) -> Type {
1203        <Vec<String>>::static_type()
1204    }
1205}
1206
1207impl ToValue for Path {
1208    fn to_value(&self) -> Value {
1209        unsafe {
1210            let mut value = Value::for_value_type::<PathBuf>();
1211
1212            gobject_ffi::g_value_take_string(value.to_glib_none_mut().0, self.to_glib_full());
1213
1214            value
1215        }
1216    }
1217
1218    fn value_type(&self) -> Type {
1219        PathBuf::static_type()
1220    }
1221}
1222
1223impl ToValue for &Path {
1224    fn to_value(&self) -> Value {
1225        (*self).to_value()
1226    }
1227
1228    fn value_type(&self) -> Type {
1229        PathBuf::static_type()
1230    }
1231}
1232
1233impl ToValueOptional for Path {
1234    fn to_value_optional(s: Option<&Self>) -> Value {
1235        let mut value = Value::for_value_type::<PathBuf>();
1236        unsafe {
1237            gobject_ffi::g_value_take_string(value.to_glib_none_mut().0, s.to_glib_full());
1238        }
1239
1240        value
1241    }
1242}
1243
1244impl ValueType for PathBuf {
1245    type Type = PathBuf;
1246}
1247
1248impl ValueTypeOptional for PathBuf {}
1249
1250unsafe impl<'a> FromValue<'a> for PathBuf {
1251    type Checker = GenericValueTypeOrNoneChecker<Self>;
1252
1253    unsafe fn from_value(value: &'a Value) -> Self {
1254        from_glib_none(gobject_ffi::g_value_get_string(value.to_glib_none().0))
1255    }
1256}
1257
1258impl ToValue for PathBuf {
1259    fn to_value(&self) -> Value {
1260        <&Path>::to_value(&self.as_path())
1261    }
1262
1263    fn value_type(&self) -> Type {
1264        PathBuf::static_type()
1265    }
1266}
1267
1268impl From<PathBuf> for Value {
1269    #[inline]
1270    fn from(s: PathBuf) -> Self {
1271        s.to_value()
1272    }
1273}
1274
1275impl ToValueOptional for PathBuf {
1276    fn to_value_optional(s: Option<&Self>) -> Value {
1277        <Path>::to_value_optional(s.as_ref().map(|s| s.as_path()))
1278    }
1279}
1280
1281impl ValueType for bool {
1282    type Type = Self;
1283}
1284
1285unsafe impl<'a> FromValue<'a> for bool {
1286    type Checker = GenericValueTypeChecker<Self>;
1287
1288    #[inline]
1289    unsafe fn from_value(value: &'a Value) -> Self {
1290        from_glib(gobject_ffi::g_value_get_boolean(value.to_glib_none().0))
1291    }
1292}
1293
1294impl ToValue for bool {
1295    #[inline]
1296    fn to_value(&self) -> Value {
1297        let mut value = Value::for_value_type::<Self>();
1298        unsafe {
1299            gobject_ffi::g_value_set_boolean(&mut value.inner, self.into_glib());
1300        }
1301        value
1302    }
1303
1304    #[inline]
1305    fn value_type(&self) -> Type {
1306        Self::static_type()
1307    }
1308}
1309
1310impl From<bool> for Value {
1311    #[inline]
1312    fn from(v: bool) -> Self {
1313        v.to_value()
1314    }
1315}
1316
1317impl ValueType for Pointer {
1318    type Type = Self;
1319}
1320
1321unsafe impl<'a> FromValue<'a> for Pointer {
1322    type Checker = GenericValueTypeChecker<Self>;
1323
1324    #[inline]
1325    unsafe fn from_value(value: &'a Value) -> Self {
1326        gobject_ffi::g_value_get_pointer(value.to_glib_none().0)
1327    }
1328}
1329
1330impl ToValue for Pointer {
1331    #[inline]
1332    fn to_value(&self) -> Value {
1333        let mut value = Value::for_value_type::<Self>();
1334        unsafe {
1335            gobject_ffi::g_value_set_pointer(&mut value.inner, *self);
1336        }
1337        value
1338    }
1339
1340    #[inline]
1341    fn value_type(&self) -> Type {
1342        <<Self as ValueType>::Type as StaticType>::static_type()
1343    }
1344}
1345
1346impl From<Pointer> for Value {
1347    #[inline]
1348    fn from(v: Pointer) -> Self {
1349        v.to_value()
1350    }
1351}
1352
1353impl ValueType for ptr::NonNull<Pointee> {
1354    type Type = Pointer;
1355}
1356
1357unsafe impl<'a> FromValue<'a> for ptr::NonNull<Pointee> {
1358    type Checker = GenericValueTypeOrNoneChecker<Self>;
1359
1360    #[inline]
1361    unsafe fn from_value(value: &'a Value) -> Self {
1362        ptr::NonNull::new_unchecked(Pointer::from_value(value))
1363    }
1364}
1365
1366impl ToValue for ptr::NonNull<Pointee> {
1367    #[inline]
1368    fn to_value(&self) -> Value {
1369        self.as_ptr().to_value()
1370    }
1371
1372    #[inline]
1373    fn value_type(&self) -> Type {
1374        <<Self as ValueType>::Type as StaticType>::static_type()
1375    }
1376}
1377
1378impl From<ptr::NonNull<Pointee>> for Value {
1379    #[inline]
1380    fn from(v: ptr::NonNull<Pointee>) -> Self {
1381        v.to_value()
1382    }
1383}
1384
1385impl ToValueOptional for ptr::NonNull<Pointee> {
1386    #[inline]
1387    fn to_value_optional(p: Option<&Self>) -> Value {
1388        p.map(|p| p.as_ptr()).unwrap_or(ptr::null_mut()).to_value()
1389    }
1390}
1391
1392macro_rules! numeric {
1393    ($name:ty, $get:expr, $set:expr) => {
1394        impl ValueType for $name {
1395            type Type = Self;
1396        }
1397
1398        unsafe impl<'a> FromValue<'a> for $name {
1399            type Checker = GenericValueTypeChecker<Self>;
1400
1401            #[inline]
1402            #[allow(clippy::redundant_closure_call)]
1403            unsafe fn from_value(value: &'a Value) -> Self {
1404                $get(value.to_glib_none().0)
1405            }
1406        }
1407
1408        impl ToValue for $name {
1409            #[inline]
1410            #[allow(clippy::redundant_closure_call)]
1411            fn to_value(&self) -> Value {
1412                let mut value = Value::for_value_type::<Self>();
1413                unsafe {
1414                    $set(&mut value.inner, *self);
1415                }
1416                value
1417            }
1418
1419            #[inline]
1420            fn value_type(&self) -> Type {
1421                Self::static_type()
1422            }
1423        }
1424
1425        impl From<$name> for Value {
1426            #[inline]
1427            fn from(v: $name) -> Self {
1428                v.to_value()
1429            }
1430        }
1431    };
1432}
1433macro_rules! not_zero {
1434    ($name:ty, $num:ty) => {
1435        impl ValueType for $name {
1436            type Type = $name;
1437        }
1438
1439        unsafe impl<'a> FromValue<'a> for $name {
1440            // Works because it returns `UnexpectedNone` if the value is NULL
1441            // by checking it against `0`.
1442            type Checker = GenericValueTypeOrNoneChecker<Self>;
1443
1444            #[inline]
1445            unsafe fn from_value(value: &'a Value) -> Self {
1446                let res = <$num>::from_value(value);
1447                Self::try_from(res).unwrap()
1448            }
1449        }
1450
1451        impl ToValue for $name {
1452            #[inline]
1453            fn to_value(&self) -> Value {
1454                <$num>::to_value(&<$num>::from(*self))
1455            }
1456
1457            #[inline]
1458            fn value_type(&self) -> Type {
1459                Self::static_type()
1460            }
1461        }
1462
1463        impl From<$name> for Value {
1464            #[inline]
1465            fn from(v: $name) -> Self {
1466                v.to_value()
1467            }
1468        }
1469
1470        impl ToValueOptional for $name {
1471            fn to_value_optional(s: Option<&Self>) -> Value {
1472                match s {
1473                    Some(x) => x.to_value(),
1474                    None => <$num>::to_value(&0),
1475                }
1476            }
1477        }
1478    };
1479}
1480
1481numeric!(
1482    i8,
1483    gobject_ffi::g_value_get_schar,
1484    gobject_ffi::g_value_set_schar
1485);
1486not_zero!(NonZeroI8, i8);
1487numeric!(
1488    u8,
1489    gobject_ffi::g_value_get_uchar,
1490    gobject_ffi::g_value_set_uchar
1491);
1492not_zero!(NonZeroU8, u8);
1493numeric!(
1494    i32,
1495    gobject_ffi::g_value_get_int,
1496    gobject_ffi::g_value_set_int
1497);
1498not_zero!(NonZeroI32, i32);
1499numeric!(
1500    u32,
1501    gobject_ffi::g_value_get_uint,
1502    gobject_ffi::g_value_set_uint
1503);
1504not_zero!(NonZeroU32, u32);
1505numeric!(
1506    i64,
1507    gobject_ffi::g_value_get_int64,
1508    gobject_ffi::g_value_set_int64
1509);
1510not_zero!(NonZeroI64, i64);
1511numeric!(
1512    u64,
1513    gobject_ffi::g_value_get_uint64,
1514    gobject_ffi::g_value_set_uint64
1515);
1516not_zero!(NonZeroU64, u64);
1517numeric!(
1518    crate::ILong,
1519    |v| gobject_ffi::g_value_get_long(v).into(),
1520    |v, i: crate::ILong| gobject_ffi::g_value_set_long(v, i.0)
1521);
1522numeric!(
1523    crate::ULong,
1524    |v| gobject_ffi::g_value_get_ulong(v).into(),
1525    |v, i: crate::ULong| gobject_ffi::g_value_set_ulong(v, i.0)
1526);
1527numeric!(
1528    f32,
1529    gobject_ffi::g_value_get_float,
1530    gobject_ffi::g_value_set_float
1531);
1532numeric!(
1533    f64,
1534    gobject_ffi::g_value_get_double,
1535    gobject_ffi::g_value_set_double
1536);
1537
1538impl ValueType for char {
1539    type Type = u32;
1540}
1541
1542unsafe impl<'a> FromValue<'a> for char {
1543    type Checker = CharTypeChecker;
1544
1545    #[inline]
1546    unsafe fn from_value(value: &'a Value) -> Self {
1547        let res: u32 = gobject_ffi::g_value_get_uint(value.to_glib_none().0);
1548        // safe because the check is done by `Self::Checker`
1549        char::from_u32_unchecked(res)
1550    }
1551}
1552
1553impl ToValue for char {
1554    #[inline]
1555    fn to_value(&self) -> Value {
1556        let mut value = Value::for_value_type::<Self>();
1557        unsafe {
1558            gobject_ffi::g_value_set_uint(&mut value.inner, *self as u32);
1559        }
1560        value
1561    }
1562
1563    #[inline]
1564    fn value_type(&self) -> Type {
1565        crate::Type::U32
1566    }
1567}
1568
1569impl From<char> for Value {
1570    #[inline]
1571    fn from(v: char) -> Self {
1572        v.to_value()
1573    }
1574}
1575
1576// rustdoc-stripper-ignore-next
1577/// A [`Value`] containing another [`Value`].
1578pub struct BoxedValue(pub Value);
1579
1580impl Deref for BoxedValue {
1581    type Target = Value;
1582
1583    #[inline]
1584    fn deref(&self) -> &Value {
1585        &self.0
1586    }
1587}
1588
1589impl ValueType for BoxedValue {
1590    type Type = BoxedValue;
1591}
1592
1593impl ValueTypeOptional for BoxedValue {}
1594
1595unsafe impl<'a> FromValue<'a> for BoxedValue {
1596    type Checker = GenericValueTypeOrNoneChecker<Self>;
1597
1598    #[inline]
1599    unsafe fn from_value(value: &'a Value) -> Self {
1600        let ptr = gobject_ffi::g_value_get_boxed(value.to_glib_none().0);
1601        BoxedValue(from_glib_none(ptr as *const gobject_ffi::GValue))
1602    }
1603}
1604
1605impl ToValue for BoxedValue {
1606    #[inline]
1607    fn to_value(&self) -> Value {
1608        unsafe {
1609            let mut value = Value::for_value_type::<BoxedValue>();
1610
1611            gobject_ffi::g_value_set_boxed(
1612                value.to_glib_none_mut().0,
1613                self.0.to_glib_none().0 as ffi::gconstpointer,
1614            );
1615
1616            value
1617        }
1618    }
1619
1620    #[inline]
1621    fn value_type(&self) -> Type {
1622        BoxedValue::static_type()
1623    }
1624}
1625
1626impl From<BoxedValue> for Value {
1627    #[inline]
1628    fn from(v: BoxedValue) -> Self {
1629        unsafe {
1630            let mut value = Value::for_value_type::<BoxedValue>();
1631
1632            gobject_ffi::g_value_take_boxed(
1633                value.to_glib_none_mut().0,
1634                v.0.to_glib_full() as ffi::gconstpointer,
1635            );
1636
1637            value
1638        }
1639    }
1640}
1641
1642impl ToValueOptional for BoxedValue {
1643    #[inline]
1644    fn to_value_optional(s: Option<&Self>) -> Value {
1645        let mut value = Value::for_value_type::<Self>();
1646        unsafe {
1647            gobject_ffi::g_value_set_boxed(
1648                value.to_glib_none_mut().0,
1649                s.map(|s| &s.0).to_glib_none().0 as ffi::gconstpointer,
1650            );
1651        }
1652
1653        value
1654    }
1655}
1656
1657#[cfg(test)]
1658mod tests {
1659    use std::num::NonZeroI32;
1660
1661    use super::*;
1662
1663    #[test]
1664    fn test_send_value() {
1665        use std::thread;
1666
1667        let v = SendValue::from(&1i32);
1668
1669        // Must compile, while it must fail with Value
1670        thread::spawn(move || drop(v)).join().unwrap();
1671    }
1672
1673    #[test]
1674    fn test_strv() {
1675        let v = ["123", "456"].to_value();
1676        assert_eq!(
1677            v.get::<Vec<GString>>(),
1678            Ok(vec![GString::from("123"), GString::from("456")])
1679        );
1680
1681        let v = vec![String::from("123"), String::from("456")].to_value();
1682        assert_eq!(
1683            v.get::<Vec<GString>>(),
1684            Ok(vec![GString::from("123"), GString::from("456")])
1685        );
1686    }
1687
1688    #[test]
1689    fn test_from_to_value() {
1690        let v = 123.to_value();
1691        assert_eq!(v.get(), Ok(123));
1692        assert_eq!(
1693            v.get::<&str>(),
1694            Err(ValueTypeMismatchError::new(Type::I32, Type::STRING).into())
1695        );
1696        assert_eq!(
1697            v.get::<bool>(),
1698            Err(ValueTypeMismatchError::new(Type::I32, Type::BOOL))
1699        );
1700
1701        // Check if &str / str / Option<&str> etc can be converted and retrieved
1702        let v_str = "test".to_value();
1703        assert_eq!(v_str.get::<&str>(), Ok("test"));
1704        assert_eq!(v_str.get::<Option<&str>>(), Ok(Some("test")));
1705        assert_eq!(
1706            v_str.get::<i32>(),
1707            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1708        );
1709
1710        let some_v = Some("test").to_value();
1711        assert_eq!(some_v.get::<&str>(), Ok("test"));
1712        assert_eq!(some_v.get_owned::<String>(), Ok("test".to_string()));
1713        assert_eq!(
1714            some_v.get_owned::<Option<String>>(),
1715            Ok(Some("test".to_string()))
1716        );
1717        assert_eq!(some_v.get::<Option<&str>>(), Ok(Some("test")));
1718        assert_eq!(
1719            some_v.get::<i32>(),
1720            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1721        );
1722
1723        let none_str: Option<&str> = None;
1724        let none_v = none_str.to_value();
1725        assert_eq!(none_v.get::<Option<&str>>(), Ok(None));
1726        assert_eq!(
1727            none_v.get::<i32>(),
1728            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1729        );
1730
1731        // Check if owned T and Option<T> can be converted and retrieved
1732        let v_str = String::from("test").to_value();
1733        assert_eq!(v_str.get::<String>(), Ok(String::from("test")));
1734        assert_eq!(
1735            v_str.get::<Option<String>>(),
1736            Ok(Some(String::from("test")))
1737        );
1738        assert_eq!(
1739            v_str.get::<i32>(),
1740            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1741        );
1742
1743        let some_v = Some(String::from("test")).to_value();
1744        assert_eq!(some_v.get::<String>(), Ok(String::from("test")));
1745        assert_eq!(
1746            some_v.get::<Option<String>>(),
1747            Ok(Some(String::from("test")))
1748        );
1749        assert_eq!(
1750            some_v.get::<i32>(),
1751            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1752        );
1753
1754        let none_str: Option<String> = None;
1755        let none_v = none_str.to_value();
1756        assert_eq!(none_v.get::<Option<String>>(), Ok(None));
1757        assert_eq!(
1758            none_v.get::<i32>(),
1759            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1760        );
1761
1762        let c_v = 'c'.to_value();
1763        assert_eq!(c_v.get::<char>(), Ok('c'));
1764
1765        let c_v = 0xFFFFFFFFu32.to_value();
1766        assert_eq!(
1767            c_v.get::<char>(),
1768            Err(InvalidCharError::CharConversionError)
1769        );
1770
1771        // Check if &T and Option<&T> can be converted and retrieved
1772        let v_str = String::from("test").to_value();
1773        assert_eq!(v_str.get::<String>(), Ok(String::from("test")));
1774        assert_eq!(
1775            v_str.get::<Option<String>>(),
1776            Ok(Some(String::from("test")))
1777        );
1778        assert_eq!(
1779            v_str.get::<i32>(),
1780            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1781        );
1782
1783        let some_v = Some(&String::from("test")).to_value();
1784        assert_eq!(some_v.get::<String>(), Ok(String::from("test")));
1785        assert_eq!(
1786            some_v.get::<Option<String>>(),
1787            Ok(Some(String::from("test")))
1788        );
1789        assert_eq!(
1790            some_v.get::<i32>(),
1791            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1792        );
1793
1794        let none_str: Option<&String> = None;
1795        let none_v = none_str.to_value();
1796        assert_eq!(none_v.get::<Option<String>>(), Ok(None));
1797        assert_eq!(
1798            none_v.get::<i32>(),
1799            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1800        );
1801
1802        // Check handling of NonZeroT
1803        let v = NonZeroI32::new(123).unwrap().to_value();
1804        assert_eq!(v.get::<NonZeroI32>(), Ok(NonZeroI32::new(123).unwrap()));
1805
1806        let v = 123i32.to_value();
1807        assert_eq!(v.get::<NonZeroI32>(), Ok(NonZeroI32::new(123).unwrap()));
1808
1809        let v = 0i32.to_value();
1810        assert_eq!(
1811            v.get::<NonZeroI32>(),
1812            Err(ValueTypeMismatchOrNoneError::UnexpectedNone)
1813        );
1814
1815        assert_eq!(v.get::<Option<NonZeroI32>>(), Ok(None));
1816    }
1817
1818    #[test]
1819    fn test_transform() {
1820        let v = 123.to_value();
1821        let v2 = v
1822            .transform::<String>()
1823            .expect("Failed to transform to string");
1824        assert_eq!(v2.get::<&str>(), Ok("123"));
1825    }
1826
1827    #[test]
1828    fn test_into_raw() {
1829        unsafe {
1830            let mut v = 123.to_value().into_raw();
1831            assert_eq!(gobject_ffi::g_type_check_value(&v), ffi::GTRUE);
1832            assert_eq!(gobject_ffi::g_value_get_int(&v), 123);
1833            gobject_ffi::g_value_unset(&mut v);
1834        }
1835    }
1836
1837    #[test]
1838    fn test_debug() {
1839        fn value_debug_string<T: ToValue>(val: T) -> String {
1840            format!("{:?}", val.to_value())
1841        }
1842
1843        assert_eq!(value_debug_string(1u32), "(guint) 1");
1844        assert_eq!(value_debug_string(2i32), "(gint) 2");
1845        assert_eq!(value_debug_string(false), "(gboolean) FALSE");
1846        assert_eq!(value_debug_string("FooBar"), r#"(gchararray) "FooBar""#);
1847    }
1848}