elicitor
Derive interactive surveys from Rust types.
Elicitor generates survey definitions from structs and enums using a procedural macro. The resulting surveys can be presented through different backends: terminal wizards, terminal forms, or graphical interfaces.
Documents to fill out can also be generated from a survey definition.
Basic Usage
use Survey;
Add to your Cargo.toml:
[]
= "0.6"
= "0.6" # or another backend
Attributes
On types
| Attribute | Purpose |
|---|---|
#[prelude("...")] |
Message shown before the survey |
#[epilogue("...")] |
Message shown after completion |
#[validate(fn_name)] |
Composite validator for cross-field checks |
On fields
| Attribute | Purpose |
|---|---|
#[ask("...")] |
Prompt text shown to the user |
#[mask] |
Hide input (passwords) |
#[multiline] |
Multi-line text input |
#[validate(fn_name)] |
Field-level validation |
#[min(n)] / #[max(n)] |
Numeric bounds |
#[multiselect] |
Multi-select for Vec<Enum> fields |
Supported Types
- Primitives:
String,bool, integers (i8..i64,u8..u64), floats (f32,f64) - Collections:
Vec<T>where T is a primitive or enum - Optional:
Option<T>for any supported T - Nested structs: Types that also derive
Survey - Enums: Unit variants, tuple variants, and struct variants
- Path types:
PathBuf
Enums
Enums become selection questions. The user picks a variant, then fills in any associated data.
For multi-select (choosing multiple variants), use Vec<Enum> with #[multiselect]:
As you can see, enums can have associated data, which is collected separately from the multiselect itself.
Validation
Field-level validators receive the current value and all collected responses:
Composite validators check relationships between fields:
Builder Pattern for assumptions and suggestions
You can pre-fill values as suggestions or skip questions which have assumed answers. Details depend on the backend.
Suggestions pre-fill fields with editable defaults:
let profile = builder
.suggest_name
.suggest_age
.run?;
Assumptions skip questions entirely:
let profile = builder
.assume_name // User won't be prompted
.run?;
Bulk suggestions from an existing instance:
let existing = load_profile?;
let updated = builder
.with_suggestions
.run?;
Backends
Backends present the survey to users. Each is a separate crate.
| Crate | Style | Description |
|---|---|---|
elicitor-wizard-dialoguer |
Wizard | CLI prompts via dialoguer |
elicitor-wizard-requestty |
Wizard | CLI prompts via requestty |
elicitor-wizard-ratatui |
Wizard | Terminal UI, one question at a time |
elicitor-form-ratatui |
Form | Terminal UI, all fields visible |
elicitor-form-egui |
Form | Native GUI via egui |
Wizard-style backends ask one question at a time. Form-style backends show all fields simultaneously.
Document Generators
These crates generate static documents from survey definitions:
| Crate | Output |
|---|---|
elicitor-doc-html |
HTML form |
elicitor-doc-latex |
LaTeX document |
Testing
Use TestBackend for unit tests:
Architecture
The crate is split into three parts:
- elicitor-types: Core data structures (
SurveyDefinition,Question,Responses, traits) - elicitor-macro: The
#[derive(Survey)]procedural macro - elicitor: Facade crate that re-exports both
Users only need to depend on elicitor. The macro generates code that uses types from elicitor_types, which are re-exported through the main crate.
See docs/architecture.md for details.
License
Licensed under either of Apache License, Version 2.0 or MIT license at your option.