2020-12-15 10:53:31 +00:00
|
|
|
// Take a look at the license at the top of the repository in the LICENSE file.
|
2017-07-07 13:04:54 +00:00
|
|
|
|
2018-04-01 08:30:03 +00:00
|
|
|
use std::borrow::{Borrow, BorrowMut, ToOwned};
|
|
|
|
use std::ffi::CStr;
|
2017-07-07 13:04:54 +00:00
|
|
|
use std::fmt;
|
|
|
|
use std::mem;
|
|
|
|
use std::ops::{Deref, DerefMut};
|
2018-04-01 08:30:03 +00:00
|
|
|
use std::ptr;
|
|
|
|
use std::str;
|
2017-07-07 13:04:54 +00:00
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
use crate::Fraction;
|
2017-07-24 23:03:18 +00:00
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
use glib::translate::*;
|
|
|
|
use glib::value::{FromValue, SendValue, ToSendValue};
|
|
|
|
use glib::StaticType;
|
2017-07-07 13:04:54 +00:00
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
|
|
|
|
pub enum GetError {
|
2020-05-26 15:52:49 +00:00
|
|
|
#[error("GetError: Structure field with name {name} not found")]
|
2021-04-20 07:19:02 +00:00
|
|
|
FieldNotFound { name: &'static str },
|
2020-05-26 15:52:49 +00:00
|
|
|
#[error("GetError: Structure field with name {name} not retrieved")]
|
2019-08-11 07:33:34 +00:00
|
|
|
ValueGetError {
|
2021-04-20 07:19:02 +00:00
|
|
|
name: &'static str,
|
2020-05-26 15:52:49 +00:00
|
|
|
#[source]
|
2021-04-20 07:19:02 +00:00
|
|
|
type_mismatch_error: glib::value::ValueTypeMismatchOrNoneError,
|
2019-08-11 07:33:34 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
impl GetError {
|
|
|
|
fn new_field_not_found(name: &'static str) -> Self {
|
2020-03-22 14:18:47 +00:00
|
|
|
skip_assert_initialized!();
|
2019-08-11 07:33:34 +00:00
|
|
|
GetError::FieldNotFound { name }
|
|
|
|
}
|
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
fn from_value_get_error<E: GlibValueError>(name: &'static str, err: E) -> Self {
|
|
|
|
skip_assert_initialized!();
|
|
|
|
E::from_value_error(name, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub trait GlibValueError: 'static {
|
|
|
|
fn from_value_error(name: &'static str, err: Self) -> GetError;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl GlibValueError for glib::value::ValueTypeMismatchError {
|
|
|
|
fn from_value_error(name: &'static str, err: Self) -> GetError {
|
2020-03-22 14:18:47 +00:00
|
|
|
skip_assert_initialized!();
|
2019-08-11 07:33:34 +00:00
|
|
|
GetError::ValueGetError {
|
|
|
|
name,
|
2021-04-20 07:19:02 +00:00
|
|
|
type_mismatch_error: glib::value::ValueTypeMismatchOrNoneError::from(err),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl GlibValueError for glib::value::ValueTypeMismatchOrNoneError {
|
|
|
|
fn from_value_error(name: &'static str, err: Self) -> GetError {
|
|
|
|
skip_assert_initialized!();
|
|
|
|
GetError::ValueGetError {
|
|
|
|
name,
|
|
|
|
type_mismatch_error: err,
|
2019-08-11 07:33:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-01 13:15:59 +00:00
|
|
|
#[doc(alias = "GstStructure")]
|
2021-04-02 20:32:57 +00:00
|
|
|
pub struct Structure(ptr::NonNull<ffi::GstStructure>);
|
2017-11-15 20:33:51 +00:00
|
|
|
unsafe impl Send for Structure {}
|
2018-09-22 08:00:17 +00:00
|
|
|
unsafe impl Sync for Structure {}
|
2017-07-07 13:04:54 +00:00
|
|
|
|
|
|
|
impl Structure {
|
2017-11-11 12:14:49 +00:00
|
|
|
pub fn builder(name: &str) -> Builder {
|
|
|
|
assert_initialized_main_thread!();
|
|
|
|
Builder::new(name)
|
|
|
|
}
|
|
|
|
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_structure_new_empty")]
|
2017-07-07 13:04:54 +00:00
|
|
|
pub fn new_empty(name: &str) -> Structure {
|
2017-07-10 09:36:15 +00:00
|
|
|
assert_initialized_main_thread!();
|
2018-04-01 08:29:15 +00:00
|
|
|
unsafe {
|
2021-04-02 20:32:57 +00:00
|
|
|
let ptr = ffi::gst_structure_new_empty(name.to_glib_none().0);
|
2018-04-01 08:29:15 +00:00
|
|
|
assert!(!ptr.is_null());
|
2020-10-24 16:56:48 +00:00
|
|
|
Structure(ptr::NonNull::new_unchecked(ptr))
|
2018-04-01 08:29:15 +00:00
|
|
|
}
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
pub fn new(name: &str, values: &[(&str, &(dyn ToSendValue + Sync))]) -> Structure {
|
2017-07-10 09:36:15 +00:00
|
|
|
assert_initialized_main_thread!();
|
2017-07-07 13:04:54 +00:00
|
|
|
let mut structure = Structure::new_empty(name);
|
|
|
|
|
|
|
|
for &(f, v) in values {
|
2017-11-15 17:18:58 +00:00
|
|
|
structure.set_value(f, v.to_send_value());
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
structure
|
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
pub unsafe fn into_ptr(self) -> *mut ffi::GstStructure {
|
2020-04-09 12:59:14 +00:00
|
|
|
let s = mem::ManuallyDrop::new(self);
|
2021-04-02 20:32:57 +00:00
|
|
|
s.0.as_ptr()
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
2020-04-20 09:11:06 +00:00
|
|
|
|
|
|
|
#[allow(clippy::should_implement_trait)]
|
2021-09-21 21:54:11 +00:00
|
|
|
pub fn from_iter<'a, 'b>(
|
|
|
|
name: &str,
|
|
|
|
iter: impl IntoIterator<Item = (&'a str, &'b SendValue)>,
|
|
|
|
) -> Structure {
|
2020-04-20 09:11:06 +00:00
|
|
|
assert_initialized_main_thread!();
|
|
|
|
let mut structure = Structure::new_empty(name);
|
|
|
|
|
|
|
|
iter.into_iter().for_each(|(f, v)| unsafe {
|
|
|
|
let mut value = v.clone().into_raw();
|
2021-04-02 20:32:57 +00:00
|
|
|
ffi::gst_structure_take_value(structure.0.as_mut(), f.to_glib_none().0, &mut value);
|
2020-04-20 09:11:06 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
structure
|
|
|
|
}
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Deref for Structure {
|
|
|
|
type Target = StructureRef;
|
|
|
|
|
|
|
|
fn deref(&self) -> &StructureRef {
|
2021-04-02 20:32:57 +00:00
|
|
|
unsafe { &*(self.0.as_ptr() as *const StructureRef) }
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl DerefMut for Structure {
|
|
|
|
fn deref_mut(&mut self) -> &mut StructureRef {
|
2021-04-02 20:32:57 +00:00
|
|
|
unsafe { &mut *(self.0.as_ptr() as *mut StructureRef) }
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AsRef<StructureRef> for Structure {
|
|
|
|
fn as_ref(&self) -> &StructureRef {
|
|
|
|
self.deref()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AsMut<StructureRef> for Structure {
|
|
|
|
fn as_mut(&mut self) -> &mut StructureRef {
|
|
|
|
self.deref_mut()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Clone for Structure {
|
|
|
|
fn clone(&self) -> Self {
|
2018-04-01 08:29:15 +00:00
|
|
|
unsafe {
|
2021-04-02 20:32:57 +00:00
|
|
|
let ptr = ffi::gst_structure_copy(self.0.as_ref());
|
2018-04-01 08:29:15 +00:00
|
|
|
assert!(!ptr.is_null());
|
2020-10-24 16:56:48 +00:00
|
|
|
Structure(ptr::NonNull::new_unchecked(ptr))
|
2018-04-01 08:29:15 +00:00
|
|
|
}
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Drop for Structure {
|
|
|
|
fn drop(&mut self) {
|
2021-04-02 20:32:57 +00:00
|
|
|
unsafe { ffi::gst_structure_free(self.0.as_mut()) }
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Debug for Structure {
|
2017-12-01 09:21:20 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2018-04-07 10:37:44 +00:00
|
|
|
f.debug_tuple("Structure").field(&self.to_string()).finish()
|
2017-12-01 09:21:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for Structure {
|
2017-07-07 13:04:54 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2018-04-07 10:37:44 +00:00
|
|
|
// Need to make sure to not call ToString::to_string() here, which
|
|
|
|
// we have because of the Display impl. We need StructureRef::to_string()
|
|
|
|
f.write_str(&StructureRef::to_string(self.as_ref()))
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl PartialEq for Structure {
|
|
|
|
fn eq(&self, other: &Structure) -> bool {
|
|
|
|
self.as_ref().eq(other)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl PartialEq<StructureRef> for Structure {
|
|
|
|
fn eq(&self, other: &StructureRef) -> bool {
|
|
|
|
self.as_ref().eq(other)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Eq for Structure {}
|
|
|
|
|
2017-07-13 11:57:02 +00:00
|
|
|
impl str::FromStr for Structure {
|
2019-12-17 19:00:42 +00:00
|
|
|
type Err = glib::BoolError;
|
2017-07-13 11:57:02 +00:00
|
|
|
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_structure_from_string")]
|
2020-11-28 11:34:36 +00:00
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
2019-10-04 06:11:30 +00:00
|
|
|
assert_initialized_main_thread!();
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
let structure = ffi::gst_structure_from_string(s.to_glib_none().0, ptr::null_mut());
|
2019-10-04 06:11:30 +00:00
|
|
|
if structure.is_null() {
|
2020-12-17 22:38:06 +00:00
|
|
|
Err(glib::bool_error!("Failed to parse structure from string"))
|
2019-10-04 06:11:30 +00:00
|
|
|
} else {
|
2021-04-02 20:32:57 +00:00
|
|
|
Ok(Self(ptr::NonNull::new_unchecked(structure)))
|
2019-10-04 06:11:30 +00:00
|
|
|
}
|
|
|
|
}
|
2017-07-13 11:57:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-07 13:04:54 +00:00
|
|
|
impl Borrow<StructureRef> for Structure {
|
|
|
|
fn borrow(&self) -> &StructureRef {
|
2021-04-02 20:32:57 +00:00
|
|
|
self.as_ref()
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl BorrowMut<StructureRef> for Structure {
|
|
|
|
fn borrow_mut(&mut self) -> &mut StructureRef {
|
2021-04-02 20:32:57 +00:00
|
|
|
self.as_mut()
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ToOwned for StructureRef {
|
|
|
|
type Owned = Structure;
|
|
|
|
|
|
|
|
fn to_owned(&self) -> Structure {
|
2018-04-01 08:29:15 +00:00
|
|
|
unsafe {
|
2021-04-02 20:32:57 +00:00
|
|
|
let ptr = ffi::gst_structure_copy(&self.0);
|
2018-04-01 08:29:15 +00:00
|
|
|
assert!(!ptr.is_null());
|
2020-10-24 16:56:48 +00:00
|
|
|
Structure(ptr::NonNull::new_unchecked(ptr))
|
2018-04-01 08:29:15 +00:00
|
|
|
}
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-10 14:13:49 +00:00
|
|
|
impl glib::types::StaticType for Structure {
|
|
|
|
fn static_type() -> glib::types::Type {
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { from_glib(ffi::gst_structure_get_type()) }
|
2017-07-10 14:13:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
impl<'a> ToGlibPtr<'a, *const ffi::GstStructure> for Structure {
|
2017-07-07 13:04:54 +00:00
|
|
|
type Storage = &'a Self;
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
fn to_glib_none(&'a self) -> Stash<'a, *const ffi::GstStructure, Self> {
|
2021-04-02 20:32:57 +00:00
|
|
|
unsafe { Stash(self.0.as_ref(), self) }
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
fn to_glib_full(&self) -> *const ffi::GstStructure {
|
2021-04-02 20:32:57 +00:00
|
|
|
unsafe { ffi::gst_structure_copy(self.0.as_ref()) }
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
impl<'a> ToGlibPtr<'a, *mut ffi::GstStructure> for Structure {
|
2017-07-07 13:04:54 +00:00
|
|
|
type Storage = &'a Self;
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
fn to_glib_none(&'a self) -> Stash<'a, *mut ffi::GstStructure, Self> {
|
2021-04-02 20:32:57 +00:00
|
|
|
unsafe {
|
|
|
|
Stash(
|
|
|
|
self.0.as_ref() as *const ffi::GstStructure as *mut ffi::GstStructure,
|
|
|
|
self,
|
|
|
|
)
|
|
|
|
}
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
fn to_glib_full(&self) -> *mut ffi::GstStructure {
|
2021-04-02 20:32:57 +00:00
|
|
|
unsafe { ffi::gst_structure_copy(self.0.as_ref()) }
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
impl<'a> ToGlibPtrMut<'a, *mut ffi::GstStructure> for Structure {
|
2017-07-07 13:04:54 +00:00
|
|
|
type Storage = &'a mut Self;
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
fn to_glib_none_mut(&'a mut self) -> StashMut<*mut ffi::GstStructure, Self> {
|
2021-04-02 20:32:57 +00:00
|
|
|
unsafe { StashMut(self.0.as_mut(), self) }
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
impl FromGlibPtrNone<*const ffi::GstStructure> for Structure {
|
|
|
|
unsafe fn from_glib_none(ptr: *const ffi::GstStructure) -> Self {
|
2018-04-01 08:29:15 +00:00
|
|
|
assert!(!ptr.is_null());
|
2020-11-21 13:46:48 +00:00
|
|
|
let ptr = ffi::gst_structure_copy(ptr);
|
2018-04-01 08:29:15 +00:00
|
|
|
assert!(!ptr.is_null());
|
2021-04-02 20:32:57 +00:00
|
|
|
Structure(ptr::NonNull::new_unchecked(ptr))
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
impl FromGlibPtrNone<*mut ffi::GstStructure> for Structure {
|
|
|
|
unsafe fn from_glib_none(ptr: *mut ffi::GstStructure) -> Self {
|
2018-04-01 08:29:15 +00:00
|
|
|
assert!(!ptr.is_null());
|
2020-11-21 13:46:48 +00:00
|
|
|
let ptr = ffi::gst_structure_copy(ptr);
|
2018-04-01 08:29:15 +00:00
|
|
|
assert!(!ptr.is_null());
|
2021-04-02 20:32:57 +00:00
|
|
|
Structure(ptr::NonNull::new_unchecked(ptr))
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
impl FromGlibPtrFull<*const ffi::GstStructure> for Structure {
|
|
|
|
unsafe fn from_glib_full(ptr: *const ffi::GstStructure) -> Self {
|
2018-04-01 08:29:15 +00:00
|
|
|
assert!(!ptr.is_null());
|
2021-04-02 20:32:57 +00:00
|
|
|
Structure(ptr::NonNull::new_unchecked(ptr as *mut ffi::GstStructure))
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
impl FromGlibPtrFull<*mut ffi::GstStructure> for Structure {
|
|
|
|
unsafe fn from_glib_full(ptr: *mut ffi::GstStructure) -> Self {
|
2018-04-01 08:29:15 +00:00
|
|
|
assert!(!ptr.is_null());
|
2021-04-02 20:32:57 +00:00
|
|
|
Structure(ptr::NonNull::new_unchecked(ptr))
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
impl glib::value::ValueType for Structure {
|
|
|
|
type Type = Self;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe impl<'a> glib::value::FromValue<'a> for Structure {
|
|
|
|
type Checker = glib::value::GenericValueTypeOrNoneChecker<Self>;
|
|
|
|
|
|
|
|
unsafe fn from_value(value: &'a glib::Value) -> Self {
|
|
|
|
skip_assert_initialized!();
|
|
|
|
from_glib_none(
|
|
|
|
glib::gobject_ffi::g_value_get_boxed(value.to_glib_none().0) as *mut ffi::GstStructure
|
|
|
|
)
|
2017-08-09 22:13:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
impl glib::value::ToValue for Structure {
|
|
|
|
fn to_value(&self) -> glib::Value {
|
2021-04-25 16:46:18 +00:00
|
|
|
let mut value = glib::Value::for_value_type::<Self>();
|
2021-04-20 07:19:02 +00:00
|
|
|
unsafe {
|
|
|
|
glib::gobject_ffi::g_value_set_boxed(
|
|
|
|
value.to_glib_none_mut().0,
|
|
|
|
glib::translate::ToGlibPtr::<*const ffi::GstStructure>::to_glib_none(self).0
|
|
|
|
as *mut _,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
value
|
|
|
|
}
|
|
|
|
|
|
|
|
fn value_type(&self) -> glib::Type {
|
|
|
|
Self::static_type()
|
2017-08-09 22:13:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
impl glib::value::ToValueOptional for Structure {
|
|
|
|
fn to_value_optional(s: Option<&Self>) -> glib::Value {
|
|
|
|
skip_assert_initialized!();
|
2021-04-25 16:46:18 +00:00
|
|
|
let mut value = glib::Value::for_value_type::<Self>();
|
2021-04-20 07:19:02 +00:00
|
|
|
unsafe {
|
|
|
|
glib::gobject_ffi::g_value_set_boxed(
|
|
|
|
value.to_glib_none_mut().0,
|
|
|
|
glib::translate::ToGlibPtr::<*const ffi::GstStructure>::to_glib_none(&s).0
|
|
|
|
as *mut _,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
value
|
2017-08-18 13:28:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-09 22:13:28 +00:00
|
|
|
impl GlibPtrDefault for Structure {
|
2020-11-21 13:46:48 +00:00
|
|
|
type GlibType = *mut ffi::GstStructure;
|
2017-08-09 22:13:28 +00:00
|
|
|
}
|
|
|
|
|
2020-10-24 17:06:59 +00:00
|
|
|
#[repr(transparent)]
|
2021-06-01 13:15:59 +00:00
|
|
|
#[doc(alias = "GstStructure")]
|
2020-11-21 13:46:48 +00:00
|
|
|
pub struct StructureRef(ffi::GstStructure);
|
2017-07-07 13:04:54 +00:00
|
|
|
|
2018-09-22 08:00:17 +00:00
|
|
|
unsafe impl Send for StructureRef {}
|
|
|
|
unsafe impl Sync for StructureRef {}
|
|
|
|
|
2017-07-07 13:04:54 +00:00
|
|
|
impl StructureRef {
|
2020-11-21 13:46:48 +00:00
|
|
|
pub unsafe fn from_glib_borrow<'a>(ptr: *const ffi::GstStructure) -> &'a StructureRef {
|
2017-07-07 13:04:54 +00:00
|
|
|
assert!(!ptr.is_null());
|
|
|
|
|
|
|
|
&*(ptr as *mut StructureRef)
|
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
pub unsafe fn from_glib_borrow_mut<'a>(ptr: *mut ffi::GstStructure) -> &'a mut StructureRef {
|
2017-07-07 13:04:54 +00:00
|
|
|
assert!(!ptr.is_null());
|
|
|
|
|
|
|
|
&mut *(ptr as *mut StructureRef)
|
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
pub unsafe fn as_ptr(&self) -> *const ffi::GstStructure {
|
|
|
|
self as *const Self as *const ffi::GstStructure
|
2017-07-24 23:03:18 +00:00
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
pub unsafe fn as_mut_ptr(&self) -> *mut ffi::GstStructure {
|
|
|
|
self as *const Self as *mut ffi::GstStructure
|
2017-07-24 23:03:18 +00:00
|
|
|
}
|
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
pub fn get<'a, T: FromValue<'a>>(&'a self, name: &str) -> Result<T, GetError>
|
|
|
|
where
|
|
|
|
<<T as FromValue<'a>>::Checker as glib::value::ValueTypeChecker>::Error: GlibValueError,
|
|
|
|
{
|
|
|
|
let name = glib::Quark::from_string(name);
|
|
|
|
self.get_by_quark(name)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_optional<'a, T: FromValue<'a>>(&'a self, name: &str) -> Result<Option<T>, GetError>
|
|
|
|
where
|
|
|
|
<<T as FromValue<'a>>::Checker as glib::value::ValueTypeChecker>::Error: GlibValueError,
|
|
|
|
{
|
|
|
|
let name = glib::Quark::from_string(name);
|
|
|
|
self.get_optional_by_quark(name)
|
|
|
|
}
|
|
|
|
|
2021-05-02 09:41:18 +00:00
|
|
|
#[doc(alias = "get_value")]
|
2021-04-20 07:19:02 +00:00
|
|
|
pub fn value(&self, name: &str) -> Result<&SendValue, GetError> {
|
|
|
|
let name = glib::Quark::from_string(name);
|
|
|
|
self.value_by_quark(name)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_by_quark<'a, T: FromValue<'a>>(&'a self, name: glib::Quark) -> Result<T, GetError>
|
|
|
|
where
|
|
|
|
<<T as FromValue<'a>>::Checker as glib::value::ValueTypeChecker>::Error: GlibValueError,
|
|
|
|
{
|
|
|
|
self.value_by_quark(name)?
|
2019-08-11 07:33:34 +00:00
|
|
|
.get()
|
2021-04-20 07:19:02 +00:00
|
|
|
.map_err(|err| GetError::from_value_get_error(name.to_string(), err))
|
2019-08-13 15:02:57 +00:00
|
|
|
}
|
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
pub fn get_optional_by_quark<'a, T: FromValue<'a>>(
|
|
|
|
&'a self,
|
|
|
|
name: glib::Quark,
|
|
|
|
) -> Result<Option<T>, GetError>
|
|
|
|
where
|
|
|
|
<<T as FromValue<'a>>::Checker as glib::value::ValueTypeChecker>::Error: GlibValueError,
|
|
|
|
{
|
|
|
|
self.value_by_quark(name)
|
|
|
|
.ok()
|
|
|
|
.map(|v| v.get())
|
|
|
|
.transpose()
|
|
|
|
.map_err(|err| GetError::from_value_get_error(name.to_string(), err))
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
pub fn value_by_quark(&self, name: glib::Quark) -> Result<&SendValue, GetError> {
|
2017-07-07 13:04:54 +00:00
|
|
|
unsafe {
|
2021-04-27 15:15:46 +00:00
|
|
|
let value = ffi::gst_structure_id_get_value(&self.0, name.into_glib());
|
2017-07-07 13:04:54 +00:00
|
|
|
|
|
|
|
if value.is_null() {
|
2021-04-20 07:19:02 +00:00
|
|
|
return Err(GetError::new_field_not_found(name.to_string()));
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
|
2019-08-11 07:33:34 +00:00
|
|
|
Ok(&*(value as *const SendValue))
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
pub fn set<T: ToSendValue + Sync>(&mut self, name: &str, value: T) {
|
2017-11-15 17:18:58 +00:00
|
|
|
let value = value.to_send_value();
|
2017-07-07 13:04:54 +00:00
|
|
|
self.set_value(name, value);
|
|
|
|
}
|
|
|
|
|
2020-03-09 10:55:14 +00:00
|
|
|
pub fn set_value(&mut self, name: &str, value: SendValue) {
|
2017-07-07 13:04:54 +00:00
|
|
|
unsafe {
|
2020-03-09 10:55:14 +00:00
|
|
|
let mut value = value.into_raw();
|
2020-11-21 13:46:48 +00:00
|
|
|
ffi::gst_structure_take_value(&mut self.0, name.to_glib_none().0, &mut value);
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
pub fn set_by_quark<T: ToSendValue + Sync>(&mut self, name: glib::Quark, value: T) {
|
|
|
|
let value = value.to_send_value();
|
|
|
|
self.set_value_by_quark(name, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_value_by_quark(&mut self, name: glib::Quark, value: SendValue) {
|
|
|
|
unsafe {
|
|
|
|
let mut value = value.into_raw();
|
2021-04-27 15:15:46 +00:00
|
|
|
ffi::gst_structure_id_take_value(&mut self.0, name.into_glib(), &mut value);
|
2021-04-20 07:19:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-02 09:41:18 +00:00
|
|
|
#[doc(alias = "get_name")]
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_structure_get_name")]
|
2021-04-11 19:39:50 +00:00
|
|
|
pub fn name<'a>(&self) -> &'a str {
|
2017-07-07 13:04:54 +00:00
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
CStr::from_ptr(ffi::gst_structure_get_name(&self.0))
|
2017-07-10 21:33:24 +00:00
|
|
|
.to_str()
|
|
|
|
.unwrap()
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
pub fn name_quark(&self) -> glib::Quark {
|
|
|
|
unsafe { from_glib(ffi::gst_structure_get_name_id(&self.0)) }
|
|
|
|
}
|
|
|
|
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_structure_set_name")]
|
2017-07-24 23:03:18 +00:00
|
|
|
pub fn set_name(&mut self, name: &str) {
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { ffi::gst_structure_set_name(&mut self.0, name.to_glib_none().0) }
|
2017-07-24 23:03:18 +00:00
|
|
|
}
|
|
|
|
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_structure_has_field")]
|
2017-07-07 13:04:54 +00:00
|
|
|
pub fn has_field(&self, field: &str) -> bool {
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
from_glib(ffi::gst_structure_has_field(
|
2017-07-10 21:33:24 +00:00
|
|
|
&self.0,
|
|
|
|
field.to_glib_none().0,
|
|
|
|
))
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-24 23:03:18 +00:00
|
|
|
pub fn has_field_with_type(&self, field: &str, type_: glib::Type) -> bool {
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
from_glib(ffi::gst_structure_has_field_typed(
|
2017-07-24 23:03:18 +00:00
|
|
|
&self.0,
|
|
|
|
field.to_glib_none().0,
|
2021-04-27 15:15:46 +00:00
|
|
|
type_.into_glib(),
|
2017-07-24 23:03:18 +00:00
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
pub fn has_field_by_quark(&self, field: glib::Quark) -> bool {
|
2021-04-27 15:15:46 +00:00
|
|
|
unsafe { from_glib(ffi::gst_structure_id_has_field(&self.0, field.into_glib())) }
|
2021-04-20 07:19:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn has_field_with_type_by_quark(&self, field: glib::Quark, type_: glib::Type) -> bool {
|
|
|
|
unsafe {
|
|
|
|
from_glib(ffi::gst_structure_id_has_field_typed(
|
|
|
|
&self.0,
|
2021-04-27 15:15:46 +00:00
|
|
|
field.into_glib(),
|
|
|
|
type_.into_glib(),
|
2021-04-20 07:19:02 +00:00
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_structure_remove_field")]
|
2017-07-07 13:04:54 +00:00
|
|
|
pub fn remove_field(&mut self, field: &str) {
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
ffi::gst_structure_remove_field(&mut self.0, field.to_glib_none().0);
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-24 23:03:18 +00:00
|
|
|
pub fn remove_fields(&mut self, fields: &[&str]) {
|
|
|
|
for f in fields {
|
|
|
|
self.remove_field(f)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_structure_remove_all_fields")]
|
2017-07-07 13:04:54 +00:00
|
|
|
pub fn remove_all_fields(&mut self) {
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
ffi::gst_structure_remove_all_fields(&mut self.0);
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn fields(&self) -> FieldIterator {
|
|
|
|
FieldIterator::new(self)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn iter(&self) -> Iter {
|
|
|
|
Iter::new(self)
|
|
|
|
}
|
|
|
|
|
2021-05-02 09:41:18 +00:00
|
|
|
#[doc(alias = "get_nth_field_name")]
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_structure_nth_field_name")]
|
2021-04-20 10:23:24 +00:00
|
|
|
pub fn nth_field_name<'a>(&self, idx: u32) -> Option<&'a str> {
|
2017-07-07 13:04:54 +00:00
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
let field_name = ffi::gst_structure_nth_field_name(&self.0, idx);
|
2017-07-07 13:04:54 +00:00
|
|
|
if field_name.is_null() {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
Some(CStr::from_ptr(field_name).to_str().unwrap())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_structure_n_fields")]
|
2017-07-24 23:03:18 +00:00
|
|
|
pub fn n_fields(&self) -> u32 {
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { ffi::gst_structure_n_fields(&self.0) as u32 }
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_structure_can_intersect")]
|
2017-07-24 23:03:18 +00:00
|
|
|
pub fn can_intersect(&self, other: &StructureRef) -> bool {
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { from_glib(ffi::gst_structure_can_intersect(&self.0, &other.0)) }
|
2017-07-24 23:03:18 +00:00
|
|
|
}
|
|
|
|
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_structure_intersect")]
|
2017-12-17 09:52:52 +00:00
|
|
|
pub fn intersect(&self, other: &StructureRef) -> Option<Structure> {
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { from_glib_full(ffi::gst_structure_intersect(&self.0, &other.0)) }
|
2017-07-24 23:03:18 +00:00
|
|
|
}
|
|
|
|
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_structure_is_subset")]
|
2017-07-24 23:03:18 +00:00
|
|
|
pub fn is_subset(&self, superset: &StructureRef) -> bool {
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { from_glib(ffi::gst_structure_is_subset(&self.0, &superset.0)) }
|
2017-07-24 23:03:18 +00:00
|
|
|
}
|
|
|
|
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_structure_fixate")]
|
2017-07-24 23:03:18 +00:00
|
|
|
pub fn fixate(&mut self) {
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { ffi::gst_structure_fixate(&mut self.0) }
|
2017-07-24 23:03:18 +00:00
|
|
|
}
|
|
|
|
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_structure_fixate_field")]
|
2017-07-24 23:03:18 +00:00
|
|
|
pub fn fixate_field(&mut self, name: &str) -> bool {
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
from_glib(ffi::gst_structure_fixate_field(
|
2017-07-24 23:03:18 +00:00
|
|
|
&mut self.0,
|
|
|
|
name.to_glib_none().0,
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_structure_fixate_field_boolean")]
|
2017-07-24 23:03:18 +00:00
|
|
|
pub fn fixate_field_bool(&mut self, name: &str, target: bool) -> bool {
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
from_glib(ffi::gst_structure_fixate_field_boolean(
|
2017-07-24 23:03:18 +00:00
|
|
|
&mut self.0,
|
|
|
|
name.to_glib_none().0,
|
2021-04-27 15:15:46 +00:00
|
|
|
target.into_glib(),
|
2017-07-24 23:03:18 +00:00
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_structure_fixate_field_string")]
|
2017-07-24 23:03:18 +00:00
|
|
|
pub fn fixate_field_str(&mut self, name: &str, target: &str) -> bool {
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
from_glib(ffi::gst_structure_fixate_field_string(
|
2017-07-24 23:03:18 +00:00
|
|
|
&mut self.0,
|
|
|
|
name.to_glib_none().0,
|
|
|
|
target.to_glib_none().0,
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_structure_fixate_field_nearest_double")]
|
2017-07-24 23:03:18 +00:00
|
|
|
pub fn fixate_field_nearest_double(&mut self, name: &str, target: f64) -> bool {
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
from_glib(ffi::gst_structure_fixate_field_nearest_double(
|
2017-07-24 23:03:18 +00:00
|
|
|
&mut self.0,
|
|
|
|
name.to_glib_none().0,
|
|
|
|
target,
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_structure_fixate_field_nearest_fraction")]
|
2017-07-24 23:03:18 +00:00
|
|
|
pub fn fixate_field_nearest_fraction<T: Into<Fraction>>(
|
|
|
|
&mut self,
|
|
|
|
name: &str,
|
|
|
|
target: T,
|
|
|
|
) -> bool {
|
2017-08-30 11:39:09 +00:00
|
|
|
skip_assert_initialized!();
|
|
|
|
|
2017-07-24 23:03:18 +00:00
|
|
|
let target = target.into();
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
from_glib(ffi::gst_structure_fixate_field_nearest_fraction(
|
2017-07-24 23:03:18 +00:00
|
|
|
&mut self.0,
|
|
|
|
name.to_glib_none().0,
|
|
|
|
*target.numer(),
|
|
|
|
*target.denom(),
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_structure_fixate_field_nearest_int")]
|
2017-07-24 23:03:18 +00:00
|
|
|
pub fn fixate_field_nearest_int(&mut self, name: &str, target: i32) -> bool {
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
from_glib(ffi::gst_structure_fixate_field_nearest_int(
|
2017-07-24 23:03:18 +00:00
|
|
|
&mut self.0,
|
|
|
|
name.to_glib_none().0,
|
|
|
|
target,
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
2021-07-09 11:55:29 +00:00
|
|
|
|
|
|
|
#[cfg(any(feature = "v1_20", feature = "dox"))]
|
|
|
|
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
|
|
|
|
#[doc(alias = "gst_structure_serialize")]
|
|
|
|
pub fn serialize(&self, flags: crate::SerializeFlags) -> glib::GString {
|
|
|
|
unsafe { from_glib_full(ffi::gst_structure_serialize(&self.0, flags.into_glib())) }
|
|
|
|
}
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
|
2018-04-06 10:21:45 +00:00
|
|
|
impl fmt::Display for StructureRef {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2020-11-21 13:46:48 +00:00
|
|
|
let s = unsafe { glib::GString::from_glib_full(ffi::gst_structure_to_string(&self.0)) };
|
2019-10-04 06:11:30 +00:00
|
|
|
f.write_str(&s)
|
2018-04-06 10:21:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-07 13:04:54 +00:00
|
|
|
impl fmt::Debug for StructureRef {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2018-04-07 10:37:44 +00:00
|
|
|
f.write_str(&self.to_string())
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl PartialEq for StructureRef {
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_structure_is_equal")]
|
2017-07-07 13:04:54 +00:00
|
|
|
fn eq(&self, other: &StructureRef) -> bool {
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { from_glib(ffi::gst_structure_is_equal(&self.0, &other.0)) }
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Eq for StructureRef {}
|
|
|
|
|
2020-05-27 10:07:32 +00:00
|
|
|
impl glib::types::StaticType for StructureRef {
|
|
|
|
fn static_type() -> glib::types::Type {
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { from_glib(ffi::gst_structure_get_type()) }
|
2020-05-27 10:07:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
unsafe impl<'a> glib::value::FromValue<'a> for &'a StructureRef {
|
|
|
|
type Checker = glib::value::GenericValueTypeOrNoneChecker<Self>;
|
|
|
|
|
|
|
|
unsafe fn from_value(value: &'a glib::Value) -> Self {
|
|
|
|
skip_assert_initialized!();
|
|
|
|
&*(glib::gobject_ffi::g_value_get_boxed(value.to_glib_none().0) as *const StructureRef)
|
2020-05-27 10:07:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
impl glib::value::ToValue for StructureRef {
|
|
|
|
fn to_value(&self) -> glib::Value {
|
|
|
|
let mut value = glib::Value::for_value_type::<Structure>();
|
|
|
|
unsafe {
|
|
|
|
glib::gobject_ffi::g_value_set_boxed(
|
|
|
|
value.to_glib_none_mut().0,
|
|
|
|
self.as_ptr() as *mut _,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
value
|
|
|
|
}
|
|
|
|
|
|
|
|
fn value_type(&self) -> glib::Type {
|
|
|
|
Self::static_type()
|
2020-05-27 10:07:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
impl glib::value::ToValueOptional for StructureRef {
|
|
|
|
fn to_value_optional(s: Option<&Self>) -> glib::Value {
|
|
|
|
skip_assert_initialized!();
|
|
|
|
let mut value = glib::Value::for_value_type::<Structure>();
|
|
|
|
unsafe {
|
|
|
|
glib::gobject_ffi::g_value_set_boxed(
|
|
|
|
value.to_glib_none_mut().0,
|
|
|
|
s.map(|s| s.as_ptr()).unwrap_or(ptr::null()) as *mut _,
|
|
|
|
)
|
2020-05-27 10:07:32 +00:00
|
|
|
}
|
2021-04-20 07:19:02 +00:00
|
|
|
value
|
2020-05-27 10:07:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-22 15:43:29 +00:00
|
|
|
#[derive(Debug)]
|
2017-07-07 13:04:54 +00:00
|
|
|
pub struct FieldIterator<'a> {
|
|
|
|
structure: &'a StructureRef,
|
|
|
|
idx: u32,
|
|
|
|
n_fields: u32,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> FieldIterator<'a> {
|
2017-08-30 11:39:09 +00:00
|
|
|
fn new(structure: &'a StructureRef) -> FieldIterator<'a> {
|
|
|
|
skip_assert_initialized!();
|
2017-07-07 13:04:54 +00:00
|
|
|
let n_fields = structure.n_fields();
|
|
|
|
|
|
|
|
FieldIterator {
|
2018-07-20 07:21:06 +00:00
|
|
|
structure,
|
2017-07-07 13:04:54 +00:00
|
|
|
idx: 0,
|
2018-07-20 07:21:06 +00:00
|
|
|
n_fields,
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Iterator for FieldIterator<'a> {
|
2020-03-12 18:17:15 +00:00
|
|
|
type Item = &'static str;
|
2017-07-07 13:04:54 +00:00
|
|
|
|
2020-03-12 18:17:15 +00:00
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
2017-07-07 13:04:54 +00:00
|
|
|
if self.idx >= self.n_fields {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
2021-04-20 10:24:17 +00:00
|
|
|
if let Some(field_name) = self.structure.nth_field_name(self.idx) {
|
2017-07-07 13:04:54 +00:00
|
|
|
self.idx += 1;
|
|
|
|
Some(field_name)
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
|
|
if self.idx == self.n_fields {
|
|
|
|
return (0, Some(0));
|
|
|
|
}
|
|
|
|
|
|
|
|
let remaining = (self.n_fields - self.idx) as usize;
|
|
|
|
|
|
|
|
(remaining, Some(remaining))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> DoubleEndedIterator for FieldIterator<'a> {
|
|
|
|
fn next_back(&mut self) -> Option<Self::Item> {
|
|
|
|
if self.idx == self.n_fields {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
self.n_fields -= 1;
|
2021-05-05 08:51:42 +00:00
|
|
|
self.structure.nth_field_name(self.n_fields)
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> ExactSizeIterator for FieldIterator<'a> {}
|
|
|
|
|
2019-01-22 15:43:29 +00:00
|
|
|
#[derive(Debug)]
|
2017-07-07 13:04:54 +00:00
|
|
|
pub struct Iter<'a> {
|
|
|
|
iter: FieldIterator<'a>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Iter<'a> {
|
2017-08-30 11:39:09 +00:00
|
|
|
fn new(structure: &'a StructureRef) -> Iter<'a> {
|
|
|
|
skip_assert_initialized!();
|
2017-07-24 08:52:28 +00:00
|
|
|
Iter {
|
|
|
|
iter: FieldIterator::new(structure),
|
|
|
|
}
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Iterator for Iter<'a> {
|
2020-03-12 18:17:15 +00:00
|
|
|
type Item = (&'static str, &'a SendValue);
|
2017-07-07 13:04:54 +00:00
|
|
|
|
2020-03-12 18:17:15 +00:00
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
2017-07-07 13:04:54 +00:00
|
|
|
if let Some(f) = self.iter.next() {
|
2021-04-20 10:24:17 +00:00
|
|
|
let v = self.iter.structure.value(f);
|
2017-07-07 13:04:54 +00:00
|
|
|
Some((f, v.unwrap()))
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
|
|
self.iter.size_hint()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> DoubleEndedIterator for Iter<'a> {
|
|
|
|
fn next_back(&mut self) -> Option<Self::Item> {
|
|
|
|
if let Some(f) = self.iter.next_back() {
|
2021-04-20 10:24:17 +00:00
|
|
|
let v = self.iter.structure.value(f);
|
2017-07-07 13:04:54 +00:00
|
|
|
Some((f, v.unwrap()))
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> ExactSizeIterator for Iter<'a> {}
|
|
|
|
|
2019-01-22 15:43:29 +00:00
|
|
|
#[derive(Debug)]
|
2017-11-11 12:14:49 +00:00
|
|
|
pub struct Builder {
|
|
|
|
s: Structure,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Builder {
|
|
|
|
fn new(name: &str) -> Self {
|
2020-03-22 14:18:47 +00:00
|
|
|
skip_assert_initialized!();
|
2017-11-11 12:14:49 +00:00
|
|
|
Builder {
|
|
|
|
s: Structure::new_empty(name),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
pub fn field<V: ToSendValue + Sync>(mut self, name: &str, value: V) -> Self {
|
2017-11-11 12:14:49 +00:00
|
|
|
self.s.set(name, value);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn build(self) -> Structure {
|
|
|
|
self.s
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-07 13:04:54 +00:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
2019-10-04 06:11:30 +00:00
|
|
|
use std::str::FromStr;
|
2017-07-07 13:04:54 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn new_set_get() {
|
2019-08-16 13:04:01 +00:00
|
|
|
use glib::{value, Type};
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
crate::init().unwrap();
|
2017-07-07 13:04:54 +00:00
|
|
|
|
|
|
|
let mut s = Structure::new_empty("test");
|
2021-04-11 19:39:50 +00:00
|
|
|
assert_eq!(s.name(), "test");
|
2017-07-07 13:04:54 +00:00
|
|
|
|
2017-11-26 21:58:02 +00:00
|
|
|
s.set("f1", &"abc");
|
|
|
|
s.set("f2", &String::from("bcd"));
|
|
|
|
s.set("f3", &123i32);
|
2017-07-07 13:04:54 +00:00
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
assert_eq!(s.get::<&str>("f1"), Ok("abc"));
|
|
|
|
assert_eq!(s.get::<Option<&str>>("f2"), Ok(Some("bcd")));
|
|
|
|
assert_eq!(s.get::<i32>("f3"), Ok(123i32));
|
2019-08-13 15:02:57 +00:00
|
|
|
assert_eq!(s.get_optional::<&str>("f1"), Ok(Some("abc")));
|
|
|
|
assert_eq!(s.get_optional::<&str>("f4"), Ok(None));
|
|
|
|
assert_eq!(s.get_optional::<i32>("f3"), Ok(Some(123i32)));
|
|
|
|
assert_eq!(s.get_optional::<i32>("f4"), Ok(None));
|
2019-08-11 07:33:34 +00:00
|
|
|
|
2019-08-16 13:04:01 +00:00
|
|
|
assert_eq!(
|
|
|
|
s.get::<i32>("f2"),
|
|
|
|
Err(GetError::from_value_get_error(
|
|
|
|
"f2",
|
2021-04-20 07:19:02 +00:00
|
|
|
value::ValueTypeMismatchError::new(Type::STRING, Type::I32),
|
2019-08-16 13:04:01 +00:00
|
|
|
))
|
|
|
|
);
|
|
|
|
assert_eq!(
|
2021-04-20 07:19:02 +00:00
|
|
|
s.get::<bool>("f3"),
|
2019-08-16 13:04:01 +00:00
|
|
|
Err(GetError::from_value_get_error(
|
|
|
|
"f3",
|
2021-04-20 07:19:02 +00:00
|
|
|
value::ValueTypeMismatchError::new(Type::I32, Type::BOOL),
|
2019-08-16 13:04:01 +00:00
|
|
|
))
|
|
|
|
);
|
|
|
|
assert_eq!(
|
|
|
|
s.get::<&str>("f4"),
|
|
|
|
Err(GetError::new_field_not_found("f4"))
|
|
|
|
);
|
2021-04-20 07:19:02 +00:00
|
|
|
assert_eq!(s.get::<i32>("f4"), Err(GetError::new_field_not_found("f4")));
|
2017-07-07 13:04:54 +00:00
|
|
|
|
|
|
|
assert_eq!(s.fields().collect::<Vec<_>>(), vec!["f1", "f2", "f3"]);
|
2017-07-12 07:38:34 +00:00
|
|
|
|
|
|
|
let v = s.iter().map(|(f, v)| (f, v.clone())).collect::<Vec<_>>();
|
|
|
|
assert_eq!(v.len(), 3);
|
|
|
|
assert_eq!(v[0].0, "f1");
|
2021-04-20 07:19:02 +00:00
|
|
|
assert_eq!(v[0].1.get::<&str>(), Ok("abc"));
|
2017-07-12 07:38:34 +00:00
|
|
|
assert_eq!(v[1].0, "f2");
|
2021-04-20 07:19:02 +00:00
|
|
|
assert_eq!(v[1].1.get::<&str>(), Ok("bcd"));
|
2017-07-12 07:38:34 +00:00
|
|
|
assert_eq!(v[2].0, "f3");
|
2021-04-20 07:19:02 +00:00
|
|
|
assert_eq!(v[2].1.get::<i32>(), Ok(123i32));
|
2017-07-07 13:04:54 +00:00
|
|
|
|
2017-07-31 11:16:42 +00:00
|
|
|
let s2 = Structure::new("test", &[("f1", &"abc"), ("f2", &"bcd"), ("f3", &123i32)]);
|
2017-07-07 13:04:54 +00:00
|
|
|
assert_eq!(s, s2);
|
|
|
|
}
|
2017-11-11 12:14:49 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_builder() {
|
2020-11-21 13:46:48 +00:00
|
|
|
crate::init().unwrap();
|
2017-11-11 12:14:49 +00:00
|
|
|
|
|
|
|
let s = Structure::builder("test")
|
2017-11-26 21:58:02 +00:00
|
|
|
.field("f1", &"abc")
|
|
|
|
.field("f2", &String::from("bcd"))
|
|
|
|
.field("f3", &123i32)
|
2017-11-11 12:14:49 +00:00
|
|
|
.build();
|
|
|
|
|
2021-04-11 19:39:50 +00:00
|
|
|
assert_eq!(s.name(), "test");
|
2021-04-20 07:19:02 +00:00
|
|
|
assert_eq!(s.get::<&str>("f1"), Ok("abc"));
|
|
|
|
assert_eq!(s.get::<&str>("f2"), Ok("bcd"));
|
|
|
|
assert_eq!(s.get::<i32>("f3"), Ok(123i32));
|
2017-11-11 12:14:49 +00:00
|
|
|
}
|
2018-04-06 10:01:17 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_string_conversion() {
|
2020-11-21 13:46:48 +00:00
|
|
|
crate::init().unwrap();
|
2019-01-27 01:02:11 +00:00
|
|
|
|
2018-04-06 10:16:47 +00:00
|
|
|
let a = "Test, f1=(string)abc, f2=(uint)123;";
|
2018-04-06 10:01:17 +00:00
|
|
|
|
2021-07-30 10:19:24 +00:00
|
|
|
let s = Structure::from_str(a).unwrap();
|
2021-04-20 07:19:02 +00:00
|
|
|
assert_eq!(s.get::<&str>("f1"), Ok("abc"));
|
|
|
|
assert_eq!(s.get::<u32>("f2"), Ok(123));
|
2018-04-06 10:01:17 +00:00
|
|
|
|
|
|
|
assert_eq!(a, s.to_string());
|
|
|
|
}
|
2019-09-24 09:34:08 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_from_value_optional() {
|
2021-04-20 07:19:02 +00:00
|
|
|
use glib::ToValue;
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
crate::init().unwrap();
|
2019-09-24 09:34:08 +00:00
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
let a = None::<&Structure>.to_value();
|
|
|
|
assert!(a.get::<Option<Structure>>().unwrap().is_none());
|
2021-07-30 10:19:24 +00:00
|
|
|
let b = Structure::from_str("foo").unwrap().to_value();
|
2021-04-20 07:19:02 +00:00
|
|
|
assert!(b.get::<Option<Structure>>().unwrap().is_some());
|
2019-09-24 09:34:08 +00:00
|
|
|
}
|
2020-04-20 09:11:06 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_new_from_iter() {
|
2020-11-21 13:46:48 +00:00
|
|
|
crate::init().unwrap();
|
2020-04-20 09:11:06 +00:00
|
|
|
|
|
|
|
let s = Structure::builder("test")
|
|
|
|
.field("f1", &"abc")
|
|
|
|
.field("f2", &String::from("bcd"))
|
|
|
|
.field("f3", &123i32)
|
|
|
|
.build();
|
|
|
|
|
2021-04-11 19:39:50 +00:00
|
|
|
let s2 = Structure::from_iter(s.name(), s.iter().filter(|(f, _)| *f == "f1"));
|
2020-04-20 09:11:06 +00:00
|
|
|
|
2021-04-11 19:39:50 +00:00
|
|
|
assert_eq!(s2.name(), "test");
|
2021-04-20 07:19:02 +00:00
|
|
|
assert_eq!(s2.get::<&str>("f1"), Ok("abc"));
|
2020-04-20 09:11:06 +00:00
|
|
|
assert!(s2.get::<&str>("f2").is_err());
|
|
|
|
assert!(s2.get::<&str>("f3").is_err());
|
|
|
|
}
|
2017-07-07 13:04:54 +00:00
|
|
|
}
|