difftreelog
feat enum prompt variant
in: trunk
11 files changed
Cargo.lockdiffbeforeafterboth351351352[[package]]352[[package]]353name = "clap"353name = "clap"354version = "4.5.11"354version = "4.5.13"355source = "registry+https://github.com/rust-lang/crates.io-index"355source = "registry+https://github.com/rust-lang/crates.io-index"356checksum = "35723e6a11662c2afb578bcf0b88bf6ea8e21282a953428f240574fcc3a2b5b3"356checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc"357dependencies = [357dependencies = [358 "clap_builder",358 "clap_builder",359 "clap_derive",359 "clap_derive",360]360]361361362[[package]]362[[package]]363name = "clap_builder"363name = "clap_builder"364version = "4.5.11"364version = "4.5.13"365source = "registry+https://github.com/rust-lang/crates.io-index"365source = "registry+https://github.com/rust-lang/crates.io-index"366checksum = "49eb96cbfa7cfa35017b7cd548c75b14c3118c98b423041d70562665e07fb0fa"366checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99"367dependencies = [367dependencies = [368 "anstream",368 "anstream",369 "anstyle",369 "anstyle",373373374[[package]]374[[package]]375name = "clap_derive"375name = "clap_derive"376version = "4.5.11"376version = "4.5.13"377source = "registry+https://github.com/rust-lang/crates.io-index"377source = "registry+https://github.com/rust-lang/crates.io-index"378checksum = "5d029b67f89d30bbb547c89fd5161293c0aec155fc691d7924b64550662db93e"378checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0"379dependencies = [379dependencies = [380 "heck",380 "heck",381 "proc-macro2",381 "proc-macro2",862 "futures-io",862 "futures-io",863]863]864865[[package]]866name = "polkit-agent"867version = "0.1.0"868dependencies = [869 "anyhow",870 "pam-client",871 "polkit-shared",872 "rand",873 "serde",874 "tokio",875 "tracing",876 "tracing-subscriber",877 "ui-prompt",878 "uuid",879 "zbus",880 "zbus_polkit",881]882864883[[package]]865[[package]]884name = "polkit-backend"866name = "polkit-backend"1012source = "registry+https://github.com/rust-lang/crates.io-index"994source = "registry+https://github.com/rust-lang/crates.io-index"1013checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"995checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"996997[[package]]998name = "remowt-agent"999version = "0.1.0"1000dependencies = [1001 "anyhow",1002 "clap",1003 "pam-client",1004 "polkit-shared",1005 "rand",1006 "serde",1007 "tokio",1008 "tracing",1009 "tracing-subscriber",1010 "ui-prompt",1011 "uuid",1012 "zbus",1013 "zbus_polkit",1014]10151016[[package]]1017name = "remowt-ssh"1018version = "0.1.0"101410191015[[package]]1020[[package]]1016name = "rpassword"1021name = "rpassword"Cargo.tomldiffbeforeafterboth2members = ["cmds/*", "crates/*"]2members = ["cmds/*", "crates/*"]3resolver = "2"3resolver = "2"45[workspace.packages]6bifrostlink = { path = "../bifrostlink/crates/bifrostlink" }7bifrostlink-ports = { path = "../bifrostlink/crates/bifrostlink-ports" }48cmds/polkit-agent/Cargo.tomldiffbeforeafterbothno changes
cmds/polkit-agent/src/main.rsdiffbeforeafterbothno changes
cmds/remowt-agent/Cargo.tomldiffbeforeafterbothno changes
cmds/remowt-agent/src/main.rsdiffbeforeafterbothno changes
cmds/remowt-ssh/Cargo.tomldiffbeforeafterbothno changes
cmds/remowt-ssh/src/main.rsdiffbeforeafterbothno changes
crates/ui-prompt/src/dbus.rsdiffbeforeafterboth404041#[proxy(interface = "lach.PolkitInputHandler")]41#[proxy(interface = "lach.PolkitInputHandler")]42trait DbusPrompter {42trait DbusPrompter {43 async fn prompt_radio(43 async fn prompt_enum(44 &self,44 &self,45 prompt: &str,45 prompt: &str,46 description: &str,46 description: &str,47 variants: &[&str],47 source: &[Source],48 source: &[Source],48 ) -> fdo::Result<bool>;49 ) -> fdo::Result<u32>;49 async fn prompt_text(50 async fn prompt_text(50 &self,51 &self,51 echo: bool,52 echo: bool,62}63}636464impl Prompter for DbusPrompterProxy<'_> {65impl Prompter for DbusPrompterProxy<'_> {65 async fn prompt_radio(66 async fn prompt_enum(66 &self,67 &self,67 prompt: &str,68 prompt: &str,68 description: &str,69 description: &str,70 variants: &[&str],69 source: &[Source],71 source: &[Source],70 ) -> Result<bool> {72 ) -> Result<u32> {71 Ok(self.prompt_radio(prompt, description, source).await?)73 Ok(self74 .prompt_enum(prompt, description, variants, source)75 .await?)72 }76 }737786 }90 }87}91}88impl BlockingPrompter for DbusPrompterProxyBlocking<'_> {92impl BlockingPrompter for DbusPrompterProxyBlocking<'_> {89 fn prompt_radio(&self, prompt: &str, description: &str, source: &[Source]) -> Result<bool> {93 fn prompt_enum(94 &self,95 prompt: &str,96 description: &str,97 variants: &[&str],98 source: &[Source],99 ) -> Result<u32> {90 Ok(self.prompt_radio(prompt, description, source)?)100 Ok(self.prompt_enum(prompt, description, variants, source)?)91 }101 }9210293 fn prompt_text(103 fn prompt_text(crates/ui-prompt/src/lib.rsdiffbeforeafterboth31 prompt: &str,31 prompt: &str,32 description: &str,32 description: &str,33 source: &[Source],33 source: &[Source],34 ) -> impl Future<Output = Result<bool>> + Send;34 ) -> impl Future<Output = Result<bool>> + Send {35 let fut = self.prompt_enum(prompt, description, &["No", "Yes"], source);36 async { fut.await.map(|v| v == 1) }37 }38 fn prompt_enum(39 &self,40 prompt: &str,41 description: &str,42 variants: &[&str],43 source: &[Source],44 ) -> impl Future<Output = Result<u32>> + Send;35 fn prompt_text(45 fn prompt_text(36 &self,46 &self,37 echo: bool,47 echo: bool,47 ) -> impl Future<Output = Result<()>> + Send;57 ) -> impl Future<Output = Result<()>> + Send;48}58}49pub trait BlockingPrompter {59pub trait BlockingPrompter {50 fn prompt_radio(&self, prompt: &str, description: &str, source: &[Source]) -> Result<bool>;60 fn prompt_radio(&self, prompt: &str, description: &str, source: &[Source]) -> Result<bool> {61 self.prompt_enum(prompt, description, &["No", "Yes"], source)62 .map(|v| v == 1)63 }64 fn prompt_enum(65 &self,66 prompt: &str,67 description: &str,68 variants: &[&str],69 source: &[Source],70 ) -> Result<u32>;51 fn prompt_text(71 fn prompt_text(52 &self,72 &self,53 echo: bool,73 echo: bool,73where93where74 P: Prompter + Sync,94 P: Prompter + Sync,75{95{76 async fn prompt_radio(96 async fn prompt_enum(77 &self,97 &self,78 prompt: &str,98 prompt: &str,79 description: &str,99 description: &str,100 variants: &[&str],80 source: &[Source],101 source: &[Source],81 ) -> Result<bool> {102 ) -> Result<u32> {82 self.prompter103 self.prompter83 .prompt_radio(prompt, description, &self.source(source))104 .prompt_enum(prompt, description, variants, &self.source(source))84 .await105 .await85 }106 }86107crates/ui-prompt/src/rofi.rsdiffbeforeafterboth889pub struct RofiPrompter;9pub struct RofiPrompter;1011fn fixup_prompt(prompt: &str) -> &str {12 // Rofi always appends such suffix13 prompt.strip_suffix(": ").unwrap_or(prompt)14}101511impl Prompter for RofiPrompter {16impl Prompter for RofiPrompter {12 async fn prompt_radio(17 async fn prompt_enum(13 &self,18 &self,14 prompt: &str,19 prompt: &str,15 description: &str,20 description: &str,21 variants: &[&str],16 source: &[Source],22 source: &[Source],17 ) -> Result<bool> {23 ) -> Result<u32> {18 trace!("rofi radio");24 trace!("rofi radio");19 let mut cmd = Command::new("rofi");25 let mut cmd = Command::new("rofi");20 let mesg = if source.is_empty() {26 let mesg = if source.is_empty() {34 "-sync",40 "-sync",35 "-only-match",41 "-only-match",36 "-p",42 "-p",37 prompt,43 fixup_prompt(prompt),44 "-format",45 "i",38 ]);46 ]);39 cmd.stdin(Stdio::piped());47 cmd.stdin(Stdio::piped());40 cmd.stdout(Stdio::piped());48 cmd.stdout(Stdio::piped());43 .spawn()51 .spawn()44 .map_err(|e| Error::InputError(format!("failed to spawn rofi: {e}")))?;52 .map_err(|e| Error::InputError(format!("failed to spawn rofi: {e}")))?;455346 child54 let mut stdin = child.stdin.take().expect("stdin is piped");47 .stdin55 for var in variants {48 .take()56 stdin49 .expect("stdin is piped")57 .write_all(var.replace('\n', " ").as_bytes())58 .await59 .map_err(|e| Error::InputError(format!("failed to write rofi variants: {e}")))?;60 stdin50 .write_all(b"Yes\nNo\n")61 .write_all(b"\n")51 .await62 .await52 .map_err(|e| Error::InputError(format!("failed to write rofi variants: {e}")))?;63 .map_err(|e| Error::InputError(format!("failed to write rofi variants: {e}")))?;64 }65 // write_all already flushes, just to be sure.66 let _ = stdin.flush().await;67 drop(stdin);536854 let out = child69 let out = child55 .wait_with_output()70 .wait_with_output()61 .unwrap_or(&out.stdout)76 .unwrap_or(&out.stdout)62 .to_owned();77 .to_owned();637879 let id: u32 = String::from_utf8(stdout)80 .map_err(|e| Error::InputError(format!("rofi produced invalid output: {e}")))?81 .parse()82 .map_err(|e| Error::InputError(format!("rofi produced invalid output: {e}")))?;64 if &stdout == b"Yes" {83 if id as usize >= variants.len() {65 Ok(true)66 } else if &stdout == b"No" {67 Ok(false)68 } else {69 Err(Error::InputError("bad rofi response".to_owned()))84 return Err(Error::InputError("invalid rofi response".to_owned()));70 }85 }8687 Ok(id)71 }88 }728973 async fn prompt_text(90 async fn prompt_text(89 out.push_str("</b>");106 out.push_str("</b>");90 out107 out91 };108 };92 cmd.args(["-dmenu", "-mesg", &mesg, "-p", prompt]);109 cmd.args(["-dmenu", "-mesg", &mesg, "-p", fixup_prompt(prompt)]);93 if !echo {110 if !echo {94 cmd.arg("-password");111 cmd.arg("-password");95 }112 }