General-purpose natural language generation from structured data.
Takes structured events and produces natural-sounding prose, not just grammatically correct output. The engine tracks discourse state across calls, so multiple renders flow together like human-written prose — using pronouns, varying phrasing, matching verbosity to impact, and structuring multi-paragraph narratives.
English, Spanish, and German grammars ship out of the box via the
prosaic-grammar-en, -es, and -de sibling crates. Add more
languages by implementing the [Language] trait.
Quick start
use ;
use English;
let mut engine = new
.strictness
.variation;
engine.register_template.unwrap;
let mut ctx = new;
ctx.insert;
ctx.insert;
ctx.insert;
let mut session = new;
let sentence = engine.render.unwrap;
assert_eq!;
Type-aware template validation
Context types that derive IntoContext also get a HasProsaicSchema
impl for free. Pair it with the context: argument of
prosaic_template! to validate slot types at compile time:
use prosaic_core::{Engine, Session};
use prosaic_derive::{IntoContext, prosaic_template};
use prosaic_grammar_en::English;
#[derive(IntoContext)]
struct RenameCtx {
old_name: String,
new_name: String,
consumer_count: i64,
}
// Compile error if `consumer_count` were declared as `String`:
let tpl = prosaic_template! {
template: "{old_name} → {new_name} ({consumer_count|pluralize:consumer})",
slots: [old_name, new_name, consumer_count],
context: RenameCtx,
};
let mut engine = Engine::new(English::new());
engine.register_template("rename", tpl).unwrap();
For templates loaded dynamically (JSON manifests, on-disk sources),
use [Engine::register_template_with_schema] to get the same check
at registration time.
Feature flags
std(default):std::error::ErroronProsaicError,SystemTime::now()fallbacks. Disable forno_std + alloctargets.time(default):{ts|relative}and{ts|since_last}pipes.polish(default): sentence-length budgeting and smart quotes.reg(default): referring expression generation (Dale-Reiter + graph-based).serde(off):Serialize/Deserializeon public types.parallel(off):DocumentPlan::render_parallelvia rayon.
no_std support
Disable the std feature to compile under no_std + alloc:
= { = "0.2", = false }
Without the std feature:
Variation::Randomfalls back toVariation::Fixed(variant 0).{ts|relative}and{ts|since_last}requireengine.reference_time().ProsaicErrordoes not implementstd::error::Error.