use car_permissions::{Domain, PermissionStatus};
use serde_json::{json, Value};
fn err_json(e: car_permissions::PermissionError) -> String {
use car_permissions::PermissionError::*;
let code = match e {
Unavailable(_) => "unavailable",
Backend(_) => "backend",
};
serde_json::json!({"code": code, "message": e.to_string()}).to_string()
}
fn parse_domain(name: &str) -> Result<Domain, String> {
Ok(match name {
"browser" => Domain::Browser,
"contacts" => Domain::Contacts,
"calendar" => Domain::Calendar,
"mail" => Domain::Mail,
"accessibility" => Domain::Accessibility,
"screen_capture" => Domain::ScreenCapture,
"automation" => Domain::Automation,
"camera" => Domain::Camera,
"microphone" => Domain::Microphone,
"health_read" => Domain::HealthRead,
other => {
return Err(serde_json::json!({
"code": "invalid_domain",
"message": format!("unknown permission domain: {}", other),
})
.to_string())
}
})
}
fn status_label(s: PermissionStatus) -> &'static str {
match s {
PermissionStatus::Granted => "granted",
PermissionStatus::Denied => "denied",
PermissionStatus::NotDetermined => "not_determined",
PermissionStatus::Restricted => "restricted",
PermissionStatus::NotApplicable => "not_applicable",
PermissionStatus::RestartRequired => "restart_required",
PermissionStatus::SignatureChanged => "signature_changed",
_ => "unknown",
}
}
fn make_ctx(target_bundle_id: Option<&str>) -> car_permissions::Context {
let mut c = car_permissions::Context::default();
if let Some(t) = target_bundle_id {
c.target_bundle_id = Some(t.to_string());
}
c
}
pub fn status(domain: &str, target_bundle_id: Option<&str>) -> Result<Value, String> {
let d = parse_domain(domain)?;
let s = car_permissions::status_with(d, &make_ctx(target_bundle_id)).map_err(err_json)?;
Ok(json!({
"domain": domain,
"status": status_label(s),
"target_bundle_id": target_bundle_id,
}))
}
pub fn request(domain: &str, target_bundle_id: Option<&str>) -> Result<Value, String> {
let d = parse_domain(domain)?;
let s = car_permissions::request_with(d, &make_ctx(target_bundle_id)).map_err(err_json)?;
Ok(json!({
"domain": domain,
"status": status_label(s),
"target_bundle_id": target_bundle_id,
}))
}
pub fn explain(domain: &str, target_bundle_id: Option<&str>) -> Result<Value, String> {
let d = parse_domain(domain)?;
let e = car_permissions::explain_with(d, &make_ctx(target_bundle_id)).map_err(err_json)?;
Ok(json!({
"domain": domain,
"status": status_label(e.status),
"message": e.message,
"fix": e.fix,
"target_bundle_id": target_bundle_id,
}))
}
pub fn domains() -> Value {
let all: Vec<&str> = car_permissions::domains()
.into_iter()
.map(|d| d.as_str())
.collect();
json!({"domains": all})
}