robius_open/
lib.rs

1//! A crate for opening URIs, e.g., URLs, `tel:`, `mailto:`, `file://`, etc.
2//!
3//! ```
4//! # use robius_open::Uri;
5//! Uri::new("tel:+61 123 456 789")
6//!     .open()
7//!     .expect("failed to open telephone URI");
8//! ```
9//!
10//! Supports:
11//! - macOS (`NSWorkspace`)
12//! - Android (`android/content/Intent`)
13//! - Linux (`xdg-open`)
14//! - Windows (`start`)
15//! - iOS (`UIApplication`)
16//!
17//! # Android
18//! To use the library on Android, you must add the following to the app
19//! manifest:
20//! ```xml
21//! <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"
22//!     tools:ignore="QueryAllPackagesPermission" />
23//!
24//! <queries>
25//!     <intent>
26//!         <action android:name="android.intent.action.MAIN" />
27//!     </intent>
28//! </queries>
29//! ```
30//! or alternatively, disable the `android-result` feature. However, disabling
31//! this feature will make [`Uri::open`] always return `Ok`, regardless of
32//! whether the URI was successfully opened.
33#![allow(clippy::result_unit_err)]
34
35mod error;
36mod sys;
37
38pub use error::{Error, Result};
39
40/// A uniform resource identifier.
41pub struct Uri<'a, 'b> {
42    inner: sys::Uri<'a, 'b>,
43}
44
45impl<'a, 'b> Uri<'a, 'b> {
46    /// Constructs a new URI.
47    pub fn new(s: &'a str) -> Self {
48        Self {
49            inner: sys::Uri::new(s),
50        }
51    }
52
53    /// Sets the action to perform with this URI.
54    ///
55    /// This only has an effect on Android, and corresponds to an [action
56    /// activity][aa]. By default, it is set to `"ACTION_VIEW"`.
57    ///
58    /// # Examples
59    ///
60    /// ```
61    /// # use robius_open::Uri;
62    /// Uri::new("tel:+61 123 456 789")
63    ///     .action("ACTION_DIAL")
64    ///     .open()
65    ///     .expect("failed to open telephone URI");
66    /// ```
67    ///
68    /// [aa]: https://developer.android.com/reference/android/content/Intent#standard-activity-actions
69    pub fn action(self, action: &'b str) -> Self {
70        Self {
71            inner: self.inner.action(action),
72        }
73    }
74
75    /// Opens the URI.
76    pub fn open(self) -> Result<()> {
77        self.inner.open()
78    }
79}