glib/
value.rs

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