Skip to content

Commit

Permalink
glib: convert some functions to use IntoGStr
Browse files Browse the repository at this point in the history
  • Loading branch information
jf2048 committed Nov 26, 2022
1 parent 30b853c commit a938c6b
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 97 deletions.
125 changes: 69 additions & 56 deletions glib/src/convert.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Take a look at the license at the top of the repository in the LICENSE file.

use crate::{translate::*, ConvertError, Error, GStr, GString, Slice};
use crate::{translate::*, ConvertError, Error, GString, IntoGStr, IntoOptionalGStr, Slice};
use std::{io, os::raw::c_char, path::PathBuf, ptr};

// rustdoc-stripper-ignore-next
Expand Down Expand Up @@ -35,24 +35,26 @@ impl CvtError {
#[doc(alias = "g_convert")]
pub fn convert(
str_: &[u8],
to_codeset: &str,
from_codeset: &str,
to_codeset: impl IntoGStr,
from_codeset: impl IntoGStr,
) -> Result<(Slice<u8>, usize), CvtError> {
assert!(str_.len() <= isize::MAX as usize);
let mut bytes_read = 0;
let mut bytes_written = 0;
let mut error = ptr::null_mut();
let result = unsafe {
ffi::g_convert(
str_.as_ptr(),
str_.len() as isize,
to_codeset.to_glib_none().0,
from_codeset.to_glib_none().0,
&mut bytes_read,
&mut bytes_written,
&mut error,
)
};
let result = to_codeset.run_with_gstr(|to_codeset| {
from_codeset.run_with_gstr(|from_codeset| unsafe {
ffi::g_convert(
str_.as_ptr(),
str_.len() as isize,
to_codeset.to_glib_none().0,
from_codeset.to_glib_none().0,
&mut bytes_read,
&mut bytes_written,
&mut error,
)
})
});
if result.is_null() {
Err(CvtError::new(unsafe { from_glib_full(error) }, bytes_read))
} else {
Expand All @@ -64,26 +66,30 @@ pub fn convert(
#[doc(alias = "g_convert_with_fallback")]
pub fn convert_with_fallback(
str_: &[u8],
to_codeset: &str,
from_codeset: &str,
fallback: Option<&str>,
to_codeset: impl IntoGStr,
from_codeset: impl IntoGStr,
fallback: Option<impl IntoGStr>,
) -> Result<(Slice<u8>, usize), CvtError> {
assert!(str_.len() <= isize::MAX as usize);
let mut bytes_read = 0;
let mut bytes_written = 0;
let mut error = ptr::null_mut();
let result = unsafe {
ffi::g_convert_with_fallback(
str_.as_ptr(),
str_.len() as isize,
to_codeset.to_glib_none().0,
from_codeset.to_glib_none().0,
fallback.to_glib_none().0,
&mut bytes_read,
&mut bytes_written,
&mut error,
)
};
let result = to_codeset.run_with_gstr(|to_codeset| {
from_codeset.run_with_gstr(|from_codeset| {
fallback.run_with_gstr(|fallback| unsafe {
ffi::g_convert_with_fallback(
str_.as_ptr(),
str_.len() as isize,
to_codeset.to_glib_none().0,
from_codeset.to_glib_none().0,
fallback.to_glib_none().0,
&mut bytes_read,
&mut bytes_written,
&mut error,
)
})
})
});
if result.is_null() {
Err(CvtError::new(unsafe { from_glib_full(error) }, bytes_read))
} else {
Expand Down Expand Up @@ -116,10 +122,12 @@ unsafe impl Send for IConv {}
impl IConv {
#[doc(alias = "g_iconv_open")]
#[allow(clippy::unnecessary_lazy_evaluations)]
pub fn new(to_codeset: &str, from_codeset: &str) -> Option<Self> {
let iconv = unsafe {
ffi::g_iconv_open(to_codeset.to_glib_none().0, from_codeset.to_glib_none().0)
};
pub fn new(to_codeset: impl IntoGStr, from_codeset: impl IntoGStr) -> Option<Self> {
let iconv = to_codeset.run_with_gstr(|to_codeset| {
from_codeset.run_with_gstr(|from_codeset| unsafe {
ffi::g_iconv_open(to_codeset.to_glib_none().0, from_codeset.to_glib_none().0)
})
});
(iconv as isize != -1).then(|| Self(iconv))
}
#[doc(alias = "g_convert_with_iconv")]
Expand Down Expand Up @@ -208,20 +216,23 @@ pub fn filename_charsets() -> (bool, Vec<GString>) {
}

#[doc(alias = "g_filename_from_utf8")]
pub fn filename_from_utf8(utf8string: &str) -> Result<(PathBuf, usize), CvtError> {
let len = utf8string.len() as isize;
pub fn filename_from_utf8(utf8string: impl IntoGStr) -> Result<(PathBuf, usize), CvtError> {
let mut bytes_read = 0;
let mut bytes_written = std::mem::MaybeUninit::uninit();
let mut error = ptr::null_mut();
let ret = unsafe {
ffi::g_filename_from_utf8(
utf8string.to_glib_none().0,
len,
&mut bytes_read,
bytes_written.as_mut_ptr(),
&mut error,
)
};
let ret = utf8string.run_with_gstr(|utf8string| {
assert!(utf8string.len() <= isize::MAX as usize);
let len = utf8string.len() as isize;
unsafe {
ffi::g_filename_from_utf8(
utf8string.to_glib_none().0,
len,
&mut bytes_read,
bytes_written.as_mut_ptr(),
&mut error,
)
}
});
if error.is_null() {
Ok(unsafe {
(
Expand Down Expand Up @@ -264,20 +275,22 @@ pub fn filename_to_utf8(
}

#[doc(alias = "g_locale_from_utf8")]
pub fn locale_from_utf8(utf8string: &GStr) -> Result<(Slice<u8>, usize), CvtError> {
assert!(utf8string.len() <= isize::MAX as usize);
pub fn locale_from_utf8(utf8string: impl IntoGStr) -> Result<(Slice<u8>, usize), CvtError> {
let mut bytes_read = 0;
let mut bytes_written = std::mem::MaybeUninit::uninit();
let mut error = ptr::null_mut();
let ret = unsafe {
ffi::g_locale_from_utf8(
utf8string.as_ptr(),
utf8string.len() as isize,
&mut bytes_read,
bytes_written.as_mut_ptr(),
&mut error,
)
};
let ret = utf8string.run_with_gstr(|utf8string| {
assert!(utf8string.len() <= isize::MAX as usize);
unsafe {
ffi::g_locale_from_utf8(
utf8string.as_ptr(),
utf8string.len() as isize,
&mut bytes_read,
bytes_written.as_mut_ptr(),
&mut error,
)
}
});
if error.is_null() {
Ok(unsafe {
(
Expand Down Expand Up @@ -324,7 +337,7 @@ mod tests {
assert!(super::convert(b"Hello", "utf-8", "ascii").is_ok());
assert!(super::convert(b"He\xaallo", "utf-8", "ascii").is_err());
assert_eq!(
super::convert_with_fallback(b"H\xc3\xa9llo", "ascii", "utf-8", None)
super::convert_with_fallback(b"H\xc3\xa9llo", "ascii", "utf-8", crate::NONE_STR)
.unwrap()
.0
.as_slice(),
Expand Down
4 changes: 2 additions & 2 deletions glib/src/functions.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Take a look at the license at the top of the repository in the LICENSE file.

use crate::GStr;
#[cfg(not(windows))]
use std::boxed::Box as Box_;
#[cfg(not(windows))]
Expand All @@ -15,7 +16,6 @@ use std::os::unix::io::{FromRawFd, IntoRawFd, RawFd};
use crate::translate::*;
#[cfg(not(windows))]
use crate::Error;
use crate::GString;
#[cfg(not(windows))]
use crate::Pid;
#[cfg(not(windows))]
Expand Down Expand Up @@ -216,7 +216,7 @@ pub fn spawn_async_with_pipes<
/// charset if available.
#[doc(alias = "g_get_charset")]
#[doc(alias = "get_charset")]
pub fn charset() -> (bool, Option<GString>) {
pub fn charset() -> (bool, Option<&'static GStr>) {
unsafe {
let mut out_charset = ptr::null();
let is_utf8 = from_glib(ffi::g_get_charset(&mut out_charset));
Expand Down
95 changes: 56 additions & 39 deletions glib/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Take a look at the license at the top of the repository in the LICENSE file.

use crate::translate::*;
use crate::{translate::*, GString, IntoGStr, IntoOptionalGStr};
use std::ffi::{OsStr, OsString};
use std::mem;
use std::ptr;
Expand All @@ -10,27 +10,31 @@ use std::ptr;
///
/// [`get_prgname()`]: fn.get_prgname.html
#[doc(alias = "get_program_name")]
pub fn program_name() -> Option<String> {
#[inline]
pub fn program_name() -> Option<GString> {
prgname()
}

#[doc(alias = "g_get_prgname")]
#[doc(alias = "get_prgname")]
pub fn prgname() -> Option<String> {
#[inline]
pub fn prgname() -> Option<GString> {
unsafe { from_glib_none(ffi::g_get_prgname()) }
}

// rustdoc-stripper-ignore-next
/// Same as [`set_prgname()`].
///
/// [`set_prgname()`]: fn.set_prgname.html
pub fn set_program_name(name: Option<&str>) {
#[inline]
pub fn set_program_name(name: Option<impl IntoGStr>) {
set_prgname(name)
}

#[doc(alias = "g_set_prgname")]
pub fn set_prgname(name: Option<&str>) {
unsafe { ffi::g_set_prgname(name.to_glib_none().0) }
#[inline]
pub fn set_prgname(name: Option<impl IntoGStr>) {
name.run_with_gstr(|name| unsafe { ffi::g_set_prgname(name.to_glib_none().0) })
}

#[doc(alias = "g_environ_getenv")]
Expand Down Expand Up @@ -128,50 +132,60 @@ pub fn is_canonical_pspec_name(name: &str) -> bool {

#[doc(alias = "g_uri_escape_string")]
pub fn uri_escape_string(
unescaped: &str,
reserved_chars_allowed: Option<&str>,
unescaped: impl IntoGStr,
reserved_chars_allowed: Option<impl IntoGStr>,
allow_utf8: bool,
) -> crate::GString {
unsafe {
from_glib_full(ffi::g_uri_escape_string(
unescaped.to_glib_none().0,
reserved_chars_allowed.to_glib_none().0,
allow_utf8.into_glib(),
))
}
unescaped.run_with_gstr(|unescaped| {
reserved_chars_allowed.run_with_gstr(|reserved_chars_allowed| unsafe {
from_glib_full(ffi::g_uri_escape_string(
unescaped.to_glib_none().0,
reserved_chars_allowed.to_glib_none().0,
allow_utf8.into_glib(),
))
})
})
}

#[doc(alias = "g_uri_unescape_string")]
pub fn uri_unescape_string(
escaped_string: &str,
illegal_characters: Option<&str>,
escaped_string: impl IntoGStr,
illegal_characters: Option<impl IntoGStr>,
) -> Option<crate::GString> {
unsafe {
from_glib_full(ffi::g_uri_unescape_string(
escaped_string.to_glib_none().0,
illegal_characters.to_glib_none().0,
))
}
escaped_string.run_with_gstr(|escaped_string| {
illegal_characters.run_with_gstr(|illegal_characters| unsafe {
from_glib_full(ffi::g_uri_unescape_string(
escaped_string.to_glib_none().0,
illegal_characters.to_glib_none().0,
))
})
})
}

#[doc(alias = "g_uri_parse_scheme")]
pub fn uri_parse_scheme(uri: &str) -> Option<crate::GString> {
unsafe { from_glib_full(ffi::g_uri_parse_scheme(uri.to_glib_none().0)) }
pub fn uri_parse_scheme(uri: impl IntoGStr) -> Option<crate::GString> {
uri.run_with_gstr(|uri| unsafe {
from_glib_full(ffi::g_uri_parse_scheme(uri.to_glib_none().0))
})
}

#[doc(alias = "g_uri_unescape_segment")]
pub fn uri_unescape_segment(
escaped_string: Option<&str>,
escaped_string_end: Option<&str>,
illegal_characters: Option<&str>,
escaped_string: Option<impl IntoGStr>,
escaped_string_end: Option<impl IntoGStr>,
illegal_characters: Option<impl IntoGStr>,
) -> Option<crate::GString> {
unsafe {
from_glib_full(ffi::g_uri_unescape_segment(
escaped_string.to_glib_none().0,
escaped_string_end.to_glib_none().0,
illegal_characters.to_glib_none().0,
))
}
escaped_string.run_with_gstr(|escaped_string| {
escaped_string_end.run_with_gstr(|escaped_string_end| {
illegal_characters.run_with_gstr(|illegal_characters| unsafe {
from_glib_full(ffi::g_uri_unescape_segment(
escaped_string.to_glib_none().0,
escaped_string_end.to_glib_none().0,
illegal_characters.to_glib_none().0,
))
})
})
})
}

#[cfg(test)]
Expand Down Expand Up @@ -244,16 +258,19 @@ mod tests {
);
assert_eq!(crate::uri_parse_scheme("foo"), None);

let escaped = crate::uri_escape_string("&foo", None, true);
let escaped = crate::uri_escape_string("&foo", crate::NONE_STR, true);
assert_eq!(escaped, GString::from("%26foo"));

let unescaped = crate::uri_unescape_string(escaped.as_str(), None);
let unescaped = crate::uri_unescape_string(escaped.as_str(), crate::GStr::NONE);
assert_eq!(unescaped, Some(GString::from("&foo")));

assert_eq!(
crate::uri_unescape_segment(Some("/foo"), None, None),
crate::uri_unescape_segment(Some("/foo"), crate::NONE_STR, crate::NONE_STR),
Some(GString::from("/foo"))
);
assert_eq!(crate::uri_unescape_segment(Some("/foo%"), None, None), None);
assert_eq!(
crate::uri_unescape_segment(Some("/foo%"), crate::NONE_STR, crate::NONE_STR),
None
);
}
}

0 comments on commit a938c6b

Please sign in to comment.