Skip to content

Commit 6228a77

Browse files
committed
json case study
1 parent c5b5890 commit 6228a77

File tree

3 files changed

+96
-0
lines changed

3 files changed

+96
-0
lines changed

src/Lean/Data/Fmt.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ prelude
1010
public import Lean.Data.Fmt.Basic
1111
public import Lean.Data.Fmt.Formatter
1212
public import Lean.Data.Fmt.LawfulCost
13+
public import Lean.Data.Fmt.Json

src/Lean/Data/Fmt/Basic.lean

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,20 @@ def Doc.joinUsing (sep : Doc) (ds : Array Doc) : Doc :=
512512
| some d =>
513513
ds[1:].foldl (init := d) fun acc d => acc.append sep |>.append d
514514

515+
/--
516+
Appends multiple documents with a separator document between each pair of adjacent documents with
517+
optional newlines between them.
518+
-/
519+
def Doc.fillUsing (sep : Doc) (ds : Array Doc) : Doc := Id.run do
520+
let some hd := ds[0]?
521+
| return .text ""
522+
let mut r : Doc := hd
523+
for d in ds do
524+
r := Doc.either
525+
(Doc.join #[r, sep, d])
526+
(Doc.join #[r, sep, .hardNl, d])
527+
return r
528+
515529
instance : Append Doc where
516530
append d1 d2 := d1.append d2
517531

src/Lean/Data/Fmt/Json.lean

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/-
2+
Copyright (c) 2025 Lean FRO. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
5+
Author: Marc Huisinga
6+
-/
7+
module
8+
9+
prelude
10+
public import Lean.Data.Fmt.Formatter
11+
public import Lean.Data.Json
12+
13+
public section
14+
15+
namespace Lean.Fmt.Json
16+
17+
def isPrimitive (j : Json) : Bool :=
18+
match j with
19+
| .arr .. => false
20+
| .obj .. => false
21+
| _ => true
22+
23+
partial def format (j : Json) : Doc :=
24+
match j with
25+
| .null => .text "null"
26+
| .bool b => .text (toString b)
27+
| .num n => .text (toString n)
28+
| .str s => .join #[.text "\"", .text s, .text "\""]
29+
| .arr a =>
30+
let elems := a.map format
31+
if a.all isPrimitive then
32+
.join #[
33+
.text "[",
34+
.aligned
35+
(.fillUsing (.text ", ") elems),
36+
.text "]"
37+
]
38+
else
39+
.join #[
40+
.text "[",
41+
.indented 2
42+
(.append
43+
.hardNl
44+
(.joinUsing
45+
(.append (.text ",") .hardNl)
46+
elems)),
47+
.hardNl,
48+
.text "]"
49+
]
50+
| .obj kv =>
51+
let pairs := kv.toArray.map fun (k, v) => formatKvPair k v
52+
.join #[
53+
.text "{",
54+
.indented 2
55+
(.append
56+
.hardNl
57+
(.joinUsing
58+
(.append (.text ",") .hardNl)
59+
pairs)),
60+
.hardNl,
61+
.text "}"
62+
]
63+
where
64+
formatKvPair (k : String) (v : Json) : Doc :=
65+
let v' := format v
66+
let f1 := .join #[
67+
.text "\"",
68+
.text k,
69+
.text "\": ",
70+
v'
71+
]
72+
if isPrimitive v then
73+
let f2 := .join #[
74+
.text "\"",
75+
.text k,
76+
.text "\":",
77+
.indented 2 (.append .hardNl v')
78+
]
79+
.either f1 f2
80+
else
81+
f1

0 commit comments

Comments
 (0)