git.delta.rocks / remowt / refs/commits / 2499daa8100a

difftreelog

source

crates/ui-prompt/src/lib.rs3.2 KiBsourcehistory
1use core::fmt;2use std::borrow::Cow;3use std::future::Future;4use std::result;56pub mod dbus;7pub mod rofi;89#[derive(thiserror::Error, Debug)]10pub enum Error {11    #[error("user has cancelled input")]12    Cancel,13    #[error("input error: {0}")]14    InputError(String),15}1617pub type Result<T, E = Error> = result::Result<T, E>;1819#[cfg_attr(feature = "dbus", derive(zbus::zvariant::Type))]20#[derive(serde::Serialize, serde::Deserialize, Clone)]21pub struct Source(Cow<'static, str>);22impl fmt::Display for Source {23    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {24        write!(f, "<u>{}</u>", self.0)25    }26}2728pub trait Prompter {29    fn prompt_radio(30        &self,31        prompt: &str,32        description: &str,33        source: &[Source],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;45    fn prompt_text(46        &self,47        echo: bool,48        prompt: &str,49        description: &str,50        source: &[Source],51    ) -> impl Future<Output = Result<String>> + Send;52    fn display_text(53        &self,54        error: bool,55        description: &str,56        source: &[Source],57    ) -> impl Future<Output = Result<()>> + Send;58}59pub trait BlockingPrompter {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>;71    fn prompt_text(72        &self,73        echo: bool,74        prompt: &str,75        description: &str,76        source: &[Source],77    ) -> Result<String>;78    fn display_text(&self, error: bool, description: &str, source: &[Source]) -> Result<()>;79}8081pub struct PrependSourcePrompter<P> {82    prompter: P,83    source: Vec<Source>,84}85impl<P> PrependSourcePrompter<P> {86    fn source(&self, input: &[Source]) -> Vec<Source> {87        let mut out = self.source.clone();88        out.extend(input.iter().cloned());89        out90    }91}92impl<P> Prompter for PrependSourcePrompter<P>93where94    P: Prompter + Sync,95{96    async fn prompt_enum(97        &self,98        prompt: &str,99        description: &str,100        variants: &[&str],101        source: &[Source],102    ) -> Result<u32> {103        self.prompter104            .prompt_enum(prompt, description, variants, &self.source(source))105            .await106    }107108    async fn prompt_text(109        &self,110        echo: bool,111        prompt: &str,112        description: &str,113        source: &[Source],114    ) -> Result<String> {115        self.prompter116            .prompt_text(echo, prompt, description, &self.source(source))117            .await118    }119120    async fn display_text(&self, error: bool, description: &str, source: &[Source]) -> Result<()> {121        self.prompter122            .display_text(error, description, &self.source(source))123            .await124    }125}