glib/
value.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3// rustdoc-stripper-ignore-next
4//! `Value` binding and helper traits.
5//!
6//! The type of a [`Value`](struct.Value.html) is dynamic in that it generally
7//! isn't known at compile time but once created a `Value` can't change its
8//! type.
9//!
10//! [`SendValue`](struct.SendValue.html) is a version of [`Value`](struct.Value.html)
11//! that can only store types that implement `Send` and as such implements `Send` itself. It
12//! dereferences to `Value` so it can be used everywhere `Value` references are accepted.
13//!
14//! Supported types are `bool`, `i8`, `u8`, `i32`, `u32`, `i64`, `u64`, `f32`,
15//! `f64`, `String` and objects (`T: IsA<Object>`).
16//!
17//! # Examples
18//!
19//! ```
20//! use glib::prelude::*; // or `use gtk::prelude::*;`
21//! use glib::Value;
22//!
23//! // Value implement From<&i32>, From<&str> and From<Option<&str>>.
24//! // Another option is the `ToValue` trait.
25//! let mut num = 10.to_value();
26//! let mut hello = Value::from("Hello!");
27//! let none: Option<&str> = None;
28//! let str_none = none.to_value();
29//!
30//! // `is` tests the type of the value.
31//! assert!(num.is::<i32>());
32//! assert!(hello.is::<String>());
33//!
34//! // `get` tries to get an optional value of the specified type
35//! // and returns an `Err` if the type doesn't match.
36//! assert_eq!(num.get(), Ok(10));
37//! assert!(num.get::<String>().is_err());
38//! assert_eq!(hello.get(), Ok(String::from("Hello!")));
39//! assert_eq!(hello.get::<String>(), Ok(String::from("Hello!")));
40//! assert_eq!(str_none.get::<Option<String>>(), Ok(None));
41//! ```
42
43use std::{
44    convert::Infallible,
45    error,
46    ffi::CStr,
47    fmt, mem,
48    num::{NonZeroI32, NonZeroI64, NonZeroI8, NonZeroU32, NonZeroU64, NonZeroU8},
49    ops::Deref,
50    path::{Path, PathBuf},
51    ptr,
52};
53
54use libc::{c_char, c_void};
55
56use crate::{
57    ffi, gobject_ffi,
58    gstring::GString,
59    prelude::*,
60    translate::*,
61    types::{Pointee, Pointer, Type},
62    GStr,
63};
64
65// rustdoc-stripper-ignore-next
66/// A type that can be stored in `Value`s.
67pub trait ValueType: ToValue + for<'a> FromValue<'a> + 'static {
68    // rustdoc-stripper-ignore-next
69    /// Type to get the `Type` from.
70    ///
71    /// This exists only for handling optional types.
72    // FIXME: Should default to Self once associated type defaults are stabilized
73    // https://github.com/rust-lang/rust/issues/29661
74    type Type: StaticType;
75}
76
77// rustdoc-stripper-ignore-next
78/// A type that can be stored in `Value`s and is optional.
79///
80/// These are types were storing an `Option` is valid. Examples are `String` and all object types.
81pub trait ValueTypeOptional:
82    ValueType + ToValueOptional + FromValueOptional<'static> + StaticType
83{
84}
85
86impl<T, C, E> ValueType for Option<T>
87where
88    T: for<'a> FromValue<'a, Checker = C> + ValueTypeOptional + StaticType + 'static,
89    C: ValueTypeChecker<Error = ValueTypeMismatchOrNoneError<E>>,
90    E: error::Error + Send + Sized + 'static,
91{
92    type Type = T::Type;
93}
94
95// rustdoc-stripper-ignore-next
96/// Trait for `Value` type checkers.
97pub unsafe trait ValueTypeChecker {
98    type Error: error::Error + Send + Sized + 'static;
99
100    fn check(value: &Value) -> Result<(), Self::Error>;
101}
102
103// rustdoc-stripper-ignore-next
104/// An error returned from the [`get`](struct.Value.html#method.get) function
105/// on a [`Value`](struct.Value.html) for non-optional types an `Option`.
106#[derive(Clone, PartialEq, Eq, Debug)]
107pub struct ValueTypeMismatchError {
108    actual: Type,
109    requested: Type,
110}
111
112impl ValueTypeMismatchError {
113    pub fn new(actual: Type, requested: Type) -> Self {
114        Self { actual, requested }
115    }
116}
117
118impl ValueTypeMismatchError {
119    pub fn actual_type(&self) -> Type {
120        self.actual
121    }
122
123    pub fn requested_type(&self) -> Type {
124        self.requested
125    }
126}
127
128impl fmt::Display for ValueTypeMismatchError {
129    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
130        write!(
131            f,
132            "Value type mismatch. Actual {:?}, requested {:?}",
133            self.actual_type(),
134            self.requested_type(),
135        )
136    }
137}
138
139impl error::Error for ValueTypeMismatchError {}
140
141impl From<Infallible> for ValueTypeMismatchError {
142    fn from(e: Infallible) -> Self {
143        match e {}
144    }
145}
146
147// rustdoc-stripper-ignore-next
148/// Generic `Value` type checker for types.
149pub struct GenericValueTypeChecker<T>(std::marker::PhantomData<T>);
150
151unsafe impl<T: StaticType> ValueTypeChecker for GenericValueTypeChecker<T> {
152    type Error = ValueTypeMismatchError;
153
154    #[doc(alias = "g_type_check_value_holds")]
155    #[inline]
156    fn check(value: &Value) -> Result<(), Self::Error> {
157        unsafe {
158            if gobject_ffi::g_type_check_value_holds(&value.inner, T::static_type().into_glib())
159                == ffi::GFALSE
160            {
161                Err(ValueTypeMismatchError::new(
162                    Type::from_glib(value.inner.g_type),
163                    T::static_type(),
164                ))
165            } else {
166                Ok(())
167            }
168        }
169    }
170}
171
172pub struct CharTypeChecker();
173unsafe impl ValueTypeChecker for CharTypeChecker {
174    type Error = InvalidCharError;
175
176    #[inline]
177    fn check(value: &Value) -> Result<(), Self::Error> {
178        let v = value.get::<u32>()?;
179        match char::from_u32(v) {
180            Some(_) => Ok(()),
181            None => Err(InvalidCharError::CharConversionError),
182        }
183    }
184}
185
186// rustdoc-stripper-ignore-next
187/// An error returned from the [`get`](struct.Value.html#method.get) function
188/// on a [`Value`](struct.Value.html) for char (which are internally u32) types.
189#[derive(Clone, PartialEq, Eq, Debug)]
190pub enum InvalidCharError {
191    WrongValueType(ValueTypeMismatchError),
192    CharConversionError,
193}
194impl fmt::Display for InvalidCharError {
195    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
196        match self {
197            Self::WrongValueType(err) => err.fmt(f),
198            Self::CharConversionError => {
199                write!(f, "couldn't convert to char, invalid u32 contents")
200            }
201        }
202    }
203}
204impl error::Error for InvalidCharError {}
205
206impl From<ValueTypeMismatchError> for InvalidCharError {
207    fn from(err: ValueTypeMismatchError) -> Self {
208        Self::WrongValueType(err)
209    }
210}
211
212impl From<Infallible> for InvalidCharError {
213    fn from(e: Infallible) -> Self {
214        match e {}
215    }
216}
217
218// rustdoc-stripper-ignore-next
219/// An error returned from the [`get`](struct.Value.html#method.get)
220/// function on a [`Value`](struct.Value.html) for optional types.
221#[derive(Clone, PartialEq, Eq, Debug)]
222pub enum ValueTypeMismatchOrNoneError<E: error::Error> {
223    WrongValueType(E),
224    UnexpectedNone,
225}
226
227impl<E: error::Error> fmt::Display for ValueTypeMismatchOrNoneError<E> {
228    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
229        match self {
230            Self::WrongValueType(err) => <E as fmt::Display>::fmt(err, f),
231            Self::UnexpectedNone => write!(f, "Unexpected None",),
232        }
233    }
234}
235
236impl<E: error::Error> error::Error for ValueTypeMismatchOrNoneError<E> {}
237
238impl<E: error::Error> From<E> for ValueTypeMismatchOrNoneError<E> {
239    fn from(err: E) -> Self {
240        Self::WrongValueType(err)
241    }
242}
243
244// rustdoc-stripper-ignore-next
245/// Generic `Value` type checker for optional types.
246pub struct GenericValueTypeOrNoneChecker<T>(std::marker::PhantomData<T>);
247
248unsafe impl<T: StaticType> ValueTypeChecker for GenericValueTypeOrNoneChecker<T> {
249    type Error = ValueTypeMismatchOrNoneError<ValueTypeMismatchError>;
250
251    #[inline]
252    fn check(value: &Value) -> Result<(), Self::Error> {
253        GenericValueTypeChecker::<T>::check(value)?;
254
255        unsafe {
256            // Values are always zero-initialized so even if pointers are only 32 bits then the
257            // whole 64 bit value will be 0 for NULL pointers.
258            if value.inner.data[0].v_uint64 == 0 {
259                return Err(Self::Error::UnexpectedNone);
260            }
261        }
262
263        Ok(())
264    }
265}
266
267// rustdoc-stripper-ignore-next
268/// Trait to retrieve the contained value from a `Value`.
269///
270/// Usually this would not be used directly but from the [`get`](struct.Value.html#method.get)
271/// function on a [`Value`](struct.Value.html)
272pub unsafe trait FromValue<'a>: Sized {
273    // rustdoc-stripper-ignore-next
274    /// Value type checker.
275    type Checker: ValueTypeChecker;
276
277    // rustdoc-stripper-ignore-next
278    /// Get the contained value from a `Value`.
279    ///
280    /// # Safety
281    /// `Self::Checker::check()` must be called first and must not fail.
282    unsafe fn from_value(value: &'a Value) -> Self;
283}
284
285// rustdoc-stripper-ignore-next
286/// Trait for types that implement `FromValue` and are Optional.
287///
288/// This trait is auto-implemented for the appropriate types and is sealed.
289pub trait FromValueOptional<'a>: private::FromValueOptionalSealed<'a> {}
290
291impl<'a, T, C, E> FromValueOptional<'a> for T
292where
293    T: FromValue<'a, Checker = C>,
294    C: ValueTypeChecker<Error = ValueTypeMismatchOrNoneError<E>>,
295    E: error::Error + Send + Sized + 'static,
296{
297}
298
299mod private {
300    pub trait FromValueOptionalSealed<'a> {}
301
302    impl<'a, T, C, E> FromValueOptionalSealed<'a> for T
303    where
304        T: super::FromValue<'a, Checker = C>,
305        C: super::ValueTypeChecker<Error = super::ValueTypeMismatchOrNoneError<E>>,
306        E: super::error::Error + Send + Sized + 'static,
307    {
308    }
309}
310
311// rustdoc-stripper-ignore-next
312/// Wrapped `Value` type checker for optional types.
313pub struct ValueTypeOrNoneChecker<T, C, E>(std::marker::PhantomData<(T, C, E)>);
314
315unsafe impl<'a, T, C, E> ValueTypeChecker for ValueTypeOrNoneChecker<T, C, E>
316where
317    T: FromValue<'a, Checker = C> + StaticType,
318    C: ValueTypeChecker<Error = ValueTypeMismatchOrNoneError<E>>,
319    E: error::Error + Send + Sized + 'static,
320{
321    type Error = E;
322
323    #[inline]
324    fn check(value: &Value) -> Result<(), Self::Error> {
325        match T::Checker::check(value) {
326            Err(ValueTypeMismatchOrNoneError::UnexpectedNone) => Ok(()),
327            Err(ValueTypeMismatchOrNoneError::WrongValueType(err)) => Err(err),
328            Ok(_) => Ok(()),
329        }
330    }
331}
332
333// rustdoc-stripper-ignore-next
334/// Blanket implementation for all optional types.
335unsafe impl<'a, T, C, E> FromValue<'a> for Option<T>
336where
337    T: FromValue<'a, Checker = C> + StaticType,
338    C: ValueTypeChecker<Error = ValueTypeMismatchOrNoneError<E>>,
339    E: error::Error + Send + Sized + 'static,
340{
341    type Checker = ValueTypeOrNoneChecker<T, C, E>;
342
343    #[inline]
344    unsafe fn from_value(value: &'a Value) -> Self {
345        match T::Checker::check(value) {
346            Err(ValueTypeMismatchOrNoneError::UnexpectedNone) => None,
347            Err(ValueTypeMismatchOrNoneError::WrongValueType(_err)) => {
348                // This should've been caught by the caller already.
349                unreachable!();
350            }
351            Ok(_) => Some(T::from_value(value)),
352        }
353    }
354}
355
356// rustdoc-stripper-ignore-next
357/// Trait to convert a value to a `Value`.
358///
359/// Similar to other common conversion traits, the following invariants are guaranteed:
360///
361/// - **Invertibility**: `x.to_value().get().unwrap() == x`. In words, [`FromValue`] is the inverse of `ToValue`.
362/// - **Idempotence**: `x.to_value() == x.to_value().to_value()`.
363///   In words, applying `ToValue` multiple times yields the same result as applying it once.
364///   Idempotence also applies the other way around: `value.get::<Value>()` is a no-op.
365///
366/// There is also the possibility to wrap values within values, see [`BoxedValue`]. All (un-)boxing needs to be done
367/// manually, and will be preserved under the conversion methods.
368///
369/// The conversion methods may cause values to be cloned, which may result in reference counter changes or heap allocations depending
370/// on the source and target type.
371pub trait ToValue {
372    // rustdoc-stripper-ignore-next
373    /// Convert a value to a `Value`.
374    fn to_value(&self) -> Value;
375
376    // rustdoc-stripper-ignore-next
377    /// Returns the type identifier of `self`.
378    ///
379    /// This is the type of the value to be returned by `to_value`.
380    fn value_type(&self) -> Type;
381}
382
383// rustdoc-stripper-ignore-next
384/// Blanket implementation for all references.
385impl<T: ToValue + StaticType> ToValue for &T {
386    #[inline]
387    fn to_value(&self) -> Value {
388        T::to_value(*self)
389    }
390
391    #[inline]
392    fn value_type(&self) -> Type {
393        T::static_type()
394    }
395}
396
397// rustdoc-stripper-ignore-next
398/// Trait to convert an `Option` to a `Value` for optional types.
399pub trait ToValueOptional {
400    // rustdoc-stripper-ignore-next
401    /// Convert an `Option` to a `Value`.
402    #[allow(clippy::wrong_self_convention)]
403    fn to_value_optional(s: Option<&Self>) -> Value;
404}
405
406// rustdoc-stripper-ignore-next
407/// Blanket implementation for all optional types.
408impl<T: ToValueOptional + StaticType> ToValue for Option<T> {
409    #[inline]
410    fn to_value(&self) -> Value {
411        T::to_value_optional(self.as_ref())
412    }
413
414    #[inline]
415    fn value_type(&self) -> Type {
416        T::static_type()
417    }
418}
419
420impl<T: Into<Value> + ToValueOptional> From<Option<T>> for Value {
421    #[inline]
422    fn from(t: Option<T>) -> Self {
423        match t {
424            None => T::to_value_optional(None),
425            Some(t) => t.into(),
426        }
427    }
428}
429
430impl<T: ToValueOptional + StaticType> StaticType for Option<T> {
431    #[inline]
432    fn static_type() -> Type {
433        T::static_type()
434    }
435}
436
437impl<T: ToValueOptional + StaticType + ?Sized> ToValueOptional for &T {
438    #[inline]
439    fn to_value_optional(s: Option<&Self>) -> Value {
440        <T as ToValueOptional>::to_value_optional(s.as_ref().map(|s| **s))
441    }
442}
443
444#[inline]
445unsafe fn copy_value(value: *const gobject_ffi::GValue) -> *mut gobject_ffi::GValue {
446    let copy = ffi::g_malloc0(mem::size_of::<gobject_ffi::GValue>()) as *mut gobject_ffi::GValue;
447    copy_into_value(copy, value);
448    copy
449}
450
451#[inline]
452unsafe fn free_value(value: *mut gobject_ffi::GValue) {
453    clear_value(value);
454    ffi::g_free(value as *mut _);
455}
456
457#[inline]
458unsafe fn init_value(value: *mut gobject_ffi::GValue) {
459    ptr::write(value, mem::zeroed());
460}
461
462#[inline]
463unsafe fn copy_into_value(dest: *mut gobject_ffi::GValue, src: *const gobject_ffi::GValue) {
464    gobject_ffi::g_value_init(dest, (*src).g_type);
465    gobject_ffi::g_value_copy(src, dest);
466}
467
468#[inline]
469unsafe fn clear_value(value: *mut gobject_ffi::GValue) {
470    // Before GLib 2.48, unsetting a zeroed GValue would give critical warnings
471    // https://bugzilla.gnome.org/show_bug.cgi?id=755766
472    if (*value).g_type != gobject_ffi::G_TYPE_INVALID {
473        gobject_ffi::g_value_unset(value);
474    }
475}
476
477// TODO: Should use impl !Send for Value {} once stable
478crate::wrapper! {
479    // rustdoc-stripper-ignore-next
480    /// A generic value capable of carrying various types.
481    ///
482    /// Once created the type of the value can't be changed.
483    ///
484    /// Some types (e.g. `String` and objects) support `None` values while others
485    /// (e.g. numeric types) don't.
486    ///
487    /// `Value` does not implement the `Send` trait, but [`SendValue`](struct.SendValue.html) can be
488    /// used instead.
489    ///
490    /// See the [module documentation](index.html) for more details.
491    // rustdoc-stripper-ignore-next-stop
492    /// An opaque structure used to hold different types of values.
493    ///
494    /// Before it can be used, a `GValue` has to be initialized to a specific type by
495    /// calling [method[`Object`][crate::Object].init] on it.
496    ///
497    /// Many types which are stored within a `GValue` need to allocate data on the
498    /// heap, so [method[`Object`][crate::Object].unset] must always be called on a `GValue` to
499    /// free any such data once you’re finished with the `GValue`, even if the
500    /// `GValue` itself is stored on the stack.
501    ///
502    /// The data within the structure has protected scope: it is accessible only
503    /// to functions within a [struct[`Object`][crate::Object]] structure, or
504    /// implementations of the `g_value_*()` API. That is, code which implements new
505    /// fundamental types.
506    ///
507    /// `GValue` users cannot make any assumptions about how data is stored
508    /// within the 2 element `data` union, and the `g_type` member should
509    /// only be accessed through the [func[`Object`][crate::Object]] macro and related
510    /// macros.
511    #[doc(alias = "GValue")]
512    pub struct Value(BoxedInline<gobject_ffi::GValue>);
513
514    match fn {
515        copy => |ptr| copy_value(ptr),
516        free => |ptr| free_value(ptr),
517        init => |ptr| init_value(ptr),
518        copy_into => |dest, src| copy_into_value(dest, src),
519        clear => |ptr| clear_value(ptr),
520    }
521}
522
523impl Value {
524    // rustdoc-stripper-ignore-next
525    /// Creates a new `Value` that is initialized with `type_`.
526    ///
527    /// # Panics
528    ///
529    /// If `type_` can't be stored in a `Value` this function panics.
530    pub fn from_type(type_: Type) -> Self {
531        unsafe {
532            assert_eq!(
533                gobject_ffi::g_type_check_is_value_type(type_.into_glib()),
534                ffi::GTRUE
535            );
536            Self::from_type_unchecked(type_)
537        }
538    }
539
540    // rustdoc-stripper-ignore-next
541    /// Creates a new `Value` that is initialized with `type_`.
542    ///
543    /// # SAFETY
544    ///
545    /// This must be called with a valid `type_` that can be stored in `Value`s.
546    #[inline]
547    pub unsafe fn from_type_unchecked(type_: Type) -> Self {
548        unsafe {
549            let mut value = Value::uninitialized();
550            gobject_ffi::g_value_init(value.to_glib_none_mut().0, type_.into_glib());
551            value
552        }
553    }
554
555    // rustdoc-stripper-ignore-next
556    /// Creates a new `Value` that is initialized for a given `ValueType`.
557    #[inline]
558    pub fn for_value_type<T: ValueType>() -> Self {
559        unsafe { Value::from_type_unchecked(T::Type::static_type()) }
560    }
561
562    // rustdoc-stripper-ignore-next
563    /// Creates a new `String`-typed `Value` from a `'static` string.
564    #[inline]
565    #[doc(alias = "g_value_set_static_string")]
566    pub fn from_static_str(s: &'static GStr) -> Self {
567        unsafe {
568            let mut v = Self::from_type_unchecked(Type::STRING);
569            gobject_ffi::g_value_set_static_string(v.to_glib_none_mut().0, s.as_ptr());
570            v
571        }
572    }
573
574    #[cfg(feature = "v2_66")]
575    #[cfg_attr(docsrs, doc(cfg(feature = "v2_66")))]
576    // rustdoc-stripper-ignore-next
577    /// Creates a new `String`-typed `Value` from a `'static` string that is also assumed to be
578    /// interned.
579    #[inline]
580    #[doc(alias = "g_value_set_interned_string")]
581    pub fn from_interned_str(s: &'static GStr) -> Self {
582        unsafe {
583            let mut v = Self::from_type_unchecked(Type::STRING);
584            gobject_ffi::g_value_set_interned_string(v.to_glib_none_mut().0, s.as_ptr());
585            v
586        }
587    }
588
589    // rustdoc-stripper-ignore-next
590    /// Tries to get a value of type `T`.
591    ///
592    /// Returns `Ok` if the type is correct.
593    #[inline]
594    pub fn get<'a, T>(
595        &'a self,
596    ) -> Result<T, <<T as FromValue<'a>>::Checker as ValueTypeChecker>::Error>
597    where
598        T: FromValue<'a>,
599    {
600        unsafe {
601            T::Checker::check(self)?;
602            Ok(T::from_value(self))
603        }
604    }
605
606    // rustdoc-stripper-ignore-next
607    /// Tries to get a value of an owned type `T`.
608    #[inline]
609    pub fn get_owned<T>(
610        &self,
611    ) -> Result<T, <<T as FromValue<'_>>::Checker as ValueTypeChecker>::Error>
612    where
613        T: for<'b> FromValue<'b> + 'static,
614    {
615        unsafe {
616            T::Checker::check(self)?;
617            Ok(FromValue::from_value(self))
618        }
619    }
620
621    // rustdoc-stripper-ignore-next
622    /// Returns `true` if the type of the value corresponds to `T`
623    /// or is a sub-type of `T`.
624    #[inline]
625    pub fn is<T: StaticType>(&self) -> bool {
626        self.is_type(T::static_type())
627    }
628
629    // rustdoc-stripper-ignore-next
630    /// Returns `true` if the type of the value corresponds to `type_`
631    /// or is a sub-type of `type_`.
632    #[inline]
633    pub fn is_type(&self, type_: Type) -> bool {
634        self.type_().is_a(type_)
635    }
636
637    // rustdoc-stripper-ignore-next
638    /// Returns the type of the value.
639    #[inline]
640    pub fn type_(&self) -> Type {
641        unsafe { from_glib(self.inner.g_type) }
642    }
643
644    // rustdoc-stripper-ignore-next
645    /// Returns whether `Value`s of type `src` can be transformed to type `dst`.
646    // rustdoc-stripper-ignore-next-stop
647    /// Checks whether [method[`Object`][crate::Object].transform] is able to transform values
648    /// of type `src_type` into values of type `dest_type`.
649    ///
650    /// Note that for the types to be transformable, they must be compatible or a
651    /// transformation function must be registered using
652    /// [func[`Object`][crate::Object].register_transform_func].
653    /// ## `src_type`
654    /// source type
655    /// ## `dest_type`
656    /// target type
657    ///
658    /// # Returns
659    ///
660    /// true if the transformation is possible; false otherwise
661    #[doc(alias = "g_value_type_transformable")]
662    pub fn type_transformable(src: Type, dst: Type) -> bool {
663        unsafe {
664            from_glib(gobject_ffi::g_value_type_transformable(
665                src.into_glib(),
666                dst.into_glib(),
667            ))
668        }
669    }
670
671    // rustdoc-stripper-ignore-next
672    /// Tries to transform the value into a value of the target type
673    // rustdoc-stripper-ignore-next-stop
674    /// Tries to cast the contents of `self` into a type appropriate
675    /// to store in `dest_value`.
676    ///
677    /// If a transformation is not possible, `dest_value` is not modified.
678    ///
679    /// For example, this could transform a `G_TYPE_INT` value into a `G_TYPE_FLOAT`
680    /// value.
681    ///
682    /// Performing transformations between value types might incur precision loss.
683    /// Especially transformations into strings might reveal seemingly arbitrary
684    /// results and the format of particular transformations to strings is not
685    /// guaranteed over time.
686    /// ## `dest_value`
687    /// target value
688    ///
689    /// # Returns
690    ///
691    /// true on success; false otherwise
692    #[doc(alias = "g_value_transform")]
693    pub fn transform<T: ValueType>(&self) -> Result<Value, crate::BoolError> {
694        self.transform_with_type(T::Type::static_type())
695    }
696
697    // rustdoc-stripper-ignore-next
698    /// Tries to transform the value into a value of the target type
699    #[doc(alias = "g_value_transform")]
700    pub fn transform_with_type(&self, type_: Type) -> Result<Value, crate::BoolError> {
701        unsafe {
702            let mut dest = Value::from_type(type_);
703            if from_glib(gobject_ffi::g_value_transform(
704                self.to_glib_none().0,
705                dest.to_glib_none_mut().0,
706            )) {
707                Ok(dest)
708            } else {
709                Err(crate::bool_error!(
710                    "Can't transform value of type '{}' into '{}'",
711                    self.type_(),
712                    type_
713                ))
714            }
715        }
716    }
717
718    // rustdoc-stripper-ignore-next
719    /// Consumes `Value` and returns the corresponding `GValue`.
720    #[inline]
721    pub fn into_raw(self) -> gobject_ffi::GValue {
722        unsafe {
723            let s = mem::ManuallyDrop::new(self);
724            ptr::read(&s.inner)
725        }
726    }
727
728    // rustdoc-stripper-ignore-next
729    /// Converts a `Value` into a `SendValue`. This fails if `self` does not store a value of type
730    /// `T`. It is required for `T` to be `Send` to call this function.
731    #[inline]
732    pub fn try_into_send_value<T: Send + StaticType>(self) -> Result<SendValue, Self> {
733        if self.type_().is_a(T::static_type()) {
734            unsafe { Ok(SendValue::unsafe_from(self.into_raw())) }
735        } else {
736            Err(self)
737        }
738    }
739
740    // rustdoc-stripper-ignore-next
741    /// Converts a `Value` into a `SendValue`.
742    ///
743    /// # Safety
744    ///
745    /// The type of the value contained in `self` must be `Send`.
746    #[inline]
747    pub unsafe fn into_send_value(self) -> SendValue {
748        SendValue::unsafe_from(self.into_raw())
749    }
750
751    fn content_debug_string(&self) -> GString {
752        unsafe { from_glib_full(gobject_ffi::g_strdup_value_contents(self.to_glib_none().0)) }
753    }
754}
755
756impl fmt::Debug for Value {
757    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
758        write!(f, "({}) {}", self.type_(), self.content_debug_string())
759    }
760}
761
762impl<'a, T: ?Sized + ToValue> From<&'a T> for Value {
763    #[inline]
764    fn from(value: &'a T) -> Self {
765        value.to_value()
766    }
767}
768
769impl From<SendValue> for Value {
770    #[inline]
771    fn from(value: SendValue) -> Self {
772        unsafe { Value::unsafe_from(value.into_raw()) }
773    }
774}
775
776impl ToValue for Value {
777    #[inline]
778    fn to_value(&self) -> Value {
779        self.clone()
780    }
781
782    #[inline]
783    fn value_type(&self) -> Type {
784        self.type_()
785    }
786}
787
788impl ToValue for &Value {
789    #[inline]
790    fn to_value(&self) -> Value {
791        (*self).clone()
792    }
793
794    #[inline]
795    fn value_type(&self) -> Type {
796        self.type_()
797    }
798}
799
800pub struct NopChecker;
801
802unsafe impl ValueTypeChecker for NopChecker {
803    type Error = Infallible;
804
805    #[inline]
806    fn check(_value: &Value) -> Result<(), Self::Error> {
807        Ok(())
808    }
809}
810
811unsafe impl<'a> FromValue<'a> for Value {
812    type Checker = NopChecker;
813
814    #[inline]
815    unsafe fn from_value(value: &'a Value) -> Self {
816        value.clone()
817    }
818}
819
820unsafe impl<'a> FromValue<'a> for &'a Value {
821    type Checker = NopChecker;
822
823    #[inline]
824    unsafe fn from_value(value: &'a Value) -> Self {
825        value
826    }
827}
828
829impl ToValue for SendValue {
830    #[inline]
831    fn to_value(&self) -> Value {
832        unsafe { from_glib_none(self.to_glib_none().0) }
833    }
834
835    #[inline]
836    fn value_type(&self) -> Type {
837        self.type_()
838    }
839}
840
841impl ToValue for &SendValue {
842    #[inline]
843    fn to_value(&self) -> Value {
844        unsafe { from_glib_none(self.to_glib_none().0) }
845    }
846
847    #[inline]
848    fn value_type(&self) -> Type {
849        self.type_()
850    }
851}
852
853impl StaticType for BoxedValue {
854    #[inline]
855    fn static_type() -> Type {
856        unsafe { from_glib(gobject_ffi::g_value_get_type()) }
857    }
858}
859
860crate::wrapper! {
861    // rustdoc-stripper-ignore-next
862    /// A version of [`Value`](struct.Value.html) for storing `Send` types, that implements Send
863    /// itself.
864    ///
865    /// See the [module documentation](index.html) for more details.
866    #[doc(alias = "GValue")]
867    pub struct SendValue(BoxedInline<gobject_ffi::GValue>);
868
869    match fn {
870        copy => |ptr| copy_value(ptr),
871        free => |ptr| free_value(ptr),
872        init => |ptr| init_value(ptr),
873        copy_into => |dest, src| copy_into_value(dest, src),
874        clear => |ptr| clear_value(ptr),
875    }
876}
877
878unsafe impl Send for SendValue {}
879
880impl SendValue {
881    // rustdoc-stripper-ignore-next
882    /// Consumes `SendValue` and returns the corresponding `GValue`.
883    #[inline]
884    pub fn into_raw(self) -> gobject_ffi::GValue {
885        unsafe {
886            let s = mem::ManuallyDrop::new(self);
887            ptr::read(&s.inner)
888        }
889    }
890    #[inline]
891    pub fn from_owned<T: Send + Into<Value>>(t: T) -> Self {
892        unsafe { Self::unsafe_from(t.into().into_raw()) }
893    }
894}
895
896impl fmt::Debug for SendValue {
897    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
898        write!(f, "({}) {}", self.type_(), self.content_debug_string())
899    }
900}
901
902impl Deref for SendValue {
903    type Target = Value;
904
905    #[inline]
906    fn deref(&self) -> &Value {
907        unsafe { &*(self as *const SendValue as *const Value) }
908    }
909}
910
911impl<'a, T: ?Sized + ToSendValue> From<&'a T> for SendValue {
912    #[inline]
913    fn from(value: &'a T) -> Self {
914        value.to_send_value()
915    }
916}
917
918// rustdoc-stripper-ignore-next
919/// Converts to `SendValue`.
920pub trait ToSendValue: Send + ToValue {
921    // rustdoc-stripper-ignore-next
922    /// Returns a `SendValue` clone of `self`.
923    fn to_send_value(&self) -> SendValue;
924}
925
926impl<T: Send + ToValue + ?Sized> ToSendValue for T {
927    #[inline]
928    fn to_send_value(&self) -> SendValue {
929        unsafe { SendValue::unsafe_from(self.to_value().into_raw()) }
930    }
931}
932
933unsafe impl<'a> FromValue<'a> for &'a str {
934    type Checker = GenericValueTypeOrNoneChecker<Self>;
935
936    #[inline]
937    unsafe fn from_value(value: &'a Value) -> Self {
938        let ptr = gobject_ffi::g_value_get_string(value.to_glib_none().0);
939        CStr::from_ptr(ptr).to_str().expect("Invalid UTF-8")
940    }
941}
942
943impl ToValue for str {
944    fn to_value(&self) -> Value {
945        unsafe {
946            let mut value = Value::for_value_type::<String>();
947
948            gobject_ffi::g_value_take_string(value.to_glib_none_mut().0, self.to_glib_full());
949
950            value
951        }
952    }
953
954    fn value_type(&self) -> Type {
955        String::static_type()
956    }
957}
958
959impl ToValue for &str {
960    fn to_value(&self) -> Value {
961        (*self).to_value()
962    }
963
964    fn value_type(&self) -> Type {
965        String::static_type()
966    }
967}
968
969impl ToValueOptional for str {
970    fn to_value_optional(s: Option<&Self>) -> Value {
971        let mut value = Value::for_value_type::<String>();
972        unsafe {
973            gobject_ffi::g_value_take_string(value.to_glib_none_mut().0, s.to_glib_full());
974        }
975
976        value
977    }
978}
979
980impl ValueType for String {
981    type Type = String;
982}
983
984impl ValueTypeOptional for String {}
985
986unsafe impl<'a> FromValue<'a> for String {
987    type Checker = GenericValueTypeOrNoneChecker<Self>;
988
989    unsafe fn from_value(value: &'a Value) -> Self {
990        String::from(<&str>::from_value(value))
991    }
992}
993
994impl ToValue for String {
995    fn to_value(&self) -> Value {
996        <&str>::to_value(&self.as_str())
997    }
998
999    fn value_type(&self) -> Type {
1000        String::static_type()
1001    }
1002}
1003
1004impl From<String> for Value {
1005    #[inline]
1006    fn from(s: String) -> Self {
1007        s.to_value()
1008    }
1009}
1010
1011impl ToValueOptional for String {
1012    fn to_value_optional(s: Option<&Self>) -> Value {
1013        <str>::to_value_optional(s.as_ref().map(|s| s.as_str()))
1014    }
1015}
1016
1017impl ValueType for Box<str> {
1018    type Type = String;
1019}
1020
1021impl ValueTypeOptional for Box<str> {}
1022
1023unsafe impl<'a> FromValue<'a> for Box<str> {
1024    type Checker = GenericValueTypeOrNoneChecker<Self>;
1025
1026    unsafe fn from_value(value: &'a Value) -> Self {
1027        Box::<str>::from(<&str>::from_value(value))
1028    }
1029}
1030
1031impl StaticType for Box<str> {
1032    fn static_type() -> Type {
1033        String::static_type()
1034    }
1035}
1036
1037impl ToValue for Box<str> {
1038    fn to_value(&self) -> Value {
1039        <&str>::to_value(&self.as_ref())
1040    }
1041
1042    fn value_type(&self) -> Type {
1043        String::static_type()
1044    }
1045}
1046
1047impl From<Box<str>> for Value {
1048    #[inline]
1049    fn from(s: Box<str>) -> Self {
1050        s.to_value()
1051    }
1052}
1053
1054impl ToValueOptional for Box<str> {
1055    fn to_value_optional(s: Option<&Self>) -> Value {
1056        <str>::to_value_optional(s.as_ref().map(|s| s.as_ref()))
1057    }
1058}
1059
1060impl ValueType for Vec<String> {
1061    type Type = Vec<String>;
1062}
1063
1064unsafe impl<'a> FromValue<'a> for Vec<String> {
1065    type Checker = GenericValueTypeChecker<Self>;
1066
1067    unsafe fn from_value(value: &'a Value) -> Self {
1068        let ptr = gobject_ffi::g_value_get_boxed(value.to_glib_none().0) as *const *const c_char;
1069        FromGlibPtrContainer::from_glib_none(ptr)
1070    }
1071}
1072
1073impl ToValue for Vec<String> {
1074    fn to_value(&self) -> Value {
1075        unsafe {
1076            let mut value = Value::for_value_type::<Self>();
1077            let ptr: *mut *mut c_char = self.to_glib_full();
1078            gobject_ffi::g_value_take_boxed(value.to_glib_none_mut().0, ptr as *const c_void);
1079            value
1080        }
1081    }
1082
1083    fn value_type(&self) -> Type {
1084        <Vec<String>>::static_type()
1085    }
1086}
1087
1088impl From<Vec<String>> for Value {
1089    #[inline]
1090    fn from(s: Vec<String>) -> Self {
1091        s.to_value()
1092    }
1093}
1094
1095impl ToValue for [&'_ str] {
1096    fn to_value(&self) -> Value {
1097        unsafe {
1098            let mut value = Value::for_value_type::<Vec<String>>();
1099            let ptr: *mut *mut c_char = self.to_glib_full();
1100            gobject_ffi::g_value_take_boxed(value.to_glib_none_mut().0, ptr as *const c_void);
1101            value
1102        }
1103    }
1104
1105    fn value_type(&self) -> Type {
1106        <Vec<String>>::static_type()
1107    }
1108}
1109
1110impl ToValue for &'_ [&'_ str] {
1111    fn to_value(&self) -> Value {
1112        unsafe {
1113            let mut value = Value::for_value_type::<Vec<String>>();
1114            let ptr: *mut *mut c_char = self.to_glib_full();
1115            gobject_ffi::g_value_take_boxed(value.to_glib_none_mut().0, ptr as *const c_void);
1116            value
1117        }
1118    }
1119
1120    fn value_type(&self) -> Type {
1121        <Vec<String>>::static_type()
1122    }
1123}
1124
1125impl ToValue for Path {
1126    fn to_value(&self) -> Value {
1127        unsafe {
1128            let mut value = Value::for_value_type::<PathBuf>();
1129
1130            gobject_ffi::g_value_take_string(value.to_glib_none_mut().0, self.to_glib_full());
1131
1132            value
1133        }
1134    }
1135
1136    fn value_type(&self) -> Type {
1137        PathBuf::static_type()
1138    }
1139}
1140
1141impl ToValue for &Path {
1142    fn to_value(&self) -> Value {
1143        (*self).to_value()
1144    }
1145
1146    fn value_type(&self) -> Type {
1147        PathBuf::static_type()
1148    }
1149}
1150
1151impl ToValueOptional for Path {
1152    fn to_value_optional(s: Option<&Self>) -> Value {
1153        let mut value = Value::for_value_type::<PathBuf>();
1154        unsafe {
1155            gobject_ffi::g_value_take_string(value.to_glib_none_mut().0, s.to_glib_full());
1156        }
1157
1158        value
1159    }
1160}
1161
1162impl ValueType for PathBuf {
1163    type Type = PathBuf;
1164}
1165
1166impl ValueTypeOptional for PathBuf {}
1167
1168unsafe impl<'a> FromValue<'a> for PathBuf {
1169    type Checker = GenericValueTypeOrNoneChecker<Self>;
1170
1171    unsafe fn from_value(value: &'a Value) -> Self {
1172        from_glib_none(gobject_ffi::g_value_get_string(value.to_glib_none().0))
1173    }
1174}
1175
1176impl ToValue for PathBuf {
1177    fn to_value(&self) -> Value {
1178        <&Path>::to_value(&self.as_path())
1179    }
1180
1181    fn value_type(&self) -> Type {
1182        PathBuf::static_type()
1183    }
1184}
1185
1186impl From<PathBuf> for Value {
1187    #[inline]
1188    fn from(s: PathBuf) -> Self {
1189        s.to_value()
1190    }
1191}
1192
1193impl ToValueOptional for PathBuf {
1194    fn to_value_optional(s: Option<&Self>) -> Value {
1195        <Path>::to_value_optional(s.as_ref().map(|s| s.as_path()))
1196    }
1197}
1198
1199impl ValueType for bool {
1200    type Type = Self;
1201}
1202
1203unsafe impl<'a> FromValue<'a> for bool {
1204    type Checker = GenericValueTypeChecker<Self>;
1205
1206    #[inline]
1207    unsafe fn from_value(value: &'a Value) -> Self {
1208        from_glib(gobject_ffi::g_value_get_boolean(value.to_glib_none().0))
1209    }
1210}
1211
1212impl ToValue for bool {
1213    #[inline]
1214    fn to_value(&self) -> Value {
1215        let mut value = Value::for_value_type::<Self>();
1216        unsafe {
1217            gobject_ffi::g_value_set_boolean(&mut value.inner, self.into_glib());
1218        }
1219        value
1220    }
1221
1222    #[inline]
1223    fn value_type(&self) -> Type {
1224        Self::static_type()
1225    }
1226}
1227
1228impl From<bool> for Value {
1229    #[inline]
1230    fn from(v: bool) -> Self {
1231        v.to_value()
1232    }
1233}
1234
1235impl ValueType for Pointer {
1236    type Type = Self;
1237}
1238
1239unsafe impl<'a> FromValue<'a> for Pointer {
1240    type Checker = GenericValueTypeChecker<Self>;
1241
1242    #[inline]
1243    unsafe fn from_value(value: &'a Value) -> Self {
1244        gobject_ffi::g_value_get_pointer(value.to_glib_none().0)
1245    }
1246}
1247
1248impl ToValue for Pointer {
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_pointer(&mut value.inner, *self);
1254        }
1255        value
1256    }
1257
1258    #[inline]
1259    fn value_type(&self) -> Type {
1260        <<Self as ValueType>::Type as StaticType>::static_type()
1261    }
1262}
1263
1264impl From<Pointer> for Value {
1265    #[inline]
1266    fn from(v: Pointer) -> Self {
1267        v.to_value()
1268    }
1269}
1270
1271impl ValueType for ptr::NonNull<Pointee> {
1272    type Type = Pointer;
1273}
1274
1275unsafe impl<'a> FromValue<'a> for ptr::NonNull<Pointee> {
1276    type Checker = GenericValueTypeOrNoneChecker<Self>;
1277
1278    #[inline]
1279    unsafe fn from_value(value: &'a Value) -> Self {
1280        ptr::NonNull::new_unchecked(Pointer::from_value(value))
1281    }
1282}
1283
1284impl ToValue for ptr::NonNull<Pointee> {
1285    #[inline]
1286    fn to_value(&self) -> Value {
1287        self.as_ptr().to_value()
1288    }
1289
1290    #[inline]
1291    fn value_type(&self) -> Type {
1292        <<Self as ValueType>::Type as StaticType>::static_type()
1293    }
1294}
1295
1296impl From<ptr::NonNull<Pointee>> for Value {
1297    #[inline]
1298    fn from(v: ptr::NonNull<Pointee>) -> Self {
1299        v.to_value()
1300    }
1301}
1302
1303impl ToValueOptional for ptr::NonNull<Pointee> {
1304    #[inline]
1305    fn to_value_optional(p: Option<&Self>) -> Value {
1306        p.map(|p| p.as_ptr()).unwrap_or(ptr::null_mut()).to_value()
1307    }
1308}
1309
1310macro_rules! numeric {
1311    ($name:ty, $get:expr, $set:expr) => {
1312        impl ValueType for $name {
1313            type Type = Self;
1314        }
1315
1316        unsafe impl<'a> FromValue<'a> for $name {
1317            type Checker = GenericValueTypeChecker<Self>;
1318
1319            #[inline]
1320            #[allow(clippy::redundant_closure_call)]
1321            unsafe fn from_value(value: &'a Value) -> Self {
1322                $get(value.to_glib_none().0)
1323            }
1324        }
1325
1326        impl ToValue for $name {
1327            #[inline]
1328            #[allow(clippy::redundant_closure_call)]
1329            fn to_value(&self) -> Value {
1330                let mut value = Value::for_value_type::<Self>();
1331                unsafe {
1332                    $set(&mut value.inner, *self);
1333                }
1334                value
1335            }
1336
1337            #[inline]
1338            fn value_type(&self) -> Type {
1339                Self::static_type()
1340            }
1341        }
1342
1343        impl From<$name> for Value {
1344            #[inline]
1345            fn from(v: $name) -> Self {
1346                v.to_value()
1347            }
1348        }
1349    };
1350}
1351macro_rules! not_zero {
1352    ($name:ty, $num:ty) => {
1353        impl ValueType for $name {
1354            type Type = $name;
1355        }
1356
1357        unsafe impl<'a> FromValue<'a> for $name {
1358            // Works because it returns `UnexpectedNone` if the value is NULL
1359            // by checking it against `0`.
1360            type Checker = GenericValueTypeOrNoneChecker<Self>;
1361
1362            #[inline]
1363            unsafe fn from_value(value: &'a Value) -> Self {
1364                let res = <$num>::from_value(value);
1365                Self::try_from(res).unwrap()
1366            }
1367        }
1368
1369        impl ToValue for $name {
1370            #[inline]
1371            fn to_value(&self) -> Value {
1372                <$num>::to_value(&<$num>::from(*self))
1373            }
1374
1375            #[inline]
1376            fn value_type(&self) -> Type {
1377                Self::static_type()
1378            }
1379        }
1380
1381        impl From<$name> for Value {
1382            #[inline]
1383            fn from(v: $name) -> Self {
1384                v.to_value()
1385            }
1386        }
1387
1388        impl ToValueOptional for $name {
1389            fn to_value_optional(s: Option<&Self>) -> Value {
1390                match s {
1391                    Some(x) => x.to_value(),
1392                    None => <$num>::to_value(&0),
1393                }
1394            }
1395        }
1396    };
1397}
1398
1399numeric!(
1400    i8,
1401    gobject_ffi::g_value_get_schar,
1402    gobject_ffi::g_value_set_schar
1403);
1404not_zero!(NonZeroI8, i8);
1405numeric!(
1406    u8,
1407    gobject_ffi::g_value_get_uchar,
1408    gobject_ffi::g_value_set_uchar
1409);
1410not_zero!(NonZeroU8, u8);
1411numeric!(
1412    i32,
1413    gobject_ffi::g_value_get_int,
1414    gobject_ffi::g_value_set_int
1415);
1416not_zero!(NonZeroI32, i32);
1417numeric!(
1418    u32,
1419    gobject_ffi::g_value_get_uint,
1420    gobject_ffi::g_value_set_uint
1421);
1422not_zero!(NonZeroU32, u32);
1423numeric!(
1424    i64,
1425    gobject_ffi::g_value_get_int64,
1426    gobject_ffi::g_value_set_int64
1427);
1428not_zero!(NonZeroI64, i64);
1429numeric!(
1430    u64,
1431    gobject_ffi::g_value_get_uint64,
1432    gobject_ffi::g_value_set_uint64
1433);
1434not_zero!(NonZeroU64, u64);
1435numeric!(
1436    crate::ILong,
1437    |v| gobject_ffi::g_value_get_long(v).into(),
1438    |v, i: crate::ILong| gobject_ffi::g_value_set_long(v, i.0)
1439);
1440numeric!(
1441    crate::ULong,
1442    |v| gobject_ffi::g_value_get_ulong(v).into(),
1443    |v, i: crate::ULong| gobject_ffi::g_value_set_ulong(v, i.0)
1444);
1445numeric!(
1446    f32,
1447    gobject_ffi::g_value_get_float,
1448    gobject_ffi::g_value_set_float
1449);
1450numeric!(
1451    f64,
1452    gobject_ffi::g_value_get_double,
1453    gobject_ffi::g_value_set_double
1454);
1455
1456impl ValueType for char {
1457    type Type = u32;
1458}
1459
1460unsafe impl<'a> FromValue<'a> for char {
1461    type Checker = CharTypeChecker;
1462
1463    #[inline]
1464    unsafe fn from_value(value: &'a Value) -> Self {
1465        let res: u32 = gobject_ffi::g_value_get_uint(value.to_glib_none().0);
1466        // safe because the check is done by `Self::Checker`
1467        char::from_u32_unchecked(res)
1468    }
1469}
1470
1471impl ToValue for char {
1472    #[inline]
1473    fn to_value(&self) -> Value {
1474        let mut value = Value::for_value_type::<Self>();
1475        unsafe {
1476            gobject_ffi::g_value_set_uint(&mut value.inner, *self as u32);
1477        }
1478        value
1479    }
1480
1481    #[inline]
1482    fn value_type(&self) -> Type {
1483        crate::Type::U32
1484    }
1485}
1486
1487impl From<char> for Value {
1488    #[inline]
1489    fn from(v: char) -> Self {
1490        v.to_value()
1491    }
1492}
1493
1494// rustdoc-stripper-ignore-next
1495/// A [`Value`] containing another [`Value`].
1496pub struct BoxedValue(pub Value);
1497
1498impl Deref for BoxedValue {
1499    type Target = Value;
1500
1501    #[inline]
1502    fn deref(&self) -> &Value {
1503        &self.0
1504    }
1505}
1506
1507impl ValueType for BoxedValue {
1508    type Type = BoxedValue;
1509}
1510
1511impl ValueTypeOptional for BoxedValue {}
1512
1513unsafe impl<'a> FromValue<'a> for BoxedValue {
1514    type Checker = GenericValueTypeOrNoneChecker<Self>;
1515
1516    #[inline]
1517    unsafe fn from_value(value: &'a Value) -> Self {
1518        let ptr = gobject_ffi::g_value_get_boxed(value.to_glib_none().0);
1519        BoxedValue(from_glib_none(ptr as *const gobject_ffi::GValue))
1520    }
1521}
1522
1523impl ToValue for BoxedValue {
1524    #[inline]
1525    fn to_value(&self) -> Value {
1526        unsafe {
1527            let mut value = Value::for_value_type::<BoxedValue>();
1528
1529            gobject_ffi::g_value_set_boxed(
1530                value.to_glib_none_mut().0,
1531                self.0.to_glib_none().0 as ffi::gconstpointer,
1532            );
1533
1534            value
1535        }
1536    }
1537
1538    #[inline]
1539    fn value_type(&self) -> Type {
1540        BoxedValue::static_type()
1541    }
1542}
1543
1544impl From<BoxedValue> for Value {
1545    #[inline]
1546    fn from(v: BoxedValue) -> Self {
1547        unsafe {
1548            let mut value = Value::for_value_type::<BoxedValue>();
1549
1550            gobject_ffi::g_value_take_boxed(
1551                value.to_glib_none_mut().0,
1552                v.0.to_glib_full() as ffi::gconstpointer,
1553            );
1554
1555            value
1556        }
1557    }
1558}
1559
1560impl ToValueOptional for BoxedValue {
1561    #[inline]
1562    fn to_value_optional(s: Option<&Self>) -> Value {
1563        let mut value = Value::for_value_type::<Self>();
1564        unsafe {
1565            gobject_ffi::g_value_set_boxed(
1566                value.to_glib_none_mut().0,
1567                s.map(|s| &s.0).to_glib_none().0 as ffi::gconstpointer,
1568            );
1569        }
1570
1571        value
1572    }
1573}
1574
1575#[cfg(test)]
1576mod tests {
1577    use std::num::NonZeroI32;
1578
1579    use super::*;
1580
1581    #[test]
1582    fn test_send_value() {
1583        use std::thread;
1584
1585        let v = SendValue::from(&1i32);
1586
1587        // Must compile, while it must fail with Value
1588        thread::spawn(move || drop(v)).join().unwrap();
1589    }
1590
1591    #[test]
1592    fn test_strv() {
1593        let v = ["123", "456"].to_value();
1594        assert_eq!(
1595            v.get::<Vec<GString>>(),
1596            Ok(vec![GString::from("123"), GString::from("456")])
1597        );
1598
1599        let v = vec![String::from("123"), String::from("456")].to_value();
1600        assert_eq!(
1601            v.get::<Vec<GString>>(),
1602            Ok(vec![GString::from("123"), GString::from("456")])
1603        );
1604    }
1605
1606    #[test]
1607    fn test_from_to_value() {
1608        let v = 123.to_value();
1609        assert_eq!(v.get(), Ok(123));
1610        assert_eq!(
1611            v.get::<&str>(),
1612            Err(ValueTypeMismatchError::new(Type::I32, Type::STRING).into())
1613        );
1614        assert_eq!(
1615            v.get::<bool>(),
1616            Err(ValueTypeMismatchError::new(Type::I32, Type::BOOL))
1617        );
1618
1619        // Check if &str / str / Option<&str> etc can be converted and retrieved
1620        let v_str = "test".to_value();
1621        assert_eq!(v_str.get::<&str>(), Ok("test"));
1622        assert_eq!(v_str.get::<Option<&str>>(), Ok(Some("test")));
1623        assert_eq!(
1624            v_str.get::<i32>(),
1625            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1626        );
1627
1628        let some_v = Some("test").to_value();
1629        assert_eq!(some_v.get::<&str>(), Ok("test"));
1630        assert_eq!(some_v.get_owned::<String>(), Ok("test".to_string()));
1631        assert_eq!(
1632            some_v.get_owned::<Option<String>>(),
1633            Ok(Some("test".to_string()))
1634        );
1635        assert_eq!(some_v.get::<Option<&str>>(), Ok(Some("test")));
1636        assert_eq!(
1637            some_v.get::<i32>(),
1638            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1639        );
1640
1641        let none_str: Option<&str> = None;
1642        let none_v = none_str.to_value();
1643        assert_eq!(none_v.get::<Option<&str>>(), Ok(None));
1644        assert_eq!(
1645            none_v.get::<i32>(),
1646            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1647        );
1648
1649        // Check if owned T and Option<T> can be converted and retrieved
1650        let v_str = String::from("test").to_value();
1651        assert_eq!(v_str.get::<String>(), Ok(String::from("test")));
1652        assert_eq!(
1653            v_str.get::<Option<String>>(),
1654            Ok(Some(String::from("test")))
1655        );
1656        assert_eq!(
1657            v_str.get::<i32>(),
1658            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1659        );
1660
1661        let some_v = Some(String::from("test")).to_value();
1662        assert_eq!(some_v.get::<String>(), Ok(String::from("test")));
1663        assert_eq!(
1664            some_v.get::<Option<String>>(),
1665            Ok(Some(String::from("test")))
1666        );
1667        assert_eq!(
1668            some_v.get::<i32>(),
1669            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1670        );
1671
1672        let none_str: Option<String> = None;
1673        let none_v = none_str.to_value();
1674        assert_eq!(none_v.get::<Option<String>>(), Ok(None));
1675        assert_eq!(
1676            none_v.get::<i32>(),
1677            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1678        );
1679
1680        let c_v = 'c'.to_value();
1681        assert_eq!(c_v.get::<char>(), Ok('c'));
1682
1683        let c_v = 0xFFFFFFFFu32.to_value();
1684        assert_eq!(
1685            c_v.get::<char>(),
1686            Err(InvalidCharError::CharConversionError)
1687        );
1688
1689        // Check if &T and Option<&T> can be converted and retrieved
1690        let v_str = String::from("test").to_value();
1691        assert_eq!(v_str.get::<String>(), Ok(String::from("test")));
1692        assert_eq!(
1693            v_str.get::<Option<String>>(),
1694            Ok(Some(String::from("test")))
1695        );
1696        assert_eq!(
1697            v_str.get::<i32>(),
1698            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1699        );
1700
1701        let some_v = Some(&String::from("test")).to_value();
1702        assert_eq!(some_v.get::<String>(), Ok(String::from("test")));
1703        assert_eq!(
1704            some_v.get::<Option<String>>(),
1705            Ok(Some(String::from("test")))
1706        );
1707        assert_eq!(
1708            some_v.get::<i32>(),
1709            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1710        );
1711
1712        let none_str: Option<&String> = None;
1713        let none_v = none_str.to_value();
1714        assert_eq!(none_v.get::<Option<String>>(), Ok(None));
1715        assert_eq!(
1716            none_v.get::<i32>(),
1717            Err(ValueTypeMismatchError::new(Type::STRING, Type::I32))
1718        );
1719
1720        // Check handling of NonZeroT
1721        let v = NonZeroI32::new(123).unwrap().to_value();
1722        assert_eq!(v.get::<NonZeroI32>(), Ok(NonZeroI32::new(123).unwrap()));
1723
1724        let v = 123i32.to_value();
1725        assert_eq!(v.get::<NonZeroI32>(), Ok(NonZeroI32::new(123).unwrap()));
1726
1727        let v = 0i32.to_value();
1728        assert_eq!(
1729            v.get::<NonZeroI32>(),
1730            Err(ValueTypeMismatchOrNoneError::UnexpectedNone)
1731        );
1732
1733        assert_eq!(v.get::<Option<NonZeroI32>>(), Ok(None));
1734    }
1735
1736    #[test]
1737    fn test_transform() {
1738        let v = 123.to_value();
1739        let v2 = v
1740            .transform::<String>()
1741            .expect("Failed to transform to string");
1742        assert_eq!(v2.get::<&str>(), Ok("123"));
1743    }
1744
1745    #[test]
1746    fn test_into_raw() {
1747        unsafe {
1748            let mut v = 123.to_value().into_raw();
1749            assert_eq!(gobject_ffi::g_type_check_value(&v), ffi::GTRUE);
1750            assert_eq!(gobject_ffi::g_value_get_int(&v), 123);
1751            gobject_ffi::g_value_unset(&mut v);
1752        }
1753    }
1754
1755    #[test]
1756    fn test_debug() {
1757        fn value_debug_string<T: ToValue>(val: T) -> String {
1758            format!("{:?}", val.to_value())
1759        }
1760
1761        assert_eq!(value_debug_string(1u32), "(guint) 1");
1762        assert_eq!(value_debug_string(2i32), "(gint) 2");
1763        assert_eq!(value_debug_string(false), "(gboolean) FALSE");
1764        assert_eq!(value_debug_string("FooBar"), r#"(gchararray) "FooBar""#);
1765    }
1766}