Skip to content

[TOML] Renderer never renders maps as inline values #61

@archer-321

Description

@archer-321

Context

AFAICT, the current implementation of toml.Renderer has code to render map-like elements as inline tables:
toml.pkl:146

However, the current implementation doesn't seem to use that code, as every type that gets converted to a Map ends up rendering as a regular table.

Suggested change

While inlining small tables generally improves readability, large tables can quickly lead to very long lines if inlined.
To determine whether a table would be small enough to inline, the implementation could

  • define a maximum number of keys above which it generates a regular table instead.
    • This could be too inaccurate, as long values like strings or even nested tables might lead to long inline tables regardless.
  • render any map fully inline and compare it with a maximum line length.
    • This would be accurate, but especially for larger tables, this might lead to performance problems
  • add an annotation that makes the renderer inline the table.
    • If the annotation is specific to pkl.toml, this would force general packages to depend on a rendering-specific package. Moreover, it would be impossible to inline third-party types.

I understand that none of the suggestions above are ideal, but considering no issue exists for this segment of dead code, I opened this issue anyway.

Example

The examples below were generated using pkl.toml@1.0.0, and pkl --version yields 0.26.0-dev+47f161a (I built the native binary locally).

The following example contains a mapping of usernames to the user's UID and GID:

import "package://pkg.pkl-lang.org/pkl-pantry/pkl.toml@1.0.0#/toml.pkl"

output {
    renderer = new toml.Renderer {}
}

users {
    foo {
        uid = 1000
        gid = 1000
    }
    cups {
        uid = 209
        gid = 209
    }
    nobody {
        uid = 65534
        gid = 65534
    }
}

Currently, it produces the following document:

[users.foo]
uid = 1000
gid = 1000

[users.cups]
uid = 209
gid = 209

[users.nobody]
uid = 65534
gid = 65534

However, the same data could be expressed in TOML using inline tables:

[users]
foo = { uid = 1000, gid = 1000 }
cups = { uid = 209, gid = 209 }
nobody = { uid = 65534, gid = 65534 }

While the verbose tables that the current implementation generates are still readable in this basic example, the additional tables quickly become a problem if many small objects are part of another table. For example, the following version renders as five tables and an array of tables (two [[]] tables).

Second example
import "package://pkg.pkl-lang.org/pkl-pantry/pkl.toml@1.0.0#/toml.pkl"

output {
    renderer = new toml.Renderer {}
}


machines = new Listing {
    new {
        hostname = "office"
        users {
            foo {
                uid = 1000
                gid = 1000
            }
            cups {
                uid = 209
                gid = 209
            }
            nobody {
                uid = 65534
                gid = 65534
            }
        }
    }
    new {
        hostname = "server"
        users {
            admin {
                uid = 1000
                gid = 1000
            }
            named {
                uid = 40
                gid = 40
            }
        }
    }
}

This generates:

[[machines]]
hostname = "office"

[machines.users.foo]
uid = 1000
gid = 1000

[machines.users.cups]
uid = 209
gid = 209

[machines.users.nobody]
uid = 65534
gid = 65534

[[machines]]
hostname = "server"

[machines.users.admin]
uid = 1000
gid = 1000

[machines.users.named]
uid = 40
gid = 40

A version using inline tables could represent the same data using two tables and an array of tables or even just the array of tables if the users table is inlined as well (even though that would lead to very long lines).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions