use pretty_lang::Doc;
enum Json {
Null,
Bool(bool),
Number(f64),
Str(String),
Array(Vec<Json>),
Object(Vec<(String, Json)>),
}
fn to_doc(value: &Json) -> Doc {
match value {
Json::Null => Doc::text("null"),
Json::Bool(true) => Doc::text("true"),
Json::Bool(false) => Doc::text("false"),
Json::Number(n) => Doc::text(n.to_string()),
Json::Str(s) => Doc::text(format!("{s:?}")),
Json::Array(items) => {
if items.is_empty() {
return Doc::text("[]");
}
let members = Doc::join(Doc::text(",").append(Doc::line()), items.iter().map(to_doc));
bracket("[", members, "]")
}
Json::Object(members) => {
if members.is_empty() {
return Doc::text("{}");
}
let members = Doc::join(
Doc::text(",").append(Doc::line()),
members.iter().map(|(key, val)| {
Doc::text(format!("{key:?}"))
.append(Doc::text(": "))
.append(to_doc(val))
}),
);
bracket("{", members, "}")
}
}
}
fn bracket(open: &'static str, body: Doc, close: &'static str) -> Doc {
Doc::text(open)
.append(Doc::softline().append(body).nest(2))
.append(Doc::softline())
.append(Doc::text(close))
.group()
}
fn main() {
let value = Json::Object(vec![
("name".into(), Json::Str("pretty-lang".into())),
("version".into(), Json::Str("0.2.0".into())),
("stable".into(), Json::Bool(false)),
(
"keywords".into(),
Json::Array(vec![
Json::Str("formatter".into()),
Json::Str("pretty".into()),
Json::Str("compiler".into()),
]),
),
(
"limits".into(),
Json::Object(vec![
("min".into(), Json::Number(0.0)),
("max".into(), Json::Null),
]),
),
]);
let doc = to_doc(&value);
for width in [120, 40, 20] {
println!("── width {width} {}", "─".repeat(30));
println!("{}\n", doc.render(width));
}
}