Skip to main content

FMT

Constant FMT 

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