Hi,
I’m pleased to announce the first release of scfg on opam.
It provides a library and an executable to work with the scfg configuration file format. (disclaimer: scfg has been created by my good friend @emersion)
Here’s an example of an scfg file taken from the specification:
train "Shinkansen" {
model "E5" {
max-speed 320km/h
weight 453.5t
lines-served "Tōhoku" "Hokkaido"
}
model "E7" {
max-speed 275km/h
weight 540t
lines-served "Hokuriku" "Jōetsu"
}
}
Scfg is a file format designed to be simple and indeed the implementation was really straightforward. I’m planning to use it in small tools I wrote (mostly sway tools written in OCaml) but never released because I couldn’t stand having to use TOML, YAML or JSON for them…
The library provides an executable to validate and pretty-print an scfg file. It’ll indent it properly, remove useless quoting and whitespaces:
$ scfg spec.scfg
train Shinkansen {
model E5 {
max-speed 320km/h
weight 453.5t
lines-served Tōhoku Hokkaido
}
model E7 {
max-speed 275km/h
weight 540t
lines-served Hokuriku Jōetsu
}
}
The library is made of four modules : Types
, Parse
, Pp
and Query
.
The Types
module simply defines the following types, which are all you need to deal with scfg:
(** A directive has a name, a list of parameters and children (a list of directive). *)
type directive =
{ name : string
; params : string list
; children : directive list
}
(** A config is a list of directives. *)
type config = directive list
The others modules can be used as follow:
let file = {|train A-Train {
bla bla bla
}
train "John Col Train" {
tut tut tut
}
|}
(* parsing the file *)
let config =
(* there's also a `Parse.from_file` function that should be more useful *)
match Scfg.Parse.from_string file with
| Error e ->
Format.eprintf "error: %s@." e;
exit 1
| Ok config -> config
(* printing the file *)
let () =
Format.printf "```scfg@.%a@.```@." Scfg.Pp.config config
(* querying the file *)
let () =
(* gets the first directive with the name `train` *)
match Scfg.Query.get_dir "train" config with
| None -> Format.printf "No train found.@."
| Some train -> (
(* get the parameter at index 0 in the `train` directive *)
match Scfg.Query.get_param 0 train with
| Error _e -> Format.printf "Train has no name.@."
| Ok name -> Format.printf "The first train is `%s`.@." name )
For more have a look at the project’s README, the documentation or feel free to ask here !