Skip to content

Commit fbc1814

Browse files
jf2048sdroege
authored andcommitted
glib: add ToGlibPtr implementations for more string types
1 parent 5368f27 commit fbc1814

File tree

1 file changed

+116
-1
lines changed

1 file changed

+116
-1
lines changed

glib/src/translate.rs

Lines changed: 116 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,9 @@ use std::{
139139
collections::HashMap,
140140
error::Error,
141141
ffi::{CStr, CString, OsStr, OsString},
142-
fmt, mem,
142+
fmt,
143+
marker::PhantomData,
144+
mem,
143145
path::{Path, PathBuf},
144146
ptr,
145147
};
@@ -502,6 +504,43 @@ impl<'a, P: Ptr, T: ?Sized + ToGlibPtr<'a, P>> ToGlibPtr<'a, P> for &'a T {
502504
}
503505
}
504506

507+
#[doc(hidden)]
508+
#[derive(Debug)]
509+
pub enum CowStash<B, O> {
510+
Borrowed(B),
511+
Owned(O),
512+
}
513+
514+
impl<'a, P: Ptr, T> ToGlibPtr<'a, P> for Cow<'a, T>
515+
where
516+
T: ToOwned + ?Sized + ToGlibPtr<'a, P>,
517+
T::Owned: ToGlibPtr<'a, P>,
518+
{
519+
type Storage = CowStash<T::Storage, <T::Owned as ToGlibPtr<'a, P>>::Storage>;
520+
521+
#[inline]
522+
fn to_glib_none(&'a self) -> Stash<'a, P, Self> {
523+
match self {
524+
Cow::Borrowed(v) => {
525+
let s = v.to_glib_none();
526+
Stash(s.0, CowStash::Borrowed(s.1))
527+
}
528+
Cow::Owned(v) => {
529+
let s = v.to_glib_none();
530+
Stash(s.0, CowStash::Owned(s.1))
531+
}
532+
}
533+
}
534+
535+
#[inline]
536+
fn to_glib_full(&self) -> P {
537+
match self {
538+
Cow::Borrowed(v) => v.to_glib_full(),
539+
Cow::Owned(v) => v.to_glib_full(),
540+
}
541+
}
542+
}
543+
505544
impl<'a> ToGlibPtr<'a, *const c_char> for str {
506545
type Storage = Cow<'static, [u8]>;
507546

@@ -581,6 +620,82 @@ impl<'a> ToGlibPtr<'a, *mut c_char> for String {
581620
}
582621
}
583622

623+
impl<'a> ToGlibPtr<'a, *const c_char> for CStr {
624+
type Storage = PhantomData<&'a Self>;
625+
626+
#[inline]
627+
fn to_glib_none(&'a self) -> Stash<'a, *const c_char, Self> {
628+
Stash(self.as_ptr(), PhantomData)
629+
}
630+
631+
#[inline]
632+
fn to_glib_full(&self) -> *const c_char {
633+
unsafe {
634+
ffi::g_strndup(
635+
self.as_ptr() as *const c_char,
636+
self.to_bytes().len() as size_t,
637+
) as *const c_char
638+
}
639+
}
640+
}
641+
642+
impl<'a> ToGlibPtr<'a, *mut c_char> for CStr {
643+
type Storage = PhantomData<&'a Self>;
644+
645+
#[inline]
646+
fn to_glib_none(&'a self) -> Stash<'a, *mut c_char, Self> {
647+
Stash(self.as_ptr() as *mut c_char, PhantomData)
648+
}
649+
650+
#[inline]
651+
fn to_glib_full(&self) -> *mut c_char {
652+
unsafe {
653+
ffi::g_strndup(
654+
self.as_ptr() as *const c_char,
655+
self.to_bytes().len() as size_t,
656+
) as *mut c_char
657+
}
658+
}
659+
}
660+
661+
impl<'a> ToGlibPtr<'a, *const c_char> for CString {
662+
type Storage = PhantomData<&'a Self>;
663+
664+
#[inline]
665+
fn to_glib_none(&'a self) -> Stash<'a, *const c_char, Self> {
666+
Stash(self.as_ptr(), PhantomData)
667+
}
668+
669+
#[inline]
670+
fn to_glib_full(&self) -> *const c_char {
671+
unsafe {
672+
ffi::g_strndup(
673+
self.as_ptr() as *const c_char,
674+
self.as_bytes().len() as size_t,
675+
) as *const c_char
676+
}
677+
}
678+
}
679+
680+
impl<'a> ToGlibPtr<'a, *mut c_char> for CString {
681+
type Storage = PhantomData<&'a Self>;
682+
683+
#[inline]
684+
fn to_glib_none(&'a self) -> Stash<'a, *mut c_char, Self> {
685+
Stash(self.as_ptr() as *mut c_char, PhantomData)
686+
}
687+
688+
#[inline]
689+
fn to_glib_full(&self) -> *mut c_char {
690+
unsafe {
691+
ffi::g_strndup(
692+
self.as_ptr() as *const c_char,
693+
self.as_bytes().len() as size_t,
694+
) as *mut c_char
695+
}
696+
}
697+
}
698+
584699
// rustdoc-stripper-ignore-next
585700
/// Translate to a pointer.
586701
pub trait IntoGlibPtr<P: Ptr> {

0 commit comments

Comments
 (0)