Skip to main content

LangCs

Struct LangCs 

Source
pub struct LangCs { /* private fields */ }

Implementations§

Source§

impl LangCs

Source

pub fn new() -> Self

Trait Implementations§

Source§

impl Default for LangCs

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Lang for LangCs

Source§

fn default_currency(&self) -> &str

This language’s own to_currency(currency=...) default, read from the live Python signature. Only 44 of 156 use EUR.

Source§

fn default_separator(&self) -> &str

This language’s own to_currency(separator=...) default, read from the live Python signature. Base’s is “,”, but only 36 of 149 languages actually use it — most default to “ “ or a conjunction, so inheriting Base’s comma silently corrupts them.

Source§

fn to_cardinal(&self, value: &BigInt) -> Result<String>

Port of Num2Word_CS.to_cardinal, integer path only.

Python builds n = str(number).replace(",", ".") and branches on "." in n. For integer input there is never a . or ,, so only the else arm is reachable: strip a leading "-", convert the magnitude, and prefix negword + " ".

Note the negword is used unstripped (self.negword + " " + result), not via Num2Word_Base’s "%s " % self.negword.strip(). “mínus” has no surrounding whitespace, so both spell “mínus jedna” — but the override means the base’s parse_minus spacing convention does not apply here.

Source§

fn to_ordinal(&self, value: &BigInt) -> Result<String>

Port of Num2Word_CS.to_ordinal.

int(number) inside Python’s try always succeeds for integer input, so the except (ValueError, TypeError): return str(number) fallback is unreachable and is not modelled.

The table covers 1..=20, the round tens 30..=90, 100 and 1000. Every other input — including 0 and all negatives — takes the to_cardinal(num) + "ý" path, producing the malformed-but-correct outputs documented in the module header (“nulaý”, “dvě stěý”, “mínus jednaý”, …). Reproduced verbatim; see PORTING.md fidelity rules.

Source§

fn ordinal_float_entry(&self, value: &FloatValue) -> Result<String>

to_ordinal(float/Decimal): Python’s first line is num = int(number) — truncation toward zero — so 2.5 → “druhý”, -1.5 → “mínus jednaý”, Decimal("1E+2") → “stý”, and the huge e-form floats that make the cardinal path raise ValueError (1e+16) convert cleanly here (“deset biliardý”). The except (ValueError, TypeError) rescue is unreachable for a finite float/Decimal; int(inf)’s OverflowError and int(nan)’s ValueError are modelled for completeness.

Source§

fn str_to_number(&self, s: &str) -> Result<ParsedNumber>

str_to_number stays Base’s Decimal(value), but CS’s to_cardinal then runs int() over the dot-free str() form, so "Infinity" raises ValueError (int('Infinity')) rather than the shared Inf sentinel’s OverflowError.

Source§

fn to_cardinal_float( &self, value: &FloatValue, _precision_override: Option<u32>, ) -> Result<String>

Port of the non-integer path of Num2Word_CS.to_cardinal.

CS overrides to_cardinal outright and handles floats/Decimals inline off the string form, never through Num2Word_Base.to_cardinal_float and never through float2tuple. So this override does NOT call the shared floatpath code: it rebuilds n = str(number) exactly (python_repr_f64 for a float, python_str_decimal for a Decimal — the same two reconstructors the currency notes describe) and then runs the Python algorithm character by character:

n = str(number).replace(",", ".")
if "." in n:
    is_negative = n.startswith("-")
    abs_n = n[1:] if is_negative else n
    left, right = abs_n.split(".")
    right = right.rstrip("0") or "0"     # '1.50' and 1.50 → 'pět'; '1.00' → 'nula'
    decimal_part = " ".join(ZERO[0] if d == "0" else ONES[int(d)][0] for d in right)
    result = "%s %s %s" % (self._int2word(int(left)), self.pointword, decimal_part)
    if is_negative: result = self.negword + " " + result
    return result
else:
    is_negative = n.startswith("-")
    if is_negative: return self.negword + " " + self._int2word(int(n[1:]))
    else:           return self._int2word(int(n))

Consequences reproduced verbatim:

  • The f64-artefact trap does not apply here: CS reads the shortest- round-trip repr string, not abs(value-pre)*10**precision. 2.675 reads its digits straight off "2.675" → “dva čárka šest sedm pět”; 1.005 off "1.005" → “jedna čárka nula nula pět”.
  • precision / precision_override are ignored. CS’s Python to_cardinal takes no precision kwarg and never reads self.precision, so the precision= override the dispatcher stashes on the converter is dead for CS. The parameter is accepted and dropped.
  • Trailing zeros are stripped from the fraction (issue #75), an all- zero fraction collapses to a single “nula”: Decimal('1.10') → “jedna čárka jedna”, 1.0 → “jedna čárka nula”.
  • A repr/str with no “.” (scientific notation, inf, nan) takes the else arm and feeds a non-decimal token to int(), which raises ValueError — reproduced via [parse_int_token]. 1e-05, 1e+16, Decimal('1E-7'), inf, nan all raise, matching the interpreter. An integral Decimal like Decimal('5') prints "5" and the else arm returns “pět”; Decimal('-3') returns “mínus tři”.
  • A “.” repr that also carries an 'e' (e.g. 1.5e-05 → "1.5e-05") enters the decimal arm and hits the 'e' while spelling the fractional digits → int('e') ValueError, same as Python.

negword is used unstripped (self.negword + " " + result), exactly as the Python source does; “mínus” has no surrounding whitespace so the bytes are identical.

Source§

fn pluralize(&self, n: &BigInt, forms: &[String]) -> Result<String>

Port of Num2Word_CS.pluralize(n, forms).

Python indexes the tuple directly, so a form list shorter than the selected index raises IndexError. Every CS entry has three forms, so that is unreachable — but it is mapped to Index rather than panicking so the exception type survives if the table ever changes.

Reached only from Num2Word_Base.to_currency’s float path; CS’s own int path pointedly does not call this (see to_currency).

Source§

fn to_currency( &self, val: &CurrencyValue, currency: &str, cents: bool, separator: Option<&str>, adjective: bool, ) -> Result<String>

Port of Num2Word_CS.to_currency.

CS intercepts isinstance(val, int) — a true Python int, never a whole float — and hands everything else to Num2Word_Base.to_currency. The split is why currency:USD of 1 is “jedna dolar” (no cents) while 1.0 is “jedna dolar, nula centů”.

§The int path’s plural bug, reproduced

Python picks the currency word by hand here instead of calling self.pluralize:

if abs_val == 1:
    currency_str = cr1[0]
else:
    currency_str = cr1[1] if len(cr1) > 1 else cr1[0]

So every count other than 1 takes cr1[1], the paucal (2-4) form, including 0, 5+ and the teens — where pluralize would correctly pick cr1[2]. The corpus locks the wrong answers in: currency:USD of 0 is “nula dolary”, of 100 is “sto dolary”, of 1000000 is “milion dolary” — all should be “dolarů”, and the float path one line below does say “dolarů” for the same magnitudes (“nula dolarů, padesát centů” at 0.5). EUR hides the bug entirely because its three forms are identical. Do not “fix” this into a pluralize call.

abs(val) is taken before the comparison, so -1 is singular too: “mínus jedna dolar”.

Source§

fn cardinal_float_entry( &self, value: &FloatValue, precision_override: Option<u32>, ) -> Result<String>

to_cardinal(float/Decimal) — the full entry, whole values included.
Source§

fn negword(&self) -> &str

Source§

fn pointword(&self) -> &str

Source§

fn lang_name(&self) -> &str

Class name, for the 'X' not implemented for 'Num2Word_Y' message.
Source§

fn currency_forms(&self, code: &str) -> Option<&CurrencyForms>

CURRENCY_FORMS[code]. None -> NotImplementedError, as in Python.
Source§

fn cards(&self) -> &Cards

Source§

fn maxval(&self) -> &BigInt

Source§

fn is_title(&self) -> bool

Source§

fn exclude_title(&self) -> &[String]

Source§

fn merge(&self, _l: (&str, &BigInt), _r: (&str, &BigInt)) -> (String, BigInt)

merge is abstract in Python (raise NotImplementedError). Languages that override to_cardinal never reach it.
Source§

fn title(&self, value: &str) -> String

Source§

fn to_ordinal_num(&self, value: &BigInt) -> Result<String>

Source§

fn to_year(&self, value: &BigInt) -> Result<String>

Source§

fn currency_adjective(&self, _code: &str) -> Option<&str>

CURRENCY_ADJECTIVES[code].
Source§

fn currency_precision(&self, _code: &str) -> i64

CURRENCY_PRECISION.get(code, 100) — subunits per unit. 1000 for 3-decimal currencies (BHD/KWD/…), 1 for no-subunit currencies.
Source§

fn money_verbose(&self, number: &BigInt, _currency: &str) -> Result<String>

Source§

fn cents_verbose(&self, number: &BigInt, _currency: &str) -> Result<String>

Source§

fn cents_terse(&self, number: &BigInt, currency: &str) -> Result<String>

Source§

fn cardinal_from_decimal(&self, value: &BigDecimal) -> Result<String>

Render a non-integral value, for the fractional-cents branch. Python reaches this as self.to_cardinal(float(right)), i.e. through the float path, so the default routes there rather than raising.
Source§

fn default_adjective(&self) -> bool

This language’s own to_currency(adjective=...) default. Base’s is False; only Mongolian defaults to True.
Source§

fn to_cheque(&self, val: &BigDecimal, currency: &str) -> Result<String>

Source§

fn to_fraction( &self, numerator: &BigInt, denominator: &BigInt, ) -> Result<String>

Num2Word_Base.to_fraction (issue #584). EN/DE/ES/FR/IT/PT and the aero profiles override with idiomatic forms (half/quarter/Drittel).
Source§

fn ordinal_num_float_entry( &self, _value: &FloatValue, repr_str: &str, ) -> Result<String>

to_ordinal_num(float/Decimal). Base returns the value unchanged and the dispatcher str()s it, so the default echoes the Python repr the binding computed.
Source§

fn year_float_entry(&self, value: &FloatValue) -> Result<String>

to_year(float/Decimal). Base’s to_year is to_cardinal.
Source§

fn cardinal_with_pointword( &self, _value: &FloatValue, _pointword: &str, _precision_override: Option<u32>, ) -> Result<String>

The pt_BR ‘ponto’ rendering: to_cardinal(value) with the pointword swapped for this one call. Only reachable through ParsedNumber::DecPoint, so only PT_BR implements it.
Source§

fn to_cardinal_kw(&self, value: &BigInt, kw: &Kwargs) -> Result<String>

Source§

fn to_ordinal_kw(&self, value: &BigInt, kw: &Kwargs) -> Result<String>

Source§

fn to_ordinal_num_kw(&self, value: &BigInt, kw: &Kwargs) -> Result<String>

Source§

fn to_year_kw(&self, value: &BigInt, kw: &Kwargs) -> Result<String>

Source§

fn to_currency_kw( &self, val: &CurrencyValue, currency: &str, cents: bool, separator: Option<&str>, adjective: bool, kw: &Kwargs, ) -> Result<String>

Source§

fn to_cardinal_float_kw( &self, value: &FloatValue, precision_override: Option<u32>, kw: &Kwargs, ) -> Result<String>

Source§

fn es_currency_ordinal_fires(&self) -> bool

Spanish “1ro” currency: does the stashed ordinal fire? Num2Word_ES apocopates 1 → “un euro” in to_currency, bypassing to_cardinal, so the stash never fires (false, the default). The regional es_XX classes inherit Base.to_currency, whose _money_verbose calls to_cardinal(1) → the stash fires → “primero córdoba” (true).
Source§

fn neg_zero_decimal(&self, _to: &str) -> Option<Result<String>>

Render Decimal('-0.0') for mode to, which BigDecimal cannot represent (it has no signed zero). None — the default — means the value coincides with float -0.0, so the binding’s Float{-0.0} demotion is exact. The ~10 languages that render the Decimal form differently (ce/cy “dim”/“ноль” via the integer path, pl its float grammar with the negword, rm a TypeError) override this to serve it natively instead of leaning on a Python fallback.
Source§

fn inf_result(&self, _negative: bool, _to: &str) -> Result<String>

str_to_number produced Decimal('Infinity') / -Infinity. Base’s integer path does int(Decimal('Infinity')) → OverflowError. The many self-contained converters that feed the raw token to int("Infinity") get ValueError instead and override this. to is the requested mode.
Source§

fn nan_result(&self, _to: &str) -> Result<String>

str_to_number produced Decimal('NaN'). Base’s int(NaN) raises ValueError (caught into the float path, which raises ValueError again). Languages whose parse raises decimal.InvalidOperation first override.
Source§

fn python_maxval(&self) -> Option<BigInt>

Python’s getattr(converter, "MAXVAL", None) — the maxval() API. Engine languages get it from their card table (Base sets MAXVAL = 1000 * top_card); self-contained ones mostly lack the attribute (None). The zero sentinel in maxval() means “unset”.

Auto Trait Implementations§

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<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.