Skip to content
This repository was archived by the owner on Jun 15, 2023. It is now read-only.

Commit 26727a6

Browse files
committed
Add a cursor for EJson
1 parent b9788c3 commit 26727a6

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

src/Data/Json/Extended/Cursor.purs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
module Data.Json.Extended.Cursor where
2+
3+
import Prelude
4+
5+
import Data.Array as A
6+
import Data.Bifunctor (lmap)
7+
import Data.Eq (class Eq1)
8+
import Data.Functor.Mu (Mu, roll, unroll)
9+
import Data.Json.Extended (EJson)
10+
import Data.Json.Extended as EJ
11+
import Data.Maybe (Maybe(..), maybe)
12+
import Data.Ord (class Ord1)
13+
import Data.Tuple (Tuple(..), lookup)
14+
15+
import Matryoshka (Algebra, cata)
16+
17+
data CursorF a
18+
= All
19+
| AtKey EJson a
20+
| AtIndex Int a
21+
22+
derive instance functorCursorFFunctor CursorF
23+
derive instance eqCursorEq a Eq (CursorF a)
24+
derive instance ordCursorOrd a Ord (CursorF a)
25+
26+
instance eq1CursorFEq1 CursorF where
27+
eq1 = eq
28+
29+
instance ord1CursorFOrd1 CursorF where
30+
compare1 = compare
31+
32+
instance showCursorFShow a => Show (CursorF a) where
33+
show = case _ of
34+
All"All"
35+
AtKey k a → "(AtKey " <> show k <> " " <> show a <> ")"
36+
AtIndex i a → "(AtIndex " <> show i <> " " <> show a <> ")"
37+
38+
type Cursor = Mu CursorF
39+
40+
all Cursor
41+
all = roll All
42+
43+
atKey EJ.EJson Cursor Cursor
44+
atKey k = roll <<< AtKey k
45+
46+
atIndex Int Cursor Cursor
47+
atIndex i = roll <<< AtIndex i
48+
49+
peel Cursor Maybe (Tuple Cursor Cursor)
50+
peel c = case unroll c of
51+
AllNothing
52+
AtKey k rest → Just $ Tuple (atKey k all) rest
53+
AtIndex i rest → Just $ Tuple (atIndex i all) rest
54+
55+
get Cursor EJson Maybe EJson
56+
get = cata go
57+
where
58+
go :: Algebra CursorF (EJson -> Maybe EJson)
59+
go = case _ of
60+
AllJust
61+
AtKey k prior → getKey k <=< prior
62+
AtIndex i prior → getIndex i <=< prior
63+
64+
set Cursor EJson EJson Maybe EJson
65+
set cur x v = case lmap unroll <$> peel cur of
66+
NothingJust x
67+
Just (Tuple All _) → Just x
68+
Just (Tuple (AtKey k _) path) → setKey k x <$> get path v
69+
Just (Tuple (AtIndex i _) path) → setIndex i x <$> get path v
70+
71+
getKey EJ.EJson EJ.EJson Maybe EJ.EJson
72+
getKey k v = case EJ.head v of
73+
EJ.Map fields → EJ.EJson <$> lookup (EJ.getEJson k) fields
74+
_ → Nothing
75+
76+
setKey EJ.EJson EJ.EJson EJ.EJson EJ.EJson
77+
setKey k (EJ.EJson x) v = case EJ.head v of
78+
EJ.Map fields →
79+
EJ.EJson <<< roll <<< EJ.Map $ map
80+
(\(kv@(Tuple k v)) → if k == k then Tuple k x else kv) fields
81+
_ → v
82+
83+
getIndex Int EJ.EJson Maybe EJ.EJson
84+
getIndex i v = case EJ.head v of
85+
EJ.Array items → EJ.EJson <$> A.index items i
86+
_ → Nothing
87+
88+
setIndex Int EJ.EJson EJ.EJson EJ.EJson
89+
setIndex i (EJ.EJson x) v = case EJ.head v of
90+
EJ.Array items →
91+
maybe v (EJ.EJson <<< roll <<< EJ.Array) $ A.updateAt i x items
92+
_ → v

0 commit comments

Comments
 (0)