pub const FMT: &str = "//! Padding and fixed-point formatting, as methods on `Int`, `String` and\n//! `Float`.\n//!\n//! `pad` writes an integer padded with zeros, `pad_left` and `pad_right`\n//! align a string with spaces, and `fixed` writes a float with a set number\n//! of decimal places. The padding methods never truncate: a value already as\n//! wide as asked comes back as it is.\n//!\n//! Padding integers and strings to a width, and writing a float to a fixed\n//! number of places:\n//!\n//! ```\n//! assert_eq(7.pad(3), \"007\")\n//! assert_eq((-5).pad(3), \"-05\")\n//! assert_eq(1234.pad(2), \"1234\") // never truncated\n//! assert_eq(\"ab\".pad_left(4), \" ab\")\n//! assert_eq(\"ab\".pad_right(4), \"ab \")\n//! assert_eq((100.0 / 3.0).fixed(2), \"33.33\")\n//! assert_eq((2.5).fixed(0), \"2\") // a tie goes to the even digit\n//!\n//! // A row of a table, in columns of fixed width.\n//! let row = \"${\"apples\".pad_right(8)}|${3.pad(4)}|${(0.5).fixed(2).pad_left(6)}\"\n//! assert_eq(row, \"apples |0003| 0.50\")\n//! ```\n\n// Nova standard library -- formatting.\n//\n// Methods rather than top-level `pub fn`s, and that is not a style choice.\n// Nova has no imports and no qualified paths: every std module\'s public names\n// are glob-imported into every other module, and a collision resolves\n// *silently in the user\'s favour*, so a top-level `pub fn pad` would take\n// `pad` from every Nova program ever written and a program with its own `pad`\n// would lose access to this one with no diagnostic. `std/strings` refused the\n// same trade for `join`; `std/log` refused it for five level names.\n\nimpl Int {\n // Zero-pad to `width`, with the sign counted toward it: `(7).pad(2)` is\n // \"07\" and `(-5).pad(3)` is \"-05\", matching Rust\'s `{:03}`. A value\n // already at or beyond `width` is returned unpadded, never truncated --\n // a formatter that drops digits turns a display concern into a\n // correctness one.\n //\n // The early return is also the negative-width clamp: `len` is at least 1\n // for every Int, so a negative `width` takes that branch and\n // `String::repeat` -- which *panics* on a negative count -- is never\n // reached with one. The upper end of `width` is not clamped at all --\n // an absurdly large one (e.g. `i64::MAX`) reaches `String::repeat` and\n // aborts cleanly with `array length is too large` (measured), guarded\n // by the array-length check at `crates/nova-mir/src/lower.rs:1080-1101`\n // rather than by anything in this function. A documented outcome, not\n // a silent one.\n /// Returns the integer as text, padded on the left with zeros to `width`\n /// characters.\n ///\n /// A negative number\'s minus sign counts toward `width` and stays in\n /// front: `(-5).pad(3)` is `\"-05\"`. A number already `width` characters or\n /// longer comes back without padding, never truncated, as does any number\n /// when `width` is zero or negative.\n pub fn pad(self, width: Int) -> String {\n let s = \"${self}\"\n let len = s.len()\n if len >= width { return s }\n let zeros = \"0\".repeat(width - len)\n if self < 0 {\n let digits = s.slice(1, len)\n \"-${zeros}${digits}\"\n } else {\n \"${zeros}${s}\"\n }\n }\n}\n\nimpl String {\n // Right-align within `width` by padding with spaces on the left. At or\n // beyond `width`, returned unchanged. The early return clamps a negative\n // `width` before `repeat` can see it.\n //\n // `width` is counted in codepoints, as `String::len` counts them, not\n // in display columns: a wide or combining character will not align by\n // column. Measured: `\"\u{65e5}\u{672c}\".pad_right(4)` is `\"\u{65e5}\u{672c} \"` (two spaces),\n // four codepoints wide but six columns in a monospace terminal.\n /// Returns the string right-aligned in `width` characters, with spaces\n /// added on the left.\n ///\n /// `width` counts characters, as `len` does, not columns on a screen, so a\n /// wide character such as `\u{65e5}` counts as one. A string already `width`\n /// characters or longer comes back as it is.\n pub fn pad_left(self, width: Int) -> String {\n let len = self.len()\n if len >= width { return self }\n let fill = \" \".repeat(width - len)\n \"${fill}${self}\"\n }\n\n // Left-align within `width` by padding with spaces on the right. Same\n // codepoint-counted `width` as `pad_left` above.\n /// Returns the string left-aligned in `width` characters, with spaces\n /// added on the right.\n ///\n /// `width` counts characters, as for `pad_left`. A string already `width`\n /// characters or longer comes back as it is.\n pub fn pad_right(self, width: Int) -> String {\n let len = self.len()\n if len >= width { return self }\n let fill = \" \".repeat(width - len)\n \"${self}${fill}\"\n }\n}\n\nimpl Float {\n // Fixed-place decimal: `(100.0 / 3.0).fixed(2)` is \"33.33\".\n //\n // The rendering is done by the runtime, deliberately breaking this\n // project\'s habit of keeping policy in Nova. Decimal rendering of a\n // binary float is a solved problem with sharp edges -- shortest\n // round-trip, ties at the cut -- and Nova cannot begin on it, having no\n // `Float` to `Int` conversion at all. This is the case where the Rust\n // side is the correct implementation rather than the convenient one.\n //\n // `places` is clamped to 0..=17 by the intrinsic.\n /// Returns the number as text with `places` digits after the decimal\n /// point: `(100.0 / 3.0).fixed(2)` is `\"33.33\"`.\n ///\n /// It rounds the float\'s exact binary value to the nearest such text, a\n /// tie going to the even digit, so `(2.5).fixed(0)` is `\"2\"` and\n /// `(1.005).fixed(2)` is `\"1.00\"`, 1.005 being stored as a little less.\n /// A negative number that rounds to zero keeps its sign, as `-0.00`.\n /// `places` is clamped to `0..=17`, and 0 gives no decimal point. It never\n /// uses an exponent, and `NaN` and the infinities give `NaN`, `inf` and\n /// `-inf`.\n pub fn fixed(self, places: Int) -> String { float_fixed(self, places) }\n}\n";Expand description
std/fmt/lib.nova.