Skip to content

Commit c9c94ed

Browse files
committed
make JSON representation more flexible for loading from parser
1 parent b9d09f7 commit c9c94ed

File tree

2 files changed

+77
-42
lines changed

2 files changed

+77
-42
lines changed

model/src/ProtoVoices/Folding.purs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ reductionToLeftmost { reduction, piece } = do
374374
-- -------------------------------------------
375375
--
376376
leftmostToReduction
377-
:: Array { trans :: { id :: TransId, edges :: { regular :: Array Edge, passing :: Array Edge }, is2nd :: Boolean }, rslice :: { id :: SliceId, notes :: StartStop (Array Note) } }
377+
:: Array { trans :: { id :: TransId, edges :: { regular :: Array Edge, passing :: Array Edge } }, rslice :: { id :: SliceId, notes :: StartStop (Array Note) } }
378378
-> Array (Leftmost SplitOp FreezeOp HoriOp)
379379
-> Either String { piece :: Piece, reduction :: Reduction }
380380
leftmostToReduction topSegments deriv = do

model/src/ProtoVoices/JSONTransport.purs

Lines changed: 76 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ module ProtoVoices.JSONTransport where
22

33
import Prelude
44

5+
import Control.Monad.State as ST
56
import Data.Array (fromFoldable, mapWithIndex)
67
import Data.Array as A
78
import Data.Bifunctor (lmap)
89
import Data.Either (Either(..), either)
910
import Data.Int as Int
1011
import Data.Map as M
11-
import Data.Maybe (Maybe(..), maybe)
12+
import Data.Maybe (Maybe(..), fromMaybe, maybe)
1213
import Data.Pitches (parseNotation)
1314
import Data.Set as S
1415
import Data.Traversable (for, sequence, traverse)
@@ -42,13 +43,12 @@ type ModelJSON =
4243
}
4344

4445
type TransitionJSON =
45-
{ id :: TransId
46+
{ id :: Maybe TransId
4647
, edges :: EdgesJSON
47-
, is2nd :: Boolean
4848
}
4949

5050
type SliceJSON =
51-
{ id :: SliceId
51+
{ id :: Maybe SliceId
5252
, notes :: StartStop (Array Note)
5353
}
5454

@@ -65,20 +65,20 @@ type LeftmostJSON = Variant
6565

6666
type FreezeJSON =
6767
{ ties :: Array Edge
68-
, prevTime :: String
68+
, prevTime :: Maybe String
6969
}
7070

7171
type SplitJSON =
7272
{ regular :: Array { parent :: Edge, children :: Array { child :: Note, orn :: Maybe String } }
7373
, passing :: Array { parent :: Edge, children :: Array { child :: Note, orn :: Maybe String } }
7474
, fromLeft :: Array { parent :: Note, children :: Array { child :: Note, orn :: Maybe String } }
7575
, fromRight :: Array { parent :: Note, children :: Array { child :: Note, orn :: Maybe String } }
76-
, unexplained :: Array Note
76+
, unexplained :: Maybe (Array Note)
7777
, keepLeft :: Array Edge
7878
, keepRight :: Array Edge
7979
, passLeft :: Array Edge
8080
, passRight :: Array Edge
81-
, ids :: { left :: TransId, slice :: SliceId, right :: TransId }
81+
, ids :: Maybe { left :: TransId, slice :: SliceId, right :: TransId }
8282
}
8383

8484
type HoriJSON =
@@ -96,15 +96,16 @@ type HoriJSON =
9696
}
9797
)
9898
}
99-
, unexplained :: { left :: Array Note, right :: Array Note }
99+
, unexplained :: Maybe { left :: Array Note, right :: Array Note }
100100
, midEdges :: EdgesJSON
101101
, ids ::
102-
{ left :: TransId
103-
, lslice :: SliceId
104-
, mid :: TransId
105-
, rslice :: SliceId
106-
, right :: TransId
107-
}
102+
Maybe
103+
{ left :: TransId
104+
, lslice :: SliceId
105+
, mid :: TransId
106+
, rslice :: SliceId
107+
, right :: TransId
108+
}
108109
}
109110

110111
type StylesJSON =
@@ -133,9 +134,9 @@ modelToJSON model = do
133134
, styles: Just $ stylesToJSON model.styles
134135
}
135136
where
136-
sliceToJSON { id, notes } = { id, notes: map _.note <$> notes }
137+
sliceToJSON { id, notes } = { id: Just id, notes: map _.note <$> notes }
137138

138-
transToJSON t = t { edges = edgesToJSON t.edges }
139+
transToJSON { edges, id } = { edges: edgesToJSON edges, id: Just id }
139140

140141
stylesToJSON :: Styles -> StylesJSON
141142
stylesToJSON { notes, edges, slices, transitions, css, staff } =
@@ -169,20 +170,20 @@ leftmostToJSON = case _ of
169170
LMHorizontalize h -> inj (Proxy :: Proxy "hori") $ horiToJSON h
170171

171172
freezeToJSON :: FreezeOp -> FreezeJSON
172-
freezeToJSON (FreezeOp { ties, prevTime }) = { ties, prevTime: either identity show prevTime }
173+
freezeToJSON (FreezeOp { ties, prevTime }) = { ties, prevTime: Just $ either identity show prevTime }
173174

174175
splitToJSON :: SplitOp -> SplitJSON
175176
splitToJSON (SplitOp split@{ unexplained, keepLeft, keepRight, passLeft, passRight, ids }) =
176177
{ regular: unwrap regToJSON <$> M.toUnfoldable split.regular
177178
, passing: unwrap (map show) <$> M.toUnfoldable split.passing
178179
, fromLeft: unwrap (map show) <$> M.toUnfoldable split.fromLeft
179180
, fromRight: unwrap (map show) <$> M.toUnfoldable split.fromRight
180-
, unexplained
181+
, unexplained: Just unexplained
181182
, keepLeft
182183
, keepRight
183184
, passLeft
184185
, passRight
185-
, ids
186+
, ids: Just ids
186187
}
187188
where
188189
unwrap
@@ -203,8 +204,8 @@ horiToJSON :: HoriOp -> HoriJSON
203204
horiToJSON (HoriOp { midEdges, children, ids, unexplained }) =
204205
{ midEdges: edgesToJSON midEdges
205206
, children: childToJSON <$> M.toUnfoldable children
206-
, ids
207-
, unexplained
207+
, ids: Just ids
208+
, unexplained: Just unexplained
208209
}
209210
where
210211
childToJSON (Tuple parent dist) =
@@ -232,39 +233,64 @@ pieceFromJSON piece =
232233
(\p -> { hold: note.hold, note: { pitch: p, id: note.id } }) <$> parseNotation note.pitch
233234
pure { time: parseTime slice.time, notes: sortNotes notes }
234235

236+
newTId :: forall m. (Monad m) => ST.StateT { nextS :: Int, nextT :: Int } m TransId
237+
newTId = do
238+
{ nextT, nextS } <- ST.get
239+
ST.put { nextT: nextT + 1, nextS }
240+
pure $ TransId nextT
241+
242+
newSId :: forall m. (Monad m) => ST.StateT { nextS :: Int, nextT :: Int } m SliceId
243+
newSId = do
244+
{ nextT, nextS } <- ST.get
245+
ST.put { nextT, nextS: nextS + 1 }
246+
pure $ SliceId nextS
247+
235248
modelFromJSON :: ModelJSON -> Either String Model
236-
modelFromJSON { topSegments, derivation, styles } = do
237-
deriv <- sequence $ leftmostFromJSON <$> derivation
238-
{ piece, reduction } <- leftmostToReduction topSegments deriv
239-
parsedStyles <- maybe (pure emptyStyles) stylesFromJSON styles
249+
modelFromJSON { topSegments, derivation, styles } = flip ST.evalStateT { nextS: 1, nextT: 0 } $ do
250+
deriv <- (sequence $ leftmostFromJSON <$> derivation)
251+
topSegments' <- sequence $ addSliceId <$> topSegments
252+
{ piece, reduction } <- ST.lift $ leftmostToReduction topSegments' deriv
253+
parsedStyles <- ST.lift $ maybe (pure emptyStyles) stylesFromJSON styles
240254
pure { piece, reduction, styles: parsedStyles }
255+
where
256+
addSliceId { trans, rslice } = do
257+
sid <- maybe newSId pure rslice.id
258+
tid <- maybe newTId pure trans.id
259+
pure $ { trans: trans { id = tid }, rslice: rslice { id = sid } }
241260

242-
leftmostFromJSON :: LeftmostJSON -> Either String (Leftmost SplitOp FreezeOp HoriOp)
261+
leftmostFromJSON :: LeftmostJSON -> ST.StateT { nextS :: Int, nextT :: Int } (Either String) (Leftmost SplitOp FreezeOp HoriOp)
243262
leftmostFromJSON =
244263
case_
245-
# on (Proxy :: Proxy "freezeLeft") (map LMFreezeLeft <<< freezeFromJSON)
246-
# on (Proxy :: Proxy "freezeOnly") (map LMFreezeOnly <<< freezeFromJSON)
247264
# on (Proxy :: Proxy "splitLeft") (map LMSplitLeft <<< splitFromJSON)
248265
# on (Proxy :: Proxy "splitOnly") (map LMSplitOnly <<< splitFromJSON)
249266
# on (Proxy :: Proxy "splitRight") (map LMSplitRight <<< splitFromJSON)
250267
# on (Proxy :: Proxy "hori") (map LMHorizontalize <<< horiFromJSON)
268+
# on (Proxy :: Proxy "freezeLeft") (map LMFreezeLeft <<< ST.lift <<< freezeFromJSON)
269+
# on (Proxy :: Proxy "freezeOnly") (map LMFreezeOnly <<< ST.lift <<< freezeFromJSON)
251270

252271
freezeFromJSON :: FreezeJSON -> Either String FreezeOp
253-
freezeFromJSON { ties, prevTime } = Right $ FreezeOp { ties, prevTime: parseTime prevTime }
254-
255-
splitFromJSON :: SplitJSON -> Either String SplitOp
256-
splitFromJSON json@{ unexplained, keepLeft, keepRight, passLeft, passRight, ids } = do
257-
regular <- M.fromFoldable <$> (sequence $ wrap readDoubleOrnament <$> json.regular)
258-
passing <- M.fromFoldable <$> (sequence $ wrap readPassingOrnament <$> json.passing)
259-
fromLeft <- M.fromFoldable <$> (sequence $ wrap readRightOrnament <$> json.fromLeft)
260-
fromRight <- M.fromFoldable <$> (sequence $ wrap readLeftOrnament <$> json.fromRight)
272+
freezeFromJSON { ties, prevTime } = Right $ FreezeOp { ties, prevTime: maybe (Left "") parseTime prevTime }
273+
274+
splitFromJSON :: SplitJSON -> ST.StateT { nextS :: Int, nextT :: Int } (Either String) SplitOp
275+
splitFromJSON json@{ unexplained, keepLeft, keepRight, passLeft, passRight, ids: idsMaybe } = do
276+
regular <- ST.lift $ M.fromFoldable <$> (sequence $ wrap readDoubleOrnament <$> json.regular)
277+
passing <- ST.lift $ M.fromFoldable <$> (sequence $ wrap readPassingOrnament <$> json.passing)
278+
fromLeft <- ST.lift $ M.fromFoldable <$> (sequence $ wrap readRightOrnament <$> json.fromLeft)
279+
fromRight <- ST.lift $ M.fromFoldable <$> (sequence $ wrap readLeftOrnament <$> json.fromRight)
280+
ids <- case idsMaybe of
281+
Just i -> pure i
282+
Nothing -> do
283+
left <- newTId
284+
slice <- newSId
285+
right <- newTId
286+
pure { left, slice, right }
261287
pure
262288
$ SplitOp
263289
{ regular
264290
, passing
265291
, fromLeft
266292
, fromRight
267-
, unexplained
293+
, unexplained: fromMaybe [] unexplained
268294
, keepLeft
269295
, keepRight
270296
, passLeft
@@ -311,14 +337,23 @@ splitFromJSON json@{ unexplained, keepLeft, keepRight, passLeft, passRight, ids
311337
Just other -> Left $ "Expected left ornament type but got " <> other
312338
Nothing -> Right Nothing
313339

314-
horiFromJSON :: HoriJSON -> Either String HoriOp
315-
horiFromJSON { midEdges, children, ids, unexplained } =
316-
Right
340+
horiFromJSON :: HoriJSON -> ST.StateT { nextS :: Int, nextT :: Int } (Either String) HoriOp
341+
horiFromJSON { midEdges, children, ids: idsMaybe, unexplained } = do
342+
ids <- case idsMaybe of
343+
Just i -> pure i
344+
Nothing -> do
345+
left <- newTId
346+
lslice <- newSId
347+
mid <- newTId
348+
rslice <- newSId
349+
right <- newTId
350+
pure { left, lslice, mid, rslice, right }
351+
pure
317352
$ HoriOp
318353
{ midEdges: { regular: S.fromFoldable midEdges.regular, passing: midEdges.passing }
319354
, children: M.fromFoldable (childFromJSON <$> children)
320355
, ids
321-
, unexplained
356+
, unexplained: fromMaybe { left: [], right: [] } unexplained
322357
}
323358
where
324359
getDist =

0 commit comments

Comments
 (0)