1use std::path::Path;23use bifrostlink::declarative::RemoteEndpoints as _;4use remowt_link_shared::{Address, BifConfig, gateway};5use tracing::debug;67use crate::bifrost::PromptEndpointsClient;8use crate::rofi::RofiPrompter;9use crate::{Prompter, Result, Source};1011pub struct AutoPrompter {12 remote: Option<PromptEndpointsClient<BifConfig>>,13 fallback: RofiPrompter,14}1516impl AutoPrompter {17 pub async fn new() -> Self {18 let remote = match gateway::local_socket() {19 Ok(path) => Self::try_connect(&path).await,20 Err(e) => {21 debug!("no local gateway socket, falling back to rofi: {e}");22 None23 }24 };25 Self {26 remote,27 fallback: RofiPrompter,28 }29 }3031 async fn try_connect(path: &Path) -> Option<PromptEndpointsClient<BifConfig>> {32 match gateway::connect(path).await {33 Ok(rpc) => Some(PromptEndpointsClient::wrap(rpc.remote(Address::User))),34 Err(e) => {35 debug!("local prompt agent unavailable, falling back to rofi: {e}");36 None37 }38 }39 }40}4142impl Prompter for AutoPrompter {43 async fn prompt_enum(44 &self,45 prompt: &str,46 description: &str,47 variants: &[&str],48 source: &[Source],49 ) -> Result<u32> {50 if let Some(remote) = &self.remote {51 return Prompter::prompt_enum(remote, prompt, description, variants, source).await;52 }53 self.fallback54 .prompt_enum(prompt, description, variants, source)55 .await56 }5758 async fn prompt_text(59 &self,60 echo: bool,61 prompt: &str,62 description: &str,63 source: &[Source],64 ) -> Result<String> {65 if let Some(remote) = &self.remote {66 return Prompter::prompt_text(remote, echo, prompt, description, source).await;67 }68 self.fallback69 .prompt_text(echo, prompt, description, source)70 .await71 }7273 async fn display_text(&self, error: bool, description: &str, source: &[Source]) -> Result<()> {74 if let Some(remote) = &self.remote {75 return Prompter::display_text(remote, error, description, source).await;76 }77 self.fallback.display_text(error, description, source).await78 }79}