Skip to main content

Form

Struct Form 

Source
pub struct Form { /* private fields */ }
Expand description

A form: named fields answered together, on one page or several. Returns Answers.

use rich_interact::headless::{self, Script};
use rich_interact::{Form, Input};

let form = Form::new("New service")
    .note("Welcome", "Two pages: the service, then where it runs.")
    .input("name", Input::new("Name"))
    .describe("Lower case, no spaces")
    .multi("features", "Features", ["tls", "metrics", "logs"])
    .group("Where")
    .choice("cloud", "Cloud", ["aws", "gcp"])
    .dynamic_choice("region", "Region", |answers| match answers.text("cloud") {
        Some("gcp") => vec!["europe-west1".into(), "us-central1".into()],
        _ => vec!["eu-west-1".into(), "us-east-1".into()],
    });
// Page one: a name and two features; Enter on its last field moves to
// page two, where GCP's regions are offered.
let script = Script::new()
    .text("api")
    .keys("tab space right space enter right tab right enter");
let (outcome, _) = headless::run(form, script, 60, 16);
let answers = outcome.unwrap().value().unwrap();
assert_eq!(answers.list("features").unwrap(), ["tls", "metrics"]);
assert_eq!(answers.text("region"), Some("us-central1"));

Implementations§

Source§

impl Form

Source

pub fn new(title: impl Into<String>) -> Form

Source

pub fn rebind(self, action: &str, keys: impl IntoIterator<Item = Key>) -> Self

Make keys do action on this form only; no keys unbinds it. The actions are the form’s (submit, cancel, next, previous, and with pages next-page and previous-page), a choice field’s (next-option, previous-option), a multi-select’s (next-choice, previous-choice, choose), a file field’s (browse) and a toggle’s (toggle, yes, no); see keymap. A text field’s keys are its Input’s, and an open picker’s its FilePicker’s.

Source

pub fn with_mouse(self, on: bool) -> Self

Report the mouse (#476): a click focuses a field (and flips a toggle, moves a choice on, chooses a multi-select’s option or opens a file field’s picker), a click on a page’s dot goes to that page, and Submit and Cancel buttons show under the fields.

Source

pub fn text(self, name: impl Into<String>, label: impl Into<String>) -> Self

A text field.

Source

pub fn input(self, name: impl Into<String>, input: Input) -> Self

A text field from a configured Input (validation, placeholder, default, suggestions); its prompt is the label.

Source

pub fn masked(self, name: impl Into<String>, label: impl Into<String>) -> Self

A masked text field, for passwords and tokens (see Input::masked).

Source

pub fn choice<I, S>( self, name: impl Into<String>, label: impl Into<String>, options: I, ) -> Self
where I: IntoIterator<Item = S>, S: Into<String>,

One of options, changed with Left and Right (or Space).

Source

pub fn dynamic_choice( self, name: impl Into<String>, label: impl Into<String>, options: impl Fn(&Answers) -> Vec<String> + 'static, ) -> Self

A choice whose options depend on the answers above it: options gets the answers of the fields before this one (those that have an answer yet) and returns the options. They are worked out again after every key; the option chosen stays chosen while it is still offered.

Source

pub fn multi<I, S>( self, name: impl Into<String>, label: impl Into<String>, options: I, ) -> Self
where I: IntoIterator<Item = S>, S: Into<String>,

Any number of options (Huh’s multi-select): Left and Right move between them, Space (or x) chooses one. Answers a Value::List, in the options’ order.

Source

pub fn chosen<I, S>(self, options: I) -> Self
where I: IntoIterator<Item = S>, S: AsRef<str>,

Choose these options of the multi-select just added, to begin with.

Source

pub fn limit(self, count: usize) -> Self

Let at most count options of the multi-select just added be chosen.

Source

pub fn toggle( self, name: impl Into<String>, label: impl Into<String>, on: bool, ) -> Self

Yes or no, changed with Space, Left, Right, y and n.

Source

pub fn note(self, title: impl Into<String>, body: impl Into<String>) -> Self

Read-only text: a title and a body, wrapped to the width. Focus passes over it and it has no answer.

Source

pub fn file( self, name: impl Into<String>, label: impl Into<String>, picker: FilePicker, ) -> Self

A path picked with picker (a FilePicker: its root, mode, extensions and jail apply). Space (or a click) opens it under the field; picking closes it, and Escape closes it with no change. Answers a Value::Path; with nothing picked, the picker’s default, and without one the field fails.

Source

pub fn describe(self, description: impl Into<String>) -> Self

A line of help under the field just added, shown dim.

Source

pub fn group(self, title: impl Into<String>) -> Self

Start a new page titled title: the fields added after it are shown together, and the form’s pages one at a time. Before any field it titles the first page.

Source

pub fn page_style(self, style: PaginatorStyle) -> Self

How the page indicator looks (default: dots).

Source

pub fn theme(self, theme: Theme) -> Self

Source

pub fn page(&self) -> usize

The page showing, from 0.

Trait Implementations§

Source§

impl Component for Form

Source§

fn start(&mut self, _: &Context<'_>) -> Flow<Answers>

A form with no fields has nothing to ask: done at once.

Source§

fn tick(&self) -> Option<Duration>

Ticks for text fields with a suggestion provider, so its results arrive, and for an open picker’s previews.

Source§

fn prompt( &mut self, io: &mut dyn LineIo, ) -> Result<Option<Answers>, NotInteractive>

Without a terminal: a line a field, in order, each page’s title before its fields and each note’s text where it is.

Source§

type Output = Answers

Source§

fn keymap(&self) -> Keymap

The bindings this component has right now, for a help overlay, a shortcut list or status-bar hints to read (see keymap). A container’s include its focused child’s, before its own. The default declares none.
Source§

fn handle(&mut self, event: &Event, context: &Context<'_>) -> Flow<Answers>

Handle one event. Ctrl+C never arrives here: the event loop ends the component with Outcome::Interrupted.
Source§

fn render(&self, context: &Context<'_>) -> View

Render the current state.
Source§

fn mouse(&self) -> bool

Whether the component wants mouse events (#476): clicks, drags and the wheel. Off by default, since reporting the mouse takes text selection away from the terminal; a component turns it on when its caller opts in, and run then enables mouse reporting for the session.
Source§

fn focusable(&self) -> bool

Whether the component takes focus in a container: Tab stops on it and keys go to it. The default: yes. A label, or a component that has finished, says no.
Source§

fn focus_step(&mut self, forward: bool) -> bool

Move focus to the next (forward) or previous focus stop inside this component, for Tab and Shift+Tab. false when there is none after the current one, so the container moves on to its next child. The default, for a component that is one stop: false.
Source§

fn focus_enter(&mut self, forward: bool) -> bool

Take focus from outside: at the first stop inside when forward, at the last otherwise. false when nothing in it can take focus. The default: whether the component is focusable.
Source§

fn default_value(&self) -> Option<Self::Output>

The value to return when the terminal is not interactive and the policy asks for defaults. None: there is none.

Auto Trait Implementations§

§

impl !RefUnwindSafe for Form

§

impl !Send for Form

§

impl !Sync for Form

§

impl !UnwindSafe for Form

§

impl Freeze for Form

§

impl Unpin for Form

§

impl UnsafeUnpin for Form

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<C> ComponentExt for C
where C: Component,

Source§

fn map<'a, M>( self, done: impl FnMut(Self::Output) -> Flow<M> + 'a, ) -> Map<'a, Self, M>
where Self: 'a,

Turn this component’s answer into M’s flow: Flow::Done(m) to finish the whole composition with m, Flow::Continue to carry on (the component stays, showing its answer, and focus moves past it). Cancelling cancels the composition unless on_cancel says otherwise.
Source§

fn with_overlays<'a>(self) -> Overlays<'a, Self::Output>
where Self: 'a, Self::Output: 'a,

Wrap this component in Overlays: a command palette, help and a shortcut sheet read from its keymap, and room for a status bar and breadcrumbs.
Source§

fn boxed<'a>(self) -> Child<'a, Self::Output>
where Self: 'a,

Box this component as a Child.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.