Skip to content

Commit 1554d01

Browse files
committed
GStringPtr: remove impl AsRef, provide explicit to_gstr and to_str
The conversion requires calculating the length so it is expensive and should be explicit.
1 parent 01b6d66 commit 1554d01

File tree

2 files changed

+60
-76
lines changed

2 files changed

+60
-76
lines changed

glib/src/collections/strv.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ impl Clone for StrV {
394394
unsafe {
395395
let mut s = Self::with_capacity(self.len());
396396
for (i, item) in self.iter().enumerate() {
397-
*s.ptr.as_ptr().add(i) = GString::from(item.as_str()).into_glib_ptr();
397+
*s.ptr.as_ptr().add(i) = GString::from(item.to_str()).into_glib_ptr();
398398
}
399399
s.len = self.len();
400400
*s.ptr.as_ptr().add(s.len) = ptr::null_mut();
@@ -446,11 +446,23 @@ impl StrV {
446446
if len == 0 {
447447
StrV::default()
448448
} else {
449-
// Need to fully copy the array here.
450-
let slice = Self::from_glib_borrow_num(ptr, len);
451-
let mut s = Self::new();
452-
s.extend_from_slice(slice);
453-
s
449+
let new_ptr =
450+
ffi::g_malloc(mem::size_of::<*mut c_char>() * len + 1) as *mut *mut c_char;
451+
452+
// Need to clone every item because we don't own it here
453+
for i in 0..len {
454+
let p = ptr.add(i) as *mut *const c_char;
455+
let q = new_ptr.add(i) as *mut *const c_char;
456+
*q = ffi::g_strdup(*p);
457+
}
458+
459+
*new_ptr.add(len) = ptr::null_mut();
460+
461+
StrV {
462+
ptr: ptr::NonNull::new_unchecked(new_ptr),
463+
len,
464+
capacity: len + 1,
465+
}
454466
}
455467
}
456468

glib/src/gstring.rs

Lines changed: 42 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,22 @@ impl GlibPtrDefault for GStringPtr {
670670
type GlibType = *mut c_char;
671671
}
672672

673+
impl GStringPtr {
674+
// rustdoc-stripper-ignore-next
675+
/// Returns the corresponding [`&GStr`].
676+
#[inline]
677+
pub fn to_gstr(&self) -> &GStr {
678+
unsafe { GStr::from_ptr(self.0.as_ptr()) }
679+
}
680+
681+
// rustdoc-stripper-ignore-next
682+
/// Returns the corresponding [`&str`].
683+
#[inline]
684+
pub fn to_str(&self) -> &str {
685+
self.to_gstr().as_str()
686+
}
687+
}
688+
673689
impl Clone for GStringPtr {
674690
#[inline]
675691
fn clone(&self) -> GStringPtr {
@@ -688,37 +704,14 @@ impl Drop for GStringPtr {
688704

689705
impl fmt::Debug for GStringPtr {
690706
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
691-
f.write_str(self.as_str())
692-
}
693-
}
694-
695-
impl std::ops::Deref for GStringPtr {
696-
type Target = GStr;
697-
698-
#[inline]
699-
fn deref(&self) -> &Self::Target {
700-
self.as_ref()
701-
}
702-
}
703-
704-
impl AsRef<GStr> for GStringPtr {
705-
#[inline]
706-
fn as_ref(&self) -> &GStr {
707-
unsafe { GStr::from_ptr(self.0.as_ptr()) }
708-
}
709-
}
710-
711-
impl AsRef<str> for GStringPtr {
712-
#[inline]
713-
fn as_ref(&self) -> &str {
714-
self.as_str()
707+
f.write_str(self.to_str())
715708
}
716709
}
717710

718711
impl fmt::Display for GStringPtr {
719712
#[inline]
720713
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
721-
f.write_str(self.as_str())
714+
f.write_str(self.to_str())
722715
}
723716
}
724717

@@ -727,161 +720,161 @@ impl Eq for GStringPtr {}
727720
impl PartialEq for GStringPtr {
728721
#[inline]
729722
fn eq(&self, other: &GStringPtr) -> bool {
730-
self.as_str() == other.as_str()
723+
self.to_gstr() == other.to_gstr()
731724
}
732725
}
733726

734727
impl PartialEq<GStringPtr> for String {
735728
#[inline]
736729
fn eq(&self, other: &GStringPtr) -> bool {
737-
self.as_str() == other.as_str()
730+
self.as_str() == other.to_str()
738731
}
739732
}
740733

741734
impl PartialEq<GStringPtr> for GString {
742735
#[inline]
743736
fn eq(&self, other: &GStringPtr) -> bool {
744-
self.as_str() == other.as_str()
737+
self.as_str() == other.to_str()
745738
}
746739
}
747740

748741
impl PartialEq<str> for GStringPtr {
749742
#[inline]
750743
fn eq(&self, other: &str) -> bool {
751-
self.as_str() == other
744+
self.to_str() == other
752745
}
753746
}
754747

755748
impl PartialEq<&str> for GStringPtr {
756749
#[inline]
757750
fn eq(&self, other: &&str) -> bool {
758-
self.as_str() == *other
751+
self.to_str() == *other
759752
}
760753
}
761754

762755
impl PartialEq<GStr> for GStringPtr {
763756
#[inline]
764757
fn eq(&self, other: &GStr) -> bool {
765-
self.as_str() == other
758+
self.to_gstr() == other
766759
}
767760
}
768761

769762
impl PartialEq<&GStr> for GStringPtr {
770763
#[inline]
771764
fn eq(&self, other: &&GStr) -> bool {
772-
self.as_str() == *other
765+
self.to_gstr() == *other
773766
}
774767
}
775768

776769
impl PartialEq<GStringPtr> for &str {
777770
#[inline]
778771
fn eq(&self, other: &GStringPtr) -> bool {
779-
*self == other.as_str()
772+
*self == other.to_str()
780773
}
781774
}
782775

783776
impl PartialEq<GStringPtr> for &GStr {
784777
#[inline]
785778
fn eq(&self, other: &GStringPtr) -> bool {
786-
*self == other.as_str()
779+
self.as_str() == other.to_str()
787780
}
788781
}
789782

790783
impl PartialEq<String> for GStringPtr {
791784
#[inline]
792785
fn eq(&self, other: &String) -> bool {
793-
self.as_str() == other.as_str()
786+
self.to_str() == other.as_str()
794787
}
795788
}
796789

797790
impl PartialEq<GString> for GStringPtr {
798791
#[inline]
799792
fn eq(&self, other: &GString) -> bool {
800-
self.as_str() == other.as_str()
793+
self.to_str() == other.as_str()
801794
}
802795
}
803796

804797
impl PartialEq<GStringPtr> for str {
805798
#[inline]
806799
fn eq(&self, other: &GStringPtr) -> bool {
807-
self == other.as_str()
800+
self == other.to_str()
808801
}
809802
}
810803

811804
impl PartialEq<GStringPtr> for GStr {
812805
#[inline]
813806
fn eq(&self, other: &GStringPtr) -> bool {
814-
self == other.as_str()
807+
self == other.to_gstr()
815808
}
816809
}
817810

818811
impl PartialOrd<GStringPtr> for GStringPtr {
819812
#[inline]
820813
fn partial_cmp(&self, other: &GStringPtr) -> Option<std::cmp::Ordering> {
821-
Some(self.as_str().cmp(other.as_str()))
814+
Some(self.to_gstr().cmp(other.to_gstr()))
822815
}
823816
}
824817

825818
impl Ord for GStringPtr {
826819
#[inline]
827820
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
828-
self.as_str().cmp(other.as_str())
821+
self.to_gstr().cmp(other.to_gstr())
829822
}
830823
}
831824

832825
impl PartialOrd<GStringPtr> for String {
833826
#[inline]
834827
fn partial_cmp(&self, other: &GStringPtr) -> Option<std::cmp::Ordering> {
835-
Some(self.as_str().cmp(other.as_str()))
828+
Some(self.as_str().cmp(other.to_str()))
836829
}
837830
}
838831

839832
impl PartialOrd<GStringPtr> for GString {
840833
#[inline]
841834
fn partial_cmp(&self, other: &GStringPtr) -> Option<std::cmp::Ordering> {
842-
Some(self.as_str().cmp(other.as_str()))
835+
Some(self.as_str().cmp(other.to_str()))
843836
}
844837
}
845838

846839
impl PartialOrd<String> for GStringPtr {
847840
#[inline]
848841
fn partial_cmp(&self, other: &String) -> Option<std::cmp::Ordering> {
849-
Some(self.as_str().cmp(other.as_str()))
842+
Some(self.to_str().cmp(other.as_str()))
850843
}
851844
}
852845

853846
impl PartialOrd<GString> for GStringPtr {
854847
#[inline]
855848
fn partial_cmp(&self, other: &GString) -> Option<std::cmp::Ordering> {
856-
Some(self.as_str().cmp(other.as_str()))
849+
Some(self.to_str().cmp(other.as_str()))
857850
}
858851
}
859852

860853
impl PartialOrd<GStringPtr> for str {
861854
#[inline]
862855
fn partial_cmp(&self, other: &GStringPtr) -> Option<std::cmp::Ordering> {
863-
Some(self.cmp(other.as_str()))
856+
Some(self.cmp(other.to_str()))
864857
}
865858
}
866859

867860
impl PartialOrd<GStringPtr> for GStr {
868861
#[inline]
869862
fn partial_cmp(&self, other: &GStringPtr) -> Option<std::cmp::Ordering> {
870-
Some(self.as_str().cmp(other.as_str()))
863+
Some(self.cmp(other.to_gstr()))
871864
}
872865
}
873866

874867
impl PartialOrd<str> for GStringPtr {
875868
#[inline]
876869
fn partial_cmp(&self, other: &str) -> Option<std::cmp::Ordering> {
877-
Some(self.as_str().cmp(other))
870+
Some(self.to_str().cmp(other))
878871
}
879872
}
880873

881874
impl PartialOrd<GStr> for GStringPtr {
882875
#[inline]
883876
fn partial_cmp(&self, other: &GStr) -> Option<std::cmp::Ordering> {
884-
Some(self.as_str().cmp(other))
877+
Some(self.to_gstr().cmp(other))
885878
}
886879
}
887880

@@ -892,31 +885,10 @@ impl AsRef<GStringPtr> for GStringPtr {
892885
}
893886
}
894887

895-
impl AsRef<std::ffi::OsStr> for GStringPtr {
896-
#[inline]
897-
fn as_ref(&self) -> &std::ffi::OsStr {
898-
self.as_str().as_ref()
899-
}
900-
}
901-
902-
impl AsRef<std::path::Path> for GStringPtr {
903-
#[inline]
904-
fn as_ref(&self) -> &std::path::Path {
905-
self.as_str().as_ref()
906-
}
907-
}
908-
909-
impl AsRef<[u8]> for GStringPtr {
910-
#[inline]
911-
fn as_ref(&self) -> &[u8] {
912-
self.as_bytes()
913-
}
914-
}
915-
916888
impl std::hash::Hash for GStringPtr {
917889
#[inline]
918890
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
919-
self.as_str().hash(state);
891+
self.to_str().hash(state);
920892
}
921893
}
922894

0 commit comments

Comments
 (0)