Hello everyone.
Today I was poking around with raylib-rs, and one of its function accepted a string in a very peculiar way.
The function I'm talking about is:
fn gui_label(&mut self, bounds: impl Into<ffi::Rectangle>, text: impl IntoCStr) -> bool {
unsafe { ffi::GuiLabel(bounds.into(), text.as_cstr_ptr()) > 0 }
}
where I noticed the text is an impl IntoCStr
, a custom trait defined like this:
pub trait IntoCStr {
fn as_cstr_ptr(&self) -> *const std::os::raw::c_char;
}
impl IntoCStr for dyn AsRef<str> {
fn as_cstr_ptr(&self) -> *const std::os::raw::c_char {
std::ffi::CString::new(self.as_ref())
.unwrap()
.as_c_str()
.as_ptr()
}
}
impl IntoCStr for dyn AsRef<CStr> {
fn as_cstr_ptr(&self) -> *const std::os::raw::c_char {
self.as_ref().as_ptr()
}
}
impl IntoCStr for Option<&CStr> {
fn as_cstr_ptr(&self) -> *const std::os::raw::c_char {
self.map(CStr::as_ptr).unwrap_or(std::ptr::null())
}
}
What interested me was the first implementation, for dyn AsRef<str>
. While I can easily use the third implementation, this first one seems to me targeted to people wanting to "cast rapidly" a str to a CStr/Impl IntoCStr, but after some digging I found out that this implementation works only for type trait variables like let x: &dyn AsRef<str>
.
Still, I'm having a lot of difficulty to understand HOW can this implementation can be called and what use-case cover. I tried for 1 hour without founding a way to call that specific implementation.
Can someone help me understand better this impl?