1use zbus::interface;2use zbus::{fdo, proxy};34use crate::Source;5use crate::{BlockingPrompter, Result};6use crate::{Error, Prompter};78pub const BUS_NAME: &str = "lach.RemowtAskpass";9pub const PROMPTER_PATH: &str = "/lach/Askpass";1011pub struct DbusPrompterInterface<P>(pub P);1213#[interface(name = "lach.PolkitInputHandler")]14impl<P: Prompter + Send + Sync + 'static> DbusPrompterInterface<P> {15 async fn prompt_enum(16 &self,17 prompt: &str,18 description: &str,19 variants: Vec<String>,20 source: Vec<Source>,21 ) -> fdo::Result<u32> {22 let variants: Vec<&str> = variants.iter().map(|v| v.as_str()).collect();23 Ok(self24 .025 .prompt_enum(prompt, description, &variants, &source)26 .await?)27 }28 async fn prompt_text(29 &self,30 echo: bool,31 prompt: &str,32 description: &str,33 source: Vec<Source>,34 ) -> fdo::Result<String> {35 Ok(self36 .037 .prompt_text(echo, prompt, description, &source)38 .await?)39 }40 async fn display_text(41 &self,42 error: bool,43 description: &str,44 source: Vec<Source>,45 ) -> fdo::Result<()> {46 Ok(self.0.display_text(error, description, &source).await?)47 }48}4950#[proxy(interface = "lach.PolkitInputHandler")]51pub trait DbusPrompter {52 async fn prompt_enum(53 &self,54 prompt: &str,55 description: &str,56 variants: &[&str],57 source: &[Source],58 ) -> fdo::Result<u32>;59 async fn prompt_text(60 &self,61 echo: bool,62 prompt: &str,63 description: &str,64 source: &[Source],65 ) -> fdo::Result<String>;66 async fn display_text(67 &self,68 error: bool,69 description: &str,70 source: &[Source],71 ) -> fdo::Result<()>;72}7374impl Prompter for DbusPrompterProxy<'_> {75 async fn prompt_enum(76 &self,77 prompt: &str,78 description: &str,79 variants: &[&str],80 source: &[Source],81 ) -> Result<u32> {82 Ok(self83 .prompt_enum(prompt, description, variants, source)84 .await?)85 }8687 async fn prompt_text(88 &self,89 echo: bool,90 prompt: &str,91 description: &str,92 source: &[Source],93 ) -> Result<String> {94 Ok(self.prompt_text(echo, prompt, description, source).await?)95 }9697 async fn display_text(&self, error: bool, description: &str, source: &[Source]) -> Result<()> {98 Ok(self.display_text(error, description, source).await?)99 }100}101impl BlockingPrompter for DbusPrompterProxyBlocking<'_> {102 fn prompt_enum(103 &self,104 prompt: &str,105 description: &str,106 variants: &[&str],107 source: &[Source],108 ) -> Result<u32> {109 Ok(self.prompt_enum(prompt, description, variants, source)?)110 }111112 fn prompt_text(113 &self,114 echo: bool,115 prompt: &str,116 description: &str,117 source: &[Source],118 ) -> Result<String> {119 Ok(self.prompt_text(echo, prompt, description, source)?)120 }121122 fn display_text(&self, error: bool, description: &str, source: &[Source]) -> Result<()> {123 Ok(self.display_text(error, description, source)?)124 }125}126127impl From<fdo::Error> for Error {128 fn from(value: fdo::Error) -> Self {129 if matches!(value, fdo::Error::NoReply(_)) {130 return Self::Cancel;131 }132 Self::InputError(format!("{value}"))133 }134}135impl From<Error> for fdo::Error {136 fn from(value: Error) -> Self {137 match value {138 Error::Cancel => fdo::Error::NoReply("input was cancelled".to_owned()),139 Error::Remote(e) => fdo::Error::NoReply(format!("remote error occured: {e}")),140 Error::InputError(e) => fdo::Error::Failed(e),141 }142 }143}