From 899b40b388bc8af6b93d54b6caf60100c10cde0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 5 Jan 2023 18:29:45 +0200 Subject: [PATCH] glib: Use `IntoGStr` trait in a couple of places This reduces allocations as all those strings are usually small and would be stack-allocated now for adding the NUL-terminator. --- glib/src/object.rs | 32 +++++++++++++++++++------------- glib/src/quark.rs | 20 ++++++++------------ glib/src/subclass/signal.rs | 23 ++++++++++++++--------- glib/src/types.rs | 9 ++++++--- 4 files changed, 47 insertions(+), 37 deletions(-) diff --git a/glib/src/object.rs b/glib/src/object.rs index bedfca358870..ed6f7990e9e8 100644 --- a/glib/src/object.rs +++ b/glib/src/object.rs @@ -13,7 +13,7 @@ use crate::{ thread_guard::thread_id, translate::*, value::FromValue, - Closure, PtrSlice, RustClosure, SignalHandlerId, Type, Value, + Closure, IntoGStr, PtrSlice, RustClosure, SignalHandlerId, Type, Value, }; // rustdoc-stripper-ignore-next @@ -2482,10 +2482,12 @@ impl ObjectExt for T { fn stop_signal_emission_by_name(&self, signal_name: &str) { unsafe { - gobject_ffi::g_signal_stop_emission_by_name( - self.as_object_ref().to_glib_none().0, - signal_name.to_glib_none().0, - ); + signal_name.run_with_gstr(|signal_name| { + gobject_ffi::g_signal_stop_emission_by_name( + self.as_object_ref().to_glib_none().0, + signal_name.as_ptr(), + ) + }); } } @@ -3012,10 +3014,12 @@ impl ObjectExt for T { #[inline] fn notify(&self, property_name: &str) { unsafe { - gobject_ffi::g_object_notify( - self.as_object_ref().to_glib_none().0, - property_name.to_glib_none().0, - ); + property_name.run_with_gstr(|property_name| { + gobject_ffi::g_object_notify( + self.as_object_ref().to_glib_none().0, + property_name.as_ptr(), + ) + }); } } @@ -3257,10 +3261,12 @@ impl ObjectClass { unsafe { let klass = self as *const _ as *const gobject_ffi::GObjectClass; - from_glib_none(gobject_ffi::g_object_class_find_property( - klass as *mut _, - property_name.to_glib_none().0, - )) + property_name.run_with_gstr(|property_name| { + from_glib_none(gobject_ffi::g_object_class_find_property( + klass as *mut _, + property_name.as_ptr(), + )) + }) } } diff --git a/glib/src/quark.rs b/glib/src/quark.rs index e80e026003b3..37dbae983730 100644 --- a/glib/src/quark.rs +++ b/glib/src/quark.rs @@ -1,8 +1,8 @@ // Take a look at the license at the top of the repository in the LICENSE file. -use std::{ffi::CStr, fmt, num::NonZeroU32}; +use std::{fmt, num::NonZeroU32}; -use crate::translate::*; +use crate::{translate::*, GStr, IntoGStr}; #[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] #[repr(transparent)] @@ -12,18 +12,14 @@ pub struct Quark(NonZeroU32); impl Quark { #[doc(alias = "g_quark_from_string")] #[allow(clippy::should_implement_trait)] - pub fn from_str(s: &str) -> Quark { - unsafe { from_glib(ffi::g_quark_from_string(s.to_glib_none().0)) } + pub fn from_str(s: impl IntoGStr) -> Quark { + unsafe { s.run_with_gstr(|s| from_glib(ffi::g_quark_from_string(s.as_ptr()))) } } #[allow(clippy::trivially_copy_pass_by_ref)] #[doc(alias = "g_quark_to_string")] - pub fn as_str<'a>(&self) -> &'a str { - unsafe { - CStr::from_ptr(ffi::g_quark_to_string(self.into_glib())) - .to_str() - .unwrap() - } + pub fn as_str<'a>(&self) -> &'a GStr { + unsafe { GStr::from_ptr(ffi::g_quark_to_string(self.into_glib())) } } #[doc(alias = "g_quark_try_string")] @@ -38,8 +34,8 @@ impl fmt::Debug for Quark { } } -impl<'a> From<&'a str> for Quark { - fn from(s: &'a str) -> Self { +impl From for Quark { + fn from(s: T) -> Self { Self::from_str(s) } } diff --git a/glib/src/subclass/signal.rs b/glib/src/subclass/signal.rs index 1d5d461076c1..2ea40cbb8f13 100644 --- a/glib/src/subclass/signal.rs +++ b/glib/src/subclass/signal.rs @@ -3,7 +3,8 @@ use std::{fmt, num::NonZeroU32, ptr, sync::Mutex}; use crate::{ - prelude::*, translate::*, utils::is_canonical_pspec_name, Closure, SignalFlags, Type, Value, + prelude::*, translate::*, utils::is_canonical_pspec_name, Closure, IntoGStr, SignalFlags, Type, + Value, }; // rustdoc-stripper-ignore-next @@ -192,13 +193,15 @@ impl SignalId { let mut signal_id = std::mem::MaybeUninit::uninit(); let mut detail_quark = std::mem::MaybeUninit::uninit(); unsafe { - let found: bool = from_glib(gobject_ffi::g_signal_parse_name( - name.to_glib_none().0, - type_.into_glib(), - signal_id.as_mut_ptr(), - detail_quark.as_mut_ptr(), - force_detail.into_glib(), - )); + let found: bool = name.run_with_gstr(|name| { + from_glib(gobject_ffi::g_signal_parse_name( + name.as_ptr(), + type_.into_glib(), + signal_id.as_mut_ptr(), + detail_quark.as_mut_ptr(), + force_detail.into_glib(), + )) + }); if found { Some(( @@ -217,7 +220,9 @@ impl SignalId { #[inline] pub fn lookup(name: &str, type_: Type) -> Option { unsafe { - let signal_id = gobject_ffi::g_signal_lookup(name.to_glib_none().0, type_.into_glib()); + let signal_id = name.run_with_gstr(|name| { + gobject_ffi::g_signal_lookup(name.as_ptr(), type_.into_glib()) + }); if signal_id == 0 { None } else { diff --git a/glib/src/types.rs b/glib/src/types.rs index 16696314fb2f..86e33eabd66f 100644 --- a/glib/src/types.rs +++ b/glib/src/types.rs @@ -5,7 +5,7 @@ use std::{fmt, marker::PhantomData, mem, ptr}; -use crate::{translate::*, Slice}; +use crate::{translate::*, IntoGStr, Slice}; // rustdoc-stripper-ignore-next /// A GLib or GLib-based library type @@ -206,9 +206,12 @@ impl Type { } #[doc(alias = "g_type_from_name")] - pub fn from_name(name: &str) -> Option { + pub fn from_name(name: impl IntoGStr) -> Option { unsafe { - let type_: Self = from_glib(gobject_ffi::g_type_from_name(name.to_glib_none().0)); + let type_ = name.run_with_gstr(|name| { + Self::from_glib(gobject_ffi::g_type_from_name(name.as_ptr())) + }); + Some(type_).filter(|t| t.is_valid()) } }