diff --git a/changelog.md b/changelog.md index e8a9ee31..86c701bf 100644 --- a/changelog.md +++ b/changelog.md @@ -6,6 +6,8 @@ when upgrading from a version of rust-sdl2 to another. * **BREAKING CHANGE** Update `sdl2-sys/sdl_bindings.rs` to use enums instead of consts. If you were using `sdl2-sys`'s enum variants directly in your project, you may be affected. If you only used sdl2 calls, there should not be any problems. +[PR #1138](https://github.com/Rust-SDL2/rust-sdl2/pull/1138) Added binding for `SDL_OpenURL` + ### v0.34.5 [PR #1100](https://github.com/Rust-SDL2/rust-sdl2/pull/1100) Added binding for `SDL_GetDisplayUsableBounds` diff --git a/src/sdl2/lib.rs b/src/sdl2/lib.rs index 15f95058..ba6f5a2f 100644 --- a/src/sdl2/lib.rs +++ b/src/sdl2/lib.rs @@ -86,6 +86,7 @@ mod sdl; pub mod surface; pub mod timer; pub mod touch; +pub mod url; pub mod version; pub mod video; diff --git a/src/sdl2/url.rs b/src/sdl2/url.rs new file mode 100644 index 00000000..4e6cb332 --- /dev/null +++ b/src/sdl2/url.rs @@ -0,0 +1,73 @@ +//! Opening URLs in default system handlers + +use std::error; +use std::ffi::{CString, NulError}; +use std::fmt; + +use crate::get_error; + +use crate::sys; + +#[derive(Debug, Clone)] +pub enum OpenUrlError { + InvalidUrl(NulError), + SdlError(String), +} + +impl fmt::Display for OpenUrlError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use self::OpenUrlError::*; + + match *self { + InvalidUrl(ref e) => write!(f, "Invalid URL: {}", e), + SdlError(ref e) => write!(f, "SDL error: {}", e), + } + } +} + +impl error::Error for OpenUrlError { + fn description(&self) -> &str { + use self::OpenUrlError::*; + + match *self { + InvalidUrl(_) => "invalid URL", + SdlError(ref e) => e, + } + } +} + +/// Opens a URL/URI in the default system-provided application. +/// +/// This will most likely open a web browser for http:// and https:// links, +/// the default handler application for file:// links, but this varies +/// between platforms and is not supported on all of them. +/// It might also cause your window to lose focus, or pause your process on mobile. +/// +/// There is no way to tell if the system successfully opened the provided URL, +/// an `Ok` result only means that something was launched to try to handle it. +/// +/// # Examples +/// +/// ```no_run +/// use sdl2::url::open_url; +/// +/// open_url("https://github.com/Rust-SDL2/rust-sdl2") +/// .expect("Opening URLs not supported on this platform"); +/// ``` +#[doc(alias = "SDL_OpenURL")] +pub fn open_url(url: &str) -> Result<(), OpenUrlError> { + use self::OpenUrlError::*; + let result = unsafe { + let url = match CString::new(url) { + Ok(s) => s, + Err(err) => return Err(InvalidUrl(err)), + }; + sys::SDL_OpenURL(url.as_ptr()) + } == 0; + + if result { + Ok(()) + } else { + Err(SdlError(get_error())) + } +}