Permission
Purpose
Asking for the camera, the microphone, the location and notifications.
Signature
pub enum Permission {
/// The camera.
Camera,
/// The microphone.
Microphone,
/// Where the device is.
Location,
/// Showing notifications.
Notifications,
}
Example

From frus-examples/widgets/src/features/interaction/widgets/permissions.rs:
//! `Permission` — asking the person for the camera, the microphone, the location and
//! notifications, and knowing what they said. `status()` looks without asking; `request()` asks
//! when there is something to ask. Both are `async`, so they run from an async handler.
use frus::{
component, open_permission_settings, Align, Button, Column, Permission, PermissionStatus,
Row, Text, Variant, Widget,
};
use crate::common::shared::{section, sections};
const ALL: [Permission; 4] = [
Permission::Camera,
Permission::Microphone,
Permission::Location,
Permission::Notifications,
];
fn name(permission: Permission) -> &'static str {
match permission {
Permission::Camera => "Camera",
Permission::Microphone => "Microphone",
Permission::Location => "Location",
Permission::Notifications => "Notifications",
}
}
fn said(status: Option<PermissionStatus>) -> &'static str {
match status {
None => "not looked at yet",
Some(PermissionStatus::Granted) => "granted",
Some(PermissionStatus::Ask) => "not decided: asking shows the question",
Some(PermissionStatus::Denied) => "refused: asking shows the question again",
Some(PermissionStatus::Blocked) => "blocked: only the settings can change it",
Some(PermissionStatus::Unavailable) => "unavailable here",
}
}
pub fn example() -> Box<dyn Widget> {
Box::new(component(|cx| {
let statuses = cx.use_state(|| [None::<PermissionStatus>; 4]);
let mut rows = Column::new()
.spacing(12.0)
.cross_axis_alignment(Align::Start);
for (index, permission) in ALL.into_iter().enumerate() {
let (looked, answered) = (statuses.clone(), statuses.clone());
// Looking does not ask; asking waits for the person's answer.
let look = cx.async_callback(move || {
let looked = looked.clone();
async move {
let status = permission.status().await;
looked.update(|all| all[index] = Some(status));
}
});
let ask = cx.async_callback(move || {
let answered = answered.clone();
async move {
let status = permission.request().await;
answered.update(|all| all[index] = Some(status));
}
});
rows = rows.child(
Column::new()
.spacing(4.0)
.cross_axis_alignment(Align::Start)
.child(Text::new(format!(
"{}: {}",
name(permission),
said(statuses.get()[index])
)))
.child(
Row::new()
.spacing(8.0)
.child(
Button::new("Look")
.variant(Variant::Outlined)
.on_press(look),
)
.child(Button::new("Ask").on_press(ask)),
),
);
}
sections(vec![
Box::new(section("Each permission, looked at or asked for", rows)),
Box::new(section(
"After a refusal for good",
Button::new("Open the settings")
.variant(Variant::Tonal)
.on_press(open_permission_settings),
)),
])
}))
}
Properties
No builder methods: everything is set through the constructor.
Behaviour
Something an application asks the person's permission for.
See also
- Disabled state: one enabled flag on every control: greyed out, inert, value kept.
- Semantics: what a screen reader is told about a widget, said from outside it.
- The guide: Taking input
- API reference:
Permission
Source: crates/frus-shell/src/permission.rs @ e6fba33f5b42