libloading/
as_symbol_name.rs1use crate::Error;
2use alloc::ffi::CString;
3use alloc::string::String;
4use core::ffi::CStr;
5
6pub(crate) trait Sealed {
7 fn symbol_name<R>(
8 self,
9 function: impl FnOnce(*const core::ffi::c_char) -> Result<R, crate::Error>,
10 ) -> Result<R, crate::Error>;
11}
12
13#[expect(private_bounds)]
18pub trait AsSymbolName: Sealed {}
19
20impl AsSymbolName for &str {}
21impl Sealed for &str {
22 fn symbol_name<R>(
23 self,
24 function: impl FnOnce(*const core::ffi::c_char) -> Result<R, Error>,
25 ) -> Result<R, Error> {
26 self.as_bytes().symbol_name(function)
27 }
28}
29
30impl AsSymbolName for &String {}
31impl Sealed for &String {
32 fn symbol_name<R>(
33 self,
34 function: impl FnOnce(*const core::ffi::c_char) -> Result<R, Error>,
35 ) -> Result<R, Error> {
36 self.as_str().symbol_name(function)
37 }
38}
39
40impl AsSymbolName for String {}
41impl Sealed for String {
42 fn symbol_name<R>(
43 mut self,
44 function: impl FnOnce(*const core::ffi::c_char) -> Result<R, Error>,
45 ) -> Result<R, Error> {
46 if crate::util::check_null_bytes(self.as_bytes())? {
47 function(self.as_ptr().cast())
48 } else {
49 self.push('\0');
50 function(self.as_ptr().cast())
51 }
52 }
53}
54
55impl AsSymbolName for &CStr {}
56impl Sealed for &CStr {
57 fn symbol_name<R>(
58 self,
59 function: impl FnOnce(*const core::ffi::c_char) -> Result<R, Error>,
60 ) -> Result<R, Error> {
61 function(self.as_ptr())
62 }
63}
64
65impl AsSymbolName for &CString {}
66impl Sealed for &CString {
67 fn symbol_name<R>(
68 self,
69 function: impl FnOnce(*const core::ffi::c_char) -> Result<R, Error>,
70 ) -> Result<R, Error> {
71 function(self.as_ptr())
72 }
73}
74
75impl AsSymbolName for CString {}
76impl Sealed for CString {
77 fn symbol_name<R>(
78 self,
79 function: impl FnOnce(*const core::ffi::c_char) -> Result<R, Error>,
80 ) -> Result<R, Error> {
81 function(self.as_ptr())
82 }
83}
84
85impl AsSymbolName for &[u8] {}
86impl Sealed for &[u8] {
87 fn symbol_name<R>(
88 self,
89 function: impl FnOnce(*const core::ffi::c_char) -> Result<R, Error>,
90 ) -> Result<R, Error> {
91 if crate::util::check_null_bytes(self)? {
92 function(self.as_ptr().cast())
93 } else {
94 let copy = crate::util::copy_and_push(self, 0);
95 function(copy.as_ptr().cast())
96 }
97 }
98}
99
100impl<const N: usize> AsSymbolName for [u8; N] {}
101impl<const N: usize> Sealed for [u8; N] {
102 fn symbol_name<R>(
103 self,
104 function: impl FnOnce(*const core::ffi::c_char) -> Result<R, Error>,
105 ) -> Result<R, Error> {
106 self.as_slice().symbol_name(function)
107 }
108}
109
110impl<const N: usize> AsSymbolName for &[u8; N] {}
111impl<const N: usize> Sealed for &[u8; N] {
112 fn symbol_name<R>(
113 self,
114 function: impl FnOnce(*const core::ffi::c_char) -> Result<R, Error>,
115 ) -> Result<R, Error> {
116 self.as_slice().symbol_name(function)
117 }
118}