use std::borrow::Borrow;
use std::fmt;
use std::marker::PhantomData;
use std::mem;
use std::ops::Deref;
use std::ffi::CStr;
use std::ptr;
use libc::{c_char, c_void};
use translate::*;
use types::{StaticType, Type};
use gstring::GString;
use ffi as glib_ffi;
use gobject_ffi;
#[repr(C)]
pub struct Value(pub(crate) gobject_ffi::GValue, PhantomData<*const c_void>);
impl Value {
pub fn from_type(type_: Type) -> Self {
unsafe {
assert_eq!(gobject_ffi::g_type_check_is_value_type(type_.to_glib()), glib_ffi::GTRUE);
let mut value = Value::uninitialized();
gobject_ffi::g_value_init(value.to_glib_none_mut().0, type_.to_glib());
value
}
}
pub fn downcast<'a, T: FromValueOptional<'a> + SetValue>(self) -> Result<TypedValue<T>, Self> {
unsafe {
let ok = from_glib(
gobject_ffi::g_type_check_value_holds(mut_override(self.to_glib_none().0),
T::static_type().to_glib()));
if ok {
Ok(TypedValue(self, PhantomData))
}
else {
Err(self)
}
}
}
pub fn downcast_ref<'a, T: FromValueOptional<'a> + SetValue>(&self) -> Option<&TypedValue<T>> {
unsafe {
let ok = from_glib(
gobject_ffi::g_type_check_value_holds(mut_override(self.to_glib_none().0),
T::static_type().to_glib()));
if ok {
Some(mem::transmute(self))
}
else {
None
}
}
}
pub fn get<'a, T: FromValueOptional<'a>>(&'a self) -> Option<T> {
unsafe {
let ok = from_glib(
gobject_ffi::g_type_check_value_holds(mut_override(self.to_glib_none().0),
T::static_type().to_glib()));
if ok {
T::from_value_optional(self)
}
else {
None
}
}
}
#[inline]
pub fn is<'a, T: FromValueOptional<'a> + SetValue>(&self) -> bool {
self.type_().is_a(&T::static_type())
}
pub fn type_(&self) -> Type {
from_glib(self.0.g_type)
}
pub fn type_transformable(src: Type, dst: Type) -> bool {
unsafe {
from_glib(gobject_ffi::g_value_type_transformable(src.to_glib(), dst.to_glib()))
}
}
#[doc(hidden)]
pub fn into_raw(mut self) -> gobject_ffi::GValue {
unsafe {
let ret = mem::replace(&mut self.0, mem::uninitialized());
mem::forget(self);
ret
}
}
pub fn try_into_send_value<'a, T: Send + FromValueOptional<'a> + SetValue>(self) -> Result<SendValue, Self> {
self.downcast::<T>().map(TypedValue::into_send_value)
}
}
impl Clone for Value {
fn clone(&self) -> Self {
unsafe {
let mut ret = Value::from_type(from_glib(self.0.g_type));
gobject_ffi::g_value_copy(self.to_glib_none().0, ret.to_glib_none_mut().0);
ret
}
}
}
impl Drop for Value {
fn drop(&mut self) {
if self.type_() != Type::Invalid {
unsafe { gobject_ffi::g_value_unset(self.to_glib_none_mut().0) }
}
}
}
impl fmt::Debug for Value {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
unsafe {
let s: GString = from_glib_full(
gobject_ffi::g_strdup_value_contents(self.to_glib_none().0));
f.debug_tuple("Value")
.field(&s)
.finish()
}
}
}
impl<'a, T: ?Sized + SetValueOptional> From<Option<&'a T>> for Value {
#[inline]
fn from(value: Option<&'a T>) -> Self {
value.to_value()
}
}
impl<'a, T: ?Sized + SetValue> From<&'a T> for Value {
#[inline]
fn from(value: &'a T) -> Self {
value.to_value()
}
}
impl<T> From<TypedValue<T>> for Value {
fn from(value: TypedValue<T>) -> Self {
value.0
}
}
impl From<SendValue> for Value {
fn from(value: SendValue) -> Self {
value.0
}
}
impl Uninitialized for Value {
unsafe fn uninitialized() -> Value {
Value(mem::zeroed(), PhantomData)
}
}
impl<'a> ToGlibPtr<'a, *const gobject_ffi::GValue> for Value {
type Storage = &'a Value;
fn to_glib_none(&'a self) -> Stash<'a, *const gobject_ffi::GValue, Self> {
Stash(&self.0, self)
}
}
impl<'a> ToGlibPtrMut<'a, *mut gobject_ffi::GValue> for Value {
type Storage = &'a mut Value;
fn to_glib_none_mut(&'a mut self) -> StashMut<'a, *mut gobject_ffi::GValue, Self> {
StashMut(&mut self.0, self)
}
}
impl<'a> ToGlibPtr<'a, *mut gobject_ffi::GValue> for &'a [&'a ToValue] {
type Storage = ValueArray;
fn to_glib_none(&'a self) -> Stash<'a, *mut gobject_ffi::GValue, Self> {
let mut values: Vec<gobject_ffi::GValue> = self.iter()
.map(|v| v.to_value().into_raw())
.collect();
Stash(values.as_mut_ptr(), ValueArray(values))
}
}
impl<'a> ToGlibContainerFromSlice<'a, *mut gobject_ffi::GValue> for &'a Value {
type Storage = &'a [&'a Value];
fn to_glib_none_from_slice(t: &'a [&'a Value]) -> (*mut gobject_ffi::GValue, &'a [&'a Value]) {
(t.as_ptr() as *mut gobject_ffi::GValue, t)
}
fn to_glib_container_from_slice(t: &'a [&'a Value]) -> (*mut gobject_ffi::GValue, &'a [&'a Value]) {
if t.is_empty() {
return (ptr::null_mut(), t);
}
unsafe {
let res = glib_ffi::g_malloc(mem::size_of::<gobject_ffi::GValue>() * t.len()) as *mut gobject_ffi::GValue;
ptr::copy_nonoverlapping(t.as_ptr() as *const gobject_ffi::GValue, res, t.len());
(res, t)
}
}
fn to_glib_full_from_slice(t: &[&'a Value]) -> *mut gobject_ffi::GValue {
if t.is_empty() {
return ptr::null_mut();
}
unsafe {
let res = glib_ffi::g_malloc(mem::size_of::<gobject_ffi::GValue>() * t.len()) as *mut gobject_ffi::GValue;
for (i, v) in t.iter().enumerate() {
gobject_ffi::g_value_init(res.add(i), v.type_().to_glib());
gobject_ffi::g_value_copy(v.to_glib_none().0, res.add(i));
}
res
}
}
}
impl<'a> ToGlibContainerFromSlice<'a, *const gobject_ffi::GValue> for &'a Value {
type Storage = &'a [&'a Value];
fn to_glib_none_from_slice(t: &'a [&'a Value]) -> (*const gobject_ffi::GValue, &'a [&'a Value]) {
let (ptr, storage) = ToGlibContainerFromSlice::<'a, *mut gobject_ffi::GValue>::to_glib_none_from_slice(t);
(ptr as *const _, storage)
}
fn to_glib_container_from_slice(_: &'a [&'a Value]) -> (*const gobject_ffi::GValue, &'a [&'a Value]) {
unimplemented!()
}
fn to_glib_full_from_slice(_: &[&'a Value]) -> *const gobject_ffi::GValue {
unimplemented!()
}
}
macro_rules! from_glib {
($name:ident, $wrap:expr) => {
impl FromGlibPtrNone<*const gobject_ffi::GValue> for $name {
unsafe fn from_glib_none(ptr: *const gobject_ffi::GValue) -> Self {
let mut ret = Value::from_type(from_glib((*ptr).g_type));
gobject_ffi::g_value_copy(ptr, ret.to_glib_none_mut().0);
$wrap(ret)
}
}
impl FromGlibPtrNone<*mut gobject_ffi::GValue> for $name {
unsafe fn from_glib_none(ptr: *mut gobject_ffi::GValue) -> Self {
from_glib_none(ptr as *const _)
}
}
impl FromGlibPtrFull<*mut gobject_ffi::GValue> for $name {
unsafe fn from_glib_full(ptr: *mut gobject_ffi::GValue) -> Self {
let mut ret = Value::uninitialized();
ptr::swap(&mut ret.0, ptr);
glib_ffi::g_free(ptr as *mut c_void);
$wrap(ret)
}
}
impl FromGlibContainerAsVec<*mut gobject_ffi::GValue, *mut *mut gobject_ffi::GValue> for $name {
unsafe fn from_glib_none_num_as_vec(ptr: *mut *mut gobject_ffi::GValue, num: usize) -> Vec<Self> {
if num == 0 || ptr.is_null() {
return Vec::new();
}
let mut res = Vec::with_capacity(num);
for i in 0..num {
res.push(from_glib_none(ptr::read(ptr.add(i))));
}
res
}
unsafe fn from_glib_container_num_as_vec(ptr: *mut *mut gobject_ffi::GValue, num: usize) -> Vec<Self> {
let res = FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr, num);
glib_ffi::g_free(ptr as *mut _);
res
}
unsafe fn from_glib_full_num_as_vec(ptr: *mut *mut gobject_ffi::GValue, num: usize) -> Vec<Self> {
if num == 0 || ptr.is_null() {
return Vec::new();
}
let mut res = Vec::with_capacity(num);
for i in 0..num {
res.push(from_glib_full(ptr::read(ptr.add(i))));
}
glib_ffi::g_free(ptr as *mut _);
res
}
}
impl FromGlibPtrArrayContainerAsVec<*mut gobject_ffi::GValue, *mut *mut gobject_ffi::GValue> for $name {
unsafe fn from_glib_none_as_vec(ptr: *mut *mut gobject_ffi::GValue) -> Vec<Self> {
FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr, c_ptr_array_len(ptr))
}
unsafe fn from_glib_container_as_vec(ptr: *mut *mut gobject_ffi::GValue) -> Vec<Self> {
FromGlibContainerAsVec::from_glib_container_num_as_vec(ptr, c_ptr_array_len(ptr))
}
unsafe fn from_glib_full_as_vec(ptr: *mut *mut gobject_ffi::GValue) -> Vec<Self> {
FromGlibContainerAsVec::from_glib_full_num_as_vec(ptr, c_ptr_array_len(ptr))
}
}
impl FromGlibContainerAsVec<*mut gobject_ffi::GValue, *const *mut gobject_ffi::GValue> for $name {
unsafe fn from_glib_none_num_as_vec(ptr: *const *mut gobject_ffi::GValue, num: usize) -> Vec<Self> {
FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr as *mut *mut _, num)
}
unsafe fn from_glib_container_num_as_vec(_: *const *mut gobject_ffi::GValue, _: usize) -> Vec<Self> {
unimplemented!()
}
unsafe fn from_glib_full_num_as_vec(_: *const *mut gobject_ffi::GValue, _: usize) -> Vec<Self> {
unimplemented!()
}
}
impl FromGlibPtrArrayContainerAsVec<*mut gobject_ffi::GValue, *const *mut gobject_ffi::GValue> for $name {
unsafe fn from_glib_none_as_vec(ptr: *const *mut gobject_ffi::GValue) -> Vec<Self> {
FromGlibPtrArrayContainerAsVec::from_glib_none_as_vec(ptr as *mut *mut _)
}
unsafe fn from_glib_container_as_vec(_: *const *mut gobject_ffi::GValue) -> Vec<Self> {
unimplemented!()
}
unsafe fn from_glib_full_as_vec(_: *const *mut gobject_ffi::GValue) -> Vec<Self> {
unimplemented!()
}
}
}
}
from_glib!(Value, |v| v);
pub struct ValueArray(Vec<gobject_ffi::GValue>);
impl Drop for ValueArray {
fn drop(&mut self) {
unsafe {
for value in &mut self.0 {
if value.g_type != gobject_ffi::G_TYPE_INVALID {
gobject_ffi::g_value_unset(value);
}
}
}
}
}
#[derive(Clone)]
#[repr(C)]
pub struct TypedValue<T>(Value, PhantomData<*const T>);
impl<'a, T: FromValueOptional<'a> + SetValue> TypedValue<T> {
pub fn get(&'a self) -> Option<T> {
unsafe { T::from_value_optional(self) }
}
pub fn get_some(&'a self) -> T where T: FromValue<'a> {
unsafe { T::from_value(self) }
}
pub fn set<U: ?Sized + SetValueOptional>(&mut self, value: Option<&U>) where T: Borrow<U> {
unsafe { SetValueOptional::set_value_optional(&mut self.0, value) }
}
pub fn set_none(&mut self) where T: SetValueOptional {
unsafe { T::set_value_optional(&mut self.0, None) }
}
pub fn set_some<U: ?Sized + SetValue>(&mut self, value: &U) where T: Borrow<U> {
unsafe { SetValue::set_value(&mut self.0, value) }
}
}
impl<T> fmt::Debug for TypedValue<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
f.debug_tuple("TypedValue")
.field(&self.0)
.finish()
}
}
impl<'a, T: FromValueOptional<'a> + SetValue + Send> TypedValue<T> {
pub fn into_send_value(self) -> SendValue {
SendValue(self.0)
}
}
impl<T> Deref for TypedValue<T> {
type Target = Value;
fn deref(&self) -> &Value {
&self.0
}
}
impl<'a, T: FromValueOptional<'a> + SetValueOptional> From<Option<&'a T>> for TypedValue<T> {
fn from(value: Option<&'a T>) -> Self {
TypedValue(Value::from(value), PhantomData)
}
}
impl<'a, T: FromValueOptional<'a> + SetValue> From<&'a T> for TypedValue<T> {
fn from(value: &'a T) -> Self {
TypedValue(Value::from(value), PhantomData)
}
}
impl<'a> From<Option<&'a str>> for TypedValue<String> {
fn from(value: Option<&'a str>) -> Self {
TypedValue(Value::from(value), PhantomData)
}
}
impl<'a> From<&'a str> for TypedValue<String> {
fn from(value: &'a str) -> Self {
TypedValue(Value::from(value), PhantomData)
}
}
impl<'a> From<TypedValue<&'a str>> for TypedValue<String> {
fn from(value: TypedValue<&str>) -> Self {
TypedValue(value.0, PhantomData)
}
}
impl<'a> From<TypedValue<String>> for TypedValue<&'a str> {
fn from(value: TypedValue<String>) -> Self {
TypedValue(value.0, PhantomData)
}
}
impl<'a, T: 'a> ToGlibPtrMut<'a, *mut gobject_ffi::GValue> for TypedValue<T> {
type Storage = &'a mut TypedValue<T>;
fn to_glib_none_mut(&'a mut self) -> StashMut<'a, *mut gobject_ffi::GValue, Self> {
StashMut(&mut (self.0).0, self)
}
}
pub trait ToValue {
fn to_value(&self) -> Value;
fn to_value_type(&self) -> Type;
}
impl<T: SetValueOptional> ToValue for Option<T> {
fn to_value(&self) -> Value {
unsafe {
let mut ret = Value::from_type(T::static_type());
T::set_value_optional(&mut ret, self.as_ref());
ret
}
}
#[inline]
fn to_value_type(&self) -> Type {
T::static_type()
}
}
impl<T: ?Sized + SetValue> ToValue for T {
fn to_value(&self) -> Value {
unsafe {
let mut ret = Value::from_type(T::static_type());
T::set_value(&mut ret, self);
ret
}
}
#[inline]
fn to_value_type(&self) -> Type {
T::static_type()
}
}
impl ToValue for Value {
fn to_value(&self) -> Value {
self.clone()
}
fn to_value_type(&self) -> Type {
self.type_()
}
}
#[derive(Clone)]
#[repr(C)]
pub struct SendValue(Value);
unsafe impl Send for SendValue {}
impl SendValue {
pub fn downcast<'a, T: FromValueOptional<'a> + SetValue + Send>(self) -> Result<TypedValue<T>, Self> {
self.0.downcast().map_err(SendValue)
}
pub fn downcast_ref<'a, T: FromValueOptional<'a> + SetValue>(&self) -> Option<&TypedValue<T>> {
unsafe {
let ok = from_glib(
gobject_ffi::g_type_check_value_holds(mut_override(self.to_glib_none().0),
T::static_type().to_glib()));
if ok {
Some(mem::transmute(self))
}
else {
None
}
}
}
#[doc(hidden)]
pub fn into_raw(self) -> gobject_ffi::GValue {
self.0.into_raw()
}
}
impl fmt::Debug for SendValue {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
f.debug_tuple("SendValue")
.field(&self.0)
.finish()
}
}
impl Deref for SendValue {
type Target = Value;
fn deref(&self) -> &Value {
&self.0
}
}
impl<'a, T: ?Sized + SetValueOptional + Send> From<Option<&'a T>> for SendValue {
#[inline]
fn from(value: Option<&'a T>) -> Self {
SendValue(value.to_value())
}
}
impl<'a, T: ?Sized + SetValue + Send> From<&'a T> for SendValue {
#[inline]
fn from(value: &'a T) -> Self {
SendValue(value.to_value())
}
}
impl<T: Send> From<TypedValue<T>> for SendValue {
fn from(value: TypedValue<T>) -> Self {
SendValue(value.0)
}
}
from_glib!(SendValue, SendValue);
impl<'a> ToGlibPtrMut<'a, *mut gobject_ffi::GValue> for SendValue {
type Storage = &'a mut SendValue;
fn to_glib_none_mut(&'a mut self) -> StashMut<'a, *mut gobject_ffi::GValue, Self> {
StashMut(&mut (self.0).0, self)
}
}
pub trait ToSendValue: Send + ToValue {
fn to_send_value(&self) -> SendValue;
}
impl<T: SetValueOptional + Send + ToValue> ToSendValue for Option<T> {
fn to_send_value(&self) -> SendValue {
SendValue(self.to_value())
}
}
impl<T: ?Sized + SetValue + Send + ToValue> ToSendValue for T {
fn to_send_value(&self) -> SendValue {
SendValue(self.to_value())
}
}
impl ToSendValue for SendValue {
fn to_send_value(&self) -> SendValue {
self.clone()
}
}
impl ToValue for SendValue {
fn to_value(&self) -> Value {
self.0.clone()
}
fn to_value_type(&self) -> Type {
self.type_()
}
}
pub trait FromValueOptional<'a>: StaticType + Sized {
unsafe fn from_value_optional(&'a Value) -> Option<Self>;
}
pub trait FromValue<'a>: FromValueOptional<'a> {
unsafe fn from_value(&'a Value) -> Self;
}
pub trait SetValueOptional: SetValue {
unsafe fn set_value_optional(&mut Value, Option<&Self>);
}
pub trait SetValue: StaticType {
unsafe fn set_value(&mut Value, &Self);
}
impl<'a> FromValueOptional<'a> for String {
unsafe fn from_value_optional(value: &'a Value) -> Option<Self> {
from_glib_none(gobject_ffi::g_value_get_string(value.to_glib_none().0))
}
}
impl<'a> FromValueOptional<'a> for &'a str {
unsafe fn from_value_optional(value: &'a Value) -> Option<Self> {
let cstr = gobject_ffi::g_value_get_string(value.to_glib_none().0);
if cstr.is_null() {
None
} else {
CStr::from_ptr(cstr).to_str().ok()
}
}
}
impl SetValue for str {
unsafe fn set_value(value: &mut Value, this: &Self) {
gobject_ffi::g_value_take_string(value.to_glib_none_mut().0, this.to_glib_full())
}
}
impl SetValueOptional for str {
unsafe fn set_value_optional(value: &mut Value, this: Option<&Self>) {
gobject_ffi::g_value_take_string(value.to_glib_none_mut().0, this.to_glib_full())
}
}
impl<'a> FromValueOptional<'a> for Vec<String> {
unsafe fn from_value_optional(value: &'a Value) -> Option<Self> {
Some(<Vec<String> as FromValue>::from_value(value))
}
}
impl<'a> FromValue<'a> for Vec<String> {
unsafe fn from_value(value: &'a Value) -> Self {
let ptr = gobject_ffi::g_value_get_boxed(value.to_glib_none().0) as *const *const c_char;
FromGlibPtrContainer::from_glib_none(ptr)
}
}
impl<'a> FromValueOptional<'a> for Vec<GString> {
unsafe fn from_value_optional(value: &'a Value) -> Option<Self> {
Some(<Vec<GString> as FromValue>::from_value(value))
}
}
impl<'a> FromValue<'a> for Vec<GString> {
unsafe fn from_value(value: &'a Value) -> Self {
let ptr = gobject_ffi::g_value_get_boxed(value.to_glib_none().0) as *const *const c_char;
FromGlibPtrContainer::from_glib_none(ptr)
}
}
impl<'a> SetValue for [&'a str] {
unsafe fn set_value(value: &mut Value, this: &Self) {
let ptr: *mut *mut c_char = this.to_glib_full();
gobject_ffi::g_value_take_boxed(value.to_glib_none_mut().0, ptr as *const c_void)
}
}
impl<'a> SetValueOptional for [&'a str] {
unsafe fn set_value_optional(value: &mut Value, this: Option<&Self>) {
let ptr: *mut *mut c_char = this.to_glib_full();
gobject_ffi::g_value_take_boxed(value.to_glib_none_mut().0, ptr as *const c_void)
}
}
impl SetValue for Vec<String> {
unsafe fn set_value(value: &mut Value, this: &Self) {
let ptr: *mut *mut c_char = this.to_glib_full();
gobject_ffi::g_value_take_boxed(value.to_glib_none_mut().0, ptr as *const c_void)
}
}
impl SetValueOptional for Vec<String> {
unsafe fn set_value_optional(value: &mut Value, this: Option<&Self>) {
let ptr: *mut *mut c_char = this.map(|v| v.to_glib_full()).unwrap_or(ptr::null_mut());
gobject_ffi::g_value_take_boxed(value.to_glib_none_mut().0, ptr as *const c_void)
}
}
impl<'a, T: ?Sized + SetValue> SetValue for &'a T {
unsafe fn set_value(value: &mut Value, this: &Self) {
SetValue::set_value(value, *this)
}
}
impl<'a, T: ?Sized + SetValueOptional> SetValueOptional for &'a T {
unsafe fn set_value_optional(value: &mut Value, this: Option<&Self>) {
SetValueOptional::set_value_optional(value, this.map(|v| *v))
}
}
impl SetValue for String {
unsafe fn set_value(value: &mut Value, this: &Self) {
gobject_ffi::g_value_take_string(value.to_glib_none_mut().0, this.to_glib_full())
}
}
impl SetValueOptional for String {
unsafe fn set_value_optional(value: &mut Value, this: Option<&Self>) {
gobject_ffi::g_value_take_string(value.to_glib_none_mut().0, this.to_glib_full())
}
}
impl<'a> FromValueOptional<'a> for bool {
unsafe fn from_value_optional(value: &'a Value) -> Option<Self> {
Some(from_glib(gobject_ffi::g_value_get_boolean(value.to_glib_none().0)))
}
}
impl<'a> FromValue<'a> for bool {
unsafe fn from_value(value: &'a Value) -> Self {
from_glib(gobject_ffi::g_value_get_boolean(value.to_glib_none().0))
}
}
impl SetValue for bool {
unsafe fn set_value(value: &mut Value, this: &Self) {
gobject_ffi::g_value_set_boolean(value.to_glib_none_mut().0, this.to_glib())
}
}
macro_rules! numeric {
($name:ident, $get:ident, $set:ident) => {
impl<'a> FromValueOptional<'a> for $name {
unsafe fn from_value_optional(value: &'a Value) -> Option<Self> {
Some(gobject_ffi::$get(value.to_glib_none().0))
}
}
impl<'a> FromValue<'a> for $name {
unsafe fn from_value(value: &'a Value) -> Self {
gobject_ffi::$get(value.to_glib_none().0)
}
}
impl SetValue for $name {
unsafe fn set_value(value: &mut Value, this: &Self) {
gobject_ffi::$set(value.to_glib_none_mut().0, *this)
}
}
}
}
numeric!(i8, g_value_get_schar, g_value_set_schar);
numeric!(u8, g_value_get_uchar, g_value_set_uchar);
numeric!(i32, g_value_get_int, g_value_set_int);
numeric!(u32, g_value_get_uint, g_value_set_uint);
numeric!(i64, g_value_get_int64, g_value_set_int64);
numeric!(u64, g_value_get_uint64, g_value_set_uint64);
numeric!(f32, g_value_get_float, g_value_set_float);
numeric!(f64, g_value_get_double, g_value_set_double);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_send_value() {
use std::thread;
let v = SendValue::from(&1i32);
thread::spawn(move || drop(v)).join().unwrap();
}
#[test]
fn test_strv() {
let v = vec!["123", "456"].to_value();
assert_eq!(v.get::<Vec<GString>>(), Some(vec![GString::from("123"), GString::from("456")]));
let v = vec![String::from("123"), String::from("456")].to_value();
assert_eq!(v.get::<Vec<GString>>(), Some(vec![GString::from("123"), GString::from("456")]));
}
}