This version of the module is deprecated: Superseded by moonbitlang/core/debug, which is part of the standard library: use its Debug trait, derive(Debug), debug_inspect and render instead. This module gets no further updates.

    debug

    experimental
    debug
    diff
    pretty-print
    Download zip
    Version
    0.1.4
    License
    Apache-2.0
    Last updated
    3 days ago
    Downloads
    1K

    #moonbit-community/debug

    An experimental Debug + diff + pretty-printer library for MoonBit. We plan to add this to the standard library when it is more mature.

    It provides:

    • A Debug trait that turns values into a structural Repr
    • A tree-based diff (ReprDelta) with configurable float tolerance
    • A pretty printer for both Repr and ReprDelta (optionally with ANSI marks)
    • A binary to auto-generate Debug implementations for your types

    Goals:

    • A way to debug values and show the diff, with pretty-printing

    • Replacing Some Roles of Show and ToJson

      The current Show trait produces output that is not suitable for debugging, as it lacks indentation and line breaks. The ToJson trait produces JSON, which is more readable with @json.inspect but not ideal for MoonBit-specific types (e.g., enums). It can also confuse users who expect ToJson to produce structured data rather than a debug representation.

      With the introduction of Debug , the Show trait can focus on producing specialized output (such as Json::stringify , String::to_string , etc.), and derive(Show) will be deprecated.

    Non-goals:

    • Deserializing from Repr back to original values
    • Output a valid moonbit code representation

    #Project structure

    The current pre-build command design forces us to separate the build script (written in MoonBit) into its own module and use a local binary dependency to invoke it. Therefore, the project is structured as follows:

    • debug/: the main library module
    • auto_derive/: the build script module that generates Debug implementations
    • auto_derive_example/: an example module that uses the debug library and build script to generate code

    #Quickstart

    Run the small demo:

    moon run cmd/main

    In another package, import this module in moon.pkg.json :

    { "import": [{ "path": "moonbit-community/debug", "alias": "dbg" }] }

    Then call:

    ///|
    fn show_examples {
    println(@dbg.pretty_print([1, 2, 3]))
    println(@dbg.pretty_print_diff(Some(1), Some(2)))
    }

    #Implement Debug for your own types

    Use record , ctor , array , and friends to build a Repr :

    ///|
    struct Person {
    name : String
    age : Int
    }

    ///|
    pub impl @dbg.Debug for Person with fn debug(self) {
    @dbg.record([("name", @dbg.debug(self.name)), ("age", @dbg.debug(self.age))])
    }

    #Auto deriving Debug

    To automatically generate Debug implementations for your types:

    1. add moonbit-community/debug_deriving as a binary dependency in your moon.mod.json

    2. add a pre-build command that runs the debug_deriving binary, for example:

    { "pre-build": [ { "command": "$mod_dir/.mooncakes/moonbit-community/debug_deriving/debug_deriving $input $output", "input": "input.mbt", "output": "output.mbt" } ] }

    1. in your input.mbt, add #debug.derive attribute to your types:

    ///|
    #debugderive
    struct Pos(Int, Int)

    #Options

    All options are passed directly as optional parameters to functions:

    #Pretty printing

    • max_depth?: optional depth limit; omit for default (4), or pass max_depth=n to prune
    • threshold?: controls single-line vs multi-line rendering (default: 8)
    • use_ansi?: enables +/- with ANSI colors in diffs (default: true)

    #Diffing

    • max_relative_error?: float tolerance for comparing Double values

    See docs_test.mbt and examples_test.mbt for runnable, snapshot-based examples.

    #Doctest examples

    ///|
    test {
    inspect(pretty_print([1, 2, 3]), content="[1, 2, 3]")
    inspect(
    pretty_print_diff(1, 2, compact_threshold=100, use_ansi=false),
    content="-1 +2",
    )
    }

    Repr

    Re-export Repr and smart constructors from @repr. Use Repr::int(x), Repr::string(s), etc. to construct values.

    ReprDelta

    Diffing (forwarded to @diff).

    Debug

    pub(open) trait Debug {
    fn debug(Self) ->
    Repr

    }

    Convert a value into a structural Repr for pretty-printing and diffing.

    Once a type implements this trait:
    • debug(x) builds a Repr
    • pretty_print(x, ...), diff(x, ...), and pretty_print_diff(x, ...) work out of the box
    impl Debug for Int16
    impl Debug for Int64
    impl Debug for UInt16
    impl Debug for UInt64
    impl Debug for Float
    impl Debug for Double
    impl Debug for String
    impl Debug for Option[T]
    impl Debug for Result[T, E]
    impl Debug for FixedArray[T]
    impl Debug for ReadOnlyArray[T]
    impl Debug for Bytes
    impl Debug for Array[T]
    impl Debug for Iter2[A, B]
    impl Debug for Map[K, V]
    impl Debug for Tuple2[A, B]
    impl Debug for Tuple3[A, B, C]
    impl Debug for Tuple4[A, B, C, D]
    impl Debug for Tuple5[A, B, C, D, E]
    impl Debug for Tuple6[A, B, C, D, E, F]
    impl Debug for Tuple7[A, B, C, D, E, F, G]
    impl Debug for Tuple8[A, B, C, D, E, F, G, H]
    impl Debug for Tuple9[A, B, C, D, E, F, G, H, I]
    impl Debug for Tuple10[A, B, C, D, E, F, G, H, I, J]
    impl Debug for Tuple11[A, B, C, D, E, F, G, H, I, J, K]
    impl Debug for Tuple12[A, B, C, D, E, F, G, H, I, J, K, L]
    impl Debug for Tuple13[A, B, C, D, E, F, G, H, I, J, K, L, M]
    impl Debug for Tuple14[A, B, C, D, E, F, G, H, I, J, K, L, M, N]
    impl Debug for Tuple15[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O]
    impl Debug for Tuple16[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P]
    impl Debug for Tuple17[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q]
    impl Debug for Tuple18[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R]
    impl Debug for Tuple19[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S]
    impl Debug for Tuple20[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T]
    impl Debug for Tuple21[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U]
    impl Debug for Tuple22[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V]
    impl Debug for BytesView
    impl Debug for StringView

    debug

    Build a Repr for any T that implements Debug.

    diff

    fn[T : Debug] diff(x : T, y : T, max_relative_error? : Double) ->
    ReprDelta

    Diff two values (by diffing their Repr).

    Optional parameters:
    • max_relative_error?: relative-error tolerance used for DoubleLit comparisons. Larger values make floats less likely to be considered different. Defaults to 1e-12 when None.

    diff_repr

    Diff two Repr values.

    Optional parameters:
    • max_relative_error?: relative-error tolerance for DoubleLit.
      • When None, the default is 1e-12.
      • Larger tolerances make floats less likely to be reported as different.

    pretty_print

    fn[T : Debug] pretty_print(x : T, max_depth? : Int, compact_threshold? : Int, use_ansi? : Bool) -> String

    Pretty-print a value.

    Optional parameters:
    • max_depth?: maximum expansion depth; deeper subtrees are replaced with .... Defaults to 4 when None.
    • compact_threshold?: compact-vs-multiline layout threshold. The printer uses a heuristic “size” for nodes; when the structure is deemed small enough under this threshold, it is kept on one line, otherwise it is broken into multiple lines. Larger values prefer single-line output. Defaults to 80 when None.
    • use_ansi?: whether to emit ANSI color escape codes. Defaults to true when None.

    pretty_print_delta

    fn pretty_print_delta(d :
    ReprDelta
    , max_depth? : Int, compact_threshold? : Int, use_ansi? : Bool) -> String

    Pretty-print a ReprDelta.

    Optional parameters:
    • max_depth?: maximum expansion depth; deeper subtrees are folded. Defaults to 4 when None. Values <= 0 are treated as 1.
    • compact_threshold?: compact-vs-multiline layout threshold (heuristic one-line vs multiline). Larger values prefer single-line output. Defaults to 80 when None.
    • use_ansi?: whether to emit ANSI color escape codes (for +/- markers). Defaults to true when None.

    pretty_print_diff

    fn[T : Debug] pretty_print_diff(x : T, y : T, max_depth? : Int, compact_threshold? : Int, use_ansi? : Bool, max_relative_error? : Double) -> String

    Pretty-print the diff between two values.

    Optional parameters:
    • max_depth?: maximum expansion depth; defaults to 4 when None.
    • compact_threshold?: compact-vs-multiline layout threshold (heuristic one-line vs multiline). Larger values prefer single-line output. Defaults to 80 when None.
    • use_ansi?: whether to emit ANSI color escape codes; defaults to true when None.
    • max_relative_error?: float tolerance for DoubleLit; defaults to 1e-12 when None.

    pretty_print_repr

    fn pretty_print_repr(r :
    Repr
    , max_depth? : Int, compact_threshold? : Int, use_ansi? : Bool) -> String

    Pretty-print a Repr.

    Optional parameters:
    • max_depth?: maximum expansion depth; deeper subtrees are replaced with .... Defaults to 4 when None. Values <= 0 are treated as 1.
    • compact_threshold?: compact-vs-multiline layout threshold. The printer uses a heuristic “size” for nodes; when the structure is deemed small enough under this threshold, it is kept on one line, otherwise it is broken into multiple lines. Larger values prefer single-line output. Defaults to 80 when None.
    • use_ansi?: whether to emit ANSI color escape codes. Defaults to true when None.