pub trait Language: Send + Sync {
Show 19 methods
// Required methods
fn pluralize(&self, word: &str, count: usize) -> String;
fn singularize(&self, word: &str) -> String;
fn article(&self, word: &str) -> &str;
fn conjugate(&self, verb: &str, tense: Tense, person: Person) -> String;
fn past_participle(&self, verb: &str) -> String;
fn present_participle(&self, verb: &str) -> String;
fn join_list(&self, items: &[&str], conjunction: Conjunction) -> String;
fn ordinal(&self, n: usize) -> String;
fn number_to_words(&self, n: usize) -> String;
// Provided methods
fn plural_description(
&self,
entity_type: &str,
count: usize,
_features: &AgreementFeatures,
) -> String { ... }
fn verb_phrase(
&self,
verb: &str,
form: VerbForm,
voice: Voice,
person: Person,
) -> String { ... }
fn plural_category(&self, n: i64) -> PluralCategory { ... }
fn pluralize_with_category(
&self,
word: &str,
category: PluralCategory,
) -> String { ... }
fn is_connective_opener(&self, text: &str) -> bool { ... }
fn discourse_marker(&self, relation: RstRelation) -> Option<&'static str> { ... }
fn proportion_phrase(
&self,
matching: i64,
total: i64,
noun_singular: Option<&str>,
_features: &AgreementFeatures,
) -> String { ... }
fn since_last_marker(&self, diff_secs: i64) -> String { ... }
fn realize_reference(
&self,
form: ReferenceForm,
features: &AgreementFeatures,
) -> Option<String> { ... }
fn possessive_name(&self, owner: &str) -> String { ... }
}Expand description
Trait abstracting over a natural language’s grammar rules.
Implement this trait for each language you want to support.
The crate ships with an English implementation in prosaic-grammar-en.
Required Methods§
Sourcefn pluralize(&self, word: &str, count: usize) -> String
fn pluralize(&self, word: &str, count: usize) -> String
Return the plural form of word for the given count.
When count is 1, return the singular form.
Sourcefn singularize(&self, word: &str) -> String
fn singularize(&self, word: &str) -> String
Return the singular form of a potentially plural word.
Sourcefn article(&self, word: &str) -> &str
fn article(&self, word: &str) -> &str
Return the indefinite article (“a” or “an” in English) for word.
Sourcefn conjugate(&self, verb: &str, tense: Tense, person: Person) -> String
fn conjugate(&self, verb: &str, tense: Tense, person: Person) -> String
Conjugate verb in the given simple tense and person
(no aspect/mood compounding — just “renamed”, “renames”, “will rename”).
Sourcefn past_participle(&self, verb: &str) -> String
fn past_participle(&self, verb: &str) -> String
Return the past participle of a verb (e.g., “broken”, “renamed”). Used for passive and perfect constructions (“was renamed”, “has been renamed”, “will have broken”).
Sourcefn present_participle(&self, verb: &str) -> String
fn present_participle(&self, verb: &str) -> String
Return the present participle of a verb (e.g., “renaming”, “writing”). Used for progressive constructions (“is renaming”, “was being renamed”).
Sourcefn join_list(&self, items: &[&str], conjunction: Conjunction) -> String
fn join_list(&self, items: &[&str], conjunction: Conjunction) -> String
Join a list of items with the given conjunction. Should use the language’s standard list format (e.g., Oxford comma in English).
Sourcefn ordinal(&self, n: usize) -> String
fn ordinal(&self, n: usize) -> String
Return the ordinal string for n (e.g., “1st”, “2nd”, “3rd”).
Sourcefn number_to_words(&self, n: usize) -> String
fn number_to_words(&self, n: usize) -> String
Spell out n as words (e.g., 42 → “forty-two”).
Provided Methods§
Sourcefn plural_description(
&self,
entity_type: &str,
count: usize,
_features: &AgreementFeatures,
) -> String
fn plural_description( &self, entity_type: &str, count: usize, _features: &AgreementFeatures, ) -> String
Produce a plural description for a set of same-type entities.
Called by the |refer pipe when the slot value is a Value::List of
2+ items sharing an entity type. The default implementation is
English-shaped but generic enough to serve as a reasonable fallback for
languages that have not overridden it:
- count = 0 →
""(empty string) - count = 1 →
"the {entity_type}" - count ≥ 2 →
"the {count} {entity_type_plural}"
Non-English grammars should override this to handle gender agreement
(Spanish/French), counter words (Japanese), dual/few/many categories
(Arabic), and so on. The features parameter carries agreement info
propagated from the first entity in the set; override implementations
may use it to select the correct article or adjective endings.
English’s prosaic_grammar_en::English uses the default; no override
is needed for v1.
Sourcefn verb_phrase(
&self,
verb: &str,
form: VerbForm,
voice: Voice,
person: Person,
) -> String
fn verb_phrase( &self, verb: &str, form: VerbForm, voice: Voice, person: Person, ) -> String
Render a full verb phrase combining tense, aspect, voice, and mood.
Default implementation composes from the primitive inflections
(conjugate, past_participle, present_participle) following
English auxiliary-verb rules. Override for languages whose verb
phrase structure differs from English’s aux + aux + participle
layout.
Sourcefn plural_category(&self, n: i64) -> PluralCategory
fn plural_category(&self, n: i64) -> PluralCategory
Classify an integer count into a CLDR plural category.
Default implementation uses English rules: n == 1 → PluralCategory::One,
anything else → PluralCategory::Other. Non-English grammars must
override this method to return the correct categories for their
language (e.g., Polish distinguishes One / Few / Many / Other;
Arabic uses all six categories).
Sourcefn pluralize_with_category(
&self,
word: &str,
category: PluralCategory,
) -> String
fn pluralize_with_category( &self, word: &str, category: PluralCategory, ) -> String
Produce the form of word appropriate for the given plural category.
Default implementation uses English rules: PluralCategory::One
returns the singular form (the word unchanged); any other category
returns the plural form via Language::pluralize with count 2,
which picks the plural branch in the legacy API without triggering
irregular-specific overrides that count on the exact integer.
Non-English grammars must override this method when they support
richer category sets (e.g., Polish One / Few / Many / Other) or
when gender / case agreement affects the choice of form.
Sourcefn is_connective_opener(&self, text: &str) -> bool
fn is_connective_opener(&self, text: &str) -> bool
Return a discourse marker for the given RST relation.
Emitted at the START of a sentence (with trailing space), e.g.
"Furthermore, ". Return None to suppress the marker (the renderer
will fall back to a plain inter-sentence space).
The default implementation encodes English markers. Non-English grammars
override with locale-appropriate markers.
Return true when text is a known sentence-leading connective
in this language. Used by retrospective-pass diagnosers (e.g.
ParagraphOpenerMonotony) that need to recognize when a paragraph
opens with a continuation/contrast/sequencing cue rather than
fresh content.
The default impl recognizes the English connective set the engine
itself emits: discourse-relation auto-connectives plus the
discourse_marker outputs. Non-English grammars override with
their own opener lexicon. Match is case-sensitive and includes
the trailing comma — operators should pass the raw connective
text the engine emits, not its lowercased form.
fn discourse_marker(&self, relation: RstRelation) -> Option<&'static str>
Sourcefn proportion_phrase(
&self,
matching: i64,
total: i64,
noun_singular: Option<&str>,
_features: &AgreementFeatures,
) -> String
fn proportion_phrase( &self, matching: i64, total: i64, noun_singular: Option<&str>, _features: &AgreementFeatures, ) -> String
Produce a natural “X of Y” proportion phrase.
Called by the {…|proportion:total_key[:noun]} pipe. Collapses the
awkward literal “N of N noun” to natural forms: “both noun” (when
both equal 2), “all N noun” (saturated, N>2), “the only noun” (1/1),
“none of the N noun” (0/N), “no noun” (0/0), and the literal
“n of t noun” only for partial coverage. See
crate::english_proportion for the full phrasing matrix.
The default implementation encodes English via crate::english_proportion.
Non-English grammars override with locale-appropriate forms
(e.g. Spanish "ambos/ambas", "todos los N"; German "beide",
"alle N"). The features parameter carries gender/number metadata
so implementations can select correctly-agreeing articles and
modifiers.
Sourcefn since_last_marker(&self, diff_secs: i64) -> String
fn since_last_marker(&self, diff_secs: i64) -> String
Format an inter-event temporal delta as a narrative phrase.
Called by the {…|since_last} pipe when the session has a
last_temporal_anchor. diff_secs is current_ts - anchor_ts
(positive = later event). Zero or negative returns “at the same
time” (English default); override for other languages.
The default implementation produces English phrases like “the next day”, “moments later”, “3 weeks later”. Non-English grammars should override to produce locale-appropriate phrases.
Sourcefn realize_reference(
&self,
form: ReferenceForm,
features: &AgreementFeatures,
) -> Option<String>
fn realize_reference( &self, form: ReferenceForm, features: &AgreementFeatures, ) -> Option<String>
Realize a reference form as surface text for this language.
The discourse policy layer chooses the crate::discourse::ReferenceForm
(Full, ShortName, Pronoun, Possessive, Demonstrative, or Zero) based on
language-agnostic rules. This method converts that choice into the
language-specific surface string.
Only Pronoun, Possessive, Demonstrative, and Zero are meaningfully handled
here. Full and ShortName route through the engine’s REG layer
(Dale & Reiter, graph-based) because they involve entity-attribute
logic that’s not the language’s concern.
Returns:
Some(text)for a realized form (e.g.,"it","they","this").NoneforZero(pro-drop) or forFull/ShortName— the caller handles those via REG.
The default implementation encodes English:
Pronoun:"they"whenfeatures.numberisPluralorDual,"it"otherwise.Possessive:"their"whenfeatures.numberisPluralorDual,"its"otherwise.Demonstrative:"this".Zero:None(English doesn’t drop pronouns).Full/ShortName:None(engine handles via REG).
Sourcefn possessive_name(&self, owner: &str) -> String
fn possessive_name(&self, owner: &str) -> String
Convert a named owner phrase into a possessive owner phrase.
Called by {name|possessive} when discourse policy says the entity
should be rendered by name rather than possessive pronoun. The default
is English-shaped ("Foo" -> "Foo's", "Services" -> "Services'");
non-English grammars should override for language-specific genitive
constructions.