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