///|
/// Represent an enum value.
///
/// # Example
///
/// ```
/// let doc = ctor(pkg="pkg", ty="Enum", "Constr", [pretty(1), pretty(2)], labeled={
/// "loc": pretty(100),
/// "name": pretty("cons"),
/// })
/// inspect(
/// doc,
/// content=(
/// #|@pkg.Enum::Constr(1, 2, loc=100, name="cons")
/// ),
/// )
/// let doc = ctor(
/// pkg="pkg",
/// ty="Enum",
/// "LongConstructor",
/// [
/// pretty(100000000),
/// pretty(200000000),
/// pretty(100000000),
/// pretty(200000000),
/// pretty(100000000),
/// pretty(200000000),
/// pretty(100000000),
/// pretty(200000000),
/// ],
/// labeled={ "loc": pretty(100), "name": pretty("cons") },
/// )
/// inspect(
/// doc,
/// content=(
/// #|@pkg.Enum::LongConstructor(
/// #| 100000000,
/// #| 200000000,
/// #| 100000000,
/// #| 200000000,
/// #| 100000000,
/// #| 200000000,
/// #| 100000000,
/// #| 200000000,
/// #| loc=100,
/// #| name="cons",
/// #|)
/// ),
/// )
/// ```
pub fn ctor(
pkg? : String,
ty? : String,
ctor : String,
payloads : Array[Document],
labeled? : Map[String, Document] = {},
) -> Document {
let pkg = match pkg {
None => empty
Some(pkg) => char('@') + text(pkg) + char('.')
}
let ty = match ty {
None => empty
Some(ty) => text(ty + "::")
}
let ctor = text(ctor)
let xs = []
payloads.each(x => xs.push((None, x)))
labeled.each((k, v) => xs.push((Some(k), v)))
let xs = separate_map(char(',') + line, xs, fn(p) {
match p.0 {
None => p.1
Some(name) => text(name) + text("=") + p.1
}
}) +
switch(empty, char(','))
group(pkg + ty + ctor + parens(nest(softline + xs) + softline))
}
///|
/// Represent a struct.
///
/// # Example
///
/// ```
/// let doc = record(pkg="pkg", ty="Struct", {
/// "spos": pretty(1),
/// "epos": pretty(2),
/// "file": pretty("abc"),
/// })
/// inspect(
/// doc,
/// content=(
/// #|@pkg.Struct::{spos: 1, epos: 2, file: "abc"}
/// ),
/// )
/// let doc = record(pkg="pkg", ty="Struct", {
/// "spos": pretty(1000000000),
/// "epos": pretty(2000000000),
/// "file": pretty("abc"),
/// "spos1": pretty(1000000000),
/// "epos1": pretty(2000000000),
/// "file1": pretty("abc"),
/// })
/// inspect(
/// doc,
/// content=(
/// #|@pkg.Struct::{
/// #| spos: 1000000000,
/// #| epos: 2000000000,
/// #| file: "abc",
/// #| spos1: 1000000000,
/// #| epos1: 2000000000,
/// #| file1: "abc",
/// #|}
/// ),
/// )
/// ```
pub fn record(
pkg? : String,
ty? : String,
fields : Map[String, Document],
) -> Document {
let pkg = match pkg {
None => empty
Some(pkg) => text("@" + pkg + ".")
}
let ty = match ty {
None => empty
Some(ty) => text(ty + "::")
}
let fields = separate_map(char(',') + line, fields.to_array(), fn(p) {
text(p.0) + text(":") + space + p.1.pretty()
}) +
switch(empty, char(','))
group(pkg + ty + braces(nest(softline + fields) + softline))
}
///|
/// Represent a tuple.
///
/// # Example
///
/// ```
/// let doc = tuple([pretty(1), pretty('a'), pretty(true)])
/// inspect(doc, content="(1, a, true)")
/// let elem = pretty("very long string")
/// let doc = tuple(Array::make(5, elem))
/// inspect(
/// doc,
/// content=(
/// #|(
/// #| "very long string",
/// #| "very long string",
/// #| "very long string",
/// #| "very long string",
/// #| "very long string",
/// #|)
/// ),
/// )
/// ```
///
pub fn tuple(elems : Array[Document]) -> Document {
let elems_doc = separate_map(char(',') + line, elems, fn(x) { x }) +
switch(empty, char(','))
group(parens(nest(softline + elems_doc) + softline))
}