Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

TOML settings

TOML is a settings format with types: strings, integers, floats, booleans, dates, arrays and nested tables. std/config reads it into a tree of TomlValues, and every question you ask the tree answers a value or nothing, so a missing setting falls back to a default instead of stopping the program.

#import "std/config"
#import "std/fs"

'' A settings file, written here so the example has one to read.
dim scratch as ustring = fs.CreateTempDir( "tbe" ).Value( )
dim path as ustring = fs.PathJoin( scratch, "app.toml" )
fs.WriteAllText( path, """
    name = "tbe"
    retries = 3

    [window]
    size = [ 800, 600 ]
    """ )

var r = config.LoadToml( path )
if r.IsOk( ) = false then
    print r.Failure( ).Message( )
    end 1
end if
dim cfg as config.TomlValue = r.Value( )

'' The value at a path, or an empty one whose As... answers are empty.
function Setting( byref t as config.TomlValue, byref p as ustring ) _
        as config.TomlValue
    return t.Path( p ).ValueOr( config.TomlValue( ) )
end function

print "name:    "; Setting( cfg, "name" ).AsString( ).ValueOr( "" )
print "retries:"; Setting( cfg, "retries" ).AsInt( ).ValueOr( 1 )
print "width:  "; Setting( cfg, "window.size.0" ).AsInt( ).ValueOr( 0 )
print "missing:"; Setting( cfg, "window.dpi" ).AsInt( ).ValueOr( 96 )
print "keys:    "; cfg.KeyAt( 0 ); ", "; cfg.KeyAt( 1 ); ", "; cfg.KeyAt( 2 )

'' A broken file is a value too.
fs.WriteAllText( path, !"retries = 3\nretries = 4\n" )
print "broken:  "; config.LoadToml( path ).Failure( ).Message( )
fs.RemoveDirAll( scratch )

Output

name:    tbe
retries: 3
width:   800
missing: 96
keys:    name, retries, window
broken:  line 2, column 1: duplicate key: 'retries'

LoadToml( path ) reads a file and ParseToml( text ) reads text; both return a Result whose value is the root table. Path( "window.size.0" ) follows keys separated by dots, a number indexing an array, and returns an Optional. AsInt( ), AsString( ), AsBool( ), AsFloat( ) and AsDateTime( ) each return an Optional too, empty when the value is another kind — so Setting plus ValueOr turns "absent" and "wrong type" into the default.

Tables keep their keys in the order the file wrote them: KeyAt( i ) and Keys( ) walk them that way. A file that breaks the rules — the same key twice, a table defined twice, a number too big for 64 bits — fails with a ConfigError naming the line and column.

To change a document, SetKey, Push and RemoveKey edit the tree and config.ToTomlText( root ) writes it back. Comments are not part of the tree, so they do not survive the round trip.

Activities

  1. Change retries = 3 to retries = "3" and see which default is printed.
  2. Add cfg.SetKey( "retries", config.TomlValue.FromInt( 5 ) ) and print config.ToTomlText( cfg ).Value( ).