Skip to content

Commit aeb6450

Browse files
committed
Refactor Huddle to sort all items together
We want to handle ordering and grouping in Huddle better, so we collect a single list of items rather than collating them by type. This is in preparation for allowing other sort orders.
1 parent 609bf9c commit aeb6450

File tree

1 file changed

+37
-38
lines changed

1 file changed

+37
-38
lines changed

src/Codec/CBOR/Cuddle/Huddle.hs

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
module Codec.CBOR.Cuddle.Huddle
1818
( -- * Core Types
1919
Huddle,
20+
HuddleItem (..),
2021
Rule,
2122
Named,
2223
IsType0 (..),
@@ -70,14 +71,17 @@ module Codec.CBOR.Cuddle.Huddle
7071
tag,
7172

7273
-- * Generics
74+
GRef,
75+
GRuleDef,
7376
GRuleCall,
7477
binding,
7578
binding2,
79+
callToDef,
7680

7781
-- * Conversion to CDDL
7882
collectFrom,
7983
toCDDL,
80-
toCDDLNoRoot
84+
toCDDLNoRoot,
8185
)
8286
where
8387

@@ -93,12 +97,12 @@ import Data.List.NonEmpty qualified as NE
9397
import Data.Map.Strict qualified as HaskMap
9498
import Data.String (IsString (fromString))
9599
import Data.Text qualified as T
96-
import Data.Tuple.Optics (Field1 (..), Field2 (..), Field3 (..))
100+
import Data.Tuple.Optics (Field2 (..))
97101
import Data.Void (Void)
98102
import Data.Word (Word64)
99103
import GHC.Exts (IsList (Item, fromList, toList))
100104
import GHC.Generics (Generic)
101-
import Optics.Core (over, view, (%~), (&), (.~))
105+
import Optics.Core (view, (%~), (&), (.~))
102106
import Prelude hiding ((/))
103107

104108
data Named a = Named
@@ -117,23 +121,22 @@ instance Show (Named a) where
117121

118122
type Rule = Named Type0
119123

124+
data HuddleItem
125+
= HIRule Rule
126+
| HIGRule GRuleDef
127+
| HIGroup (Named Group)
128+
deriving (Generic, Show)
129+
120130
-- | Top-level Huddle type is a list of rules.
121131
data Huddle = Huddle
122132
{ -- | Root elements
123133
roots :: [Rule],
124-
rules :: NE.NonEmpty Rule,
125-
groups :: [Named Group],
126-
gRules :: [GRuleDef]
134+
items :: [HuddleItem]
127135
}
128136
deriving (Generic, Show)
129137

130-
-- | This instance is mostly used for testing
131-
instance IsList Huddle where
132-
type Item Huddle = Rule
133-
fromList [] = error "Huddle: Cannot have empty ruleset"
134-
fromList (x : xs) = Huddle mempty (x NE.:| xs) mempty mempty
135-
136-
toList = NE.toList . rules
138+
instance Default Huddle where
139+
def = Huddle [] []
137140

138141
data Choice a
139142
= NoChoice a
@@ -826,19 +829,17 @@ collectFrom topRs =
826829
toHuddle $
827830
execState
828831
(traverse goRule topRs)
829-
(HaskMap.empty, HaskMap.empty, HaskMap.empty)
832+
HaskMap.empty
830833
where
831-
toHuddle (rules, groups, gRules) =
834+
toHuddle items =
832835
Huddle
833836
{ roots = topRs,
834-
rules = NE.fromList $ view _2 <$> HaskMap.toList rules,
835-
groups = view _2 <$> HaskMap.toList groups,
836-
gRules = view _2 <$> HaskMap.toList gRules
837+
items = view _2 <$> HaskMap.toList items
837838
}
838839
goRule r@(Named n t0 _) = do
839-
(rules, _, _) <- get
840-
when (HaskMap.notMember n rules) $ do
841-
modify (over _1 $ HaskMap.insert n r)
840+
items <- get
841+
when (HaskMap.notMember n items) $ do
842+
modify (HaskMap.insert n (HIRule r))
842843
goT0 t0
843844
goChoice f (NoChoice x) = f x
844845
goChoice f (ChoiceOf x xs) = f x >> goChoice f xs
@@ -848,14 +849,14 @@ collectFrom topRs =
848849
goT2 (T2Tagged (Tagged _ t0)) = goT0 t0
849850
goT2 (T2Ref n) = goRule n
850851
goT2 (T2Group r@(Named n g _)) = do
851-
(_, groups, _) <- get
852-
when (HaskMap.notMember n groups) $ do
853-
modify (over _2 $ HaskMap.insert n r)
852+
items <- get
853+
when (HaskMap.notMember n items) $ do
854+
modify (HaskMap.insert n (HIGroup r))
854855
goGroup g
855856
goT2 (T2Generic r@(Named n g _)) = do
856-
(_, _, gRules) <- get
857-
when (HaskMap.notMember n gRules) $ do
858-
modify (over _3 $ HaskMap.insert n (fmap callToDef r))
857+
items <- get
858+
when (HaskMap.notMember n items) $ do
859+
modify (HaskMap.insert n (HIGRule $ fmap callToDef r))
859860
goT0 (body g)
860861
-- Note that the parameters here may be different, so this doesn't live
861862
-- under the guard
@@ -872,13 +873,14 @@ collectFrom topRs =
872873
--------------------------------------------------------------------------------
873874
-- Conversion to CDDL
874875
--------------------------------------------------------------------------------
875-
-- | Convert from Huddle to CDDL, generating a top level root element.
876-
toCDDL :: Huddle -> CDDL
876+
877+
-- | Convert from Huddle to CDDL, generating a top level root element.
878+
toCDDL :: Huddle -> CDDL
877879
toCDDL = toCDDL' True
878880

879881
-- | Convert from Huddle to CDDL, skipping a root element.
880-
toCDDLNoRoot :: Huddle -> CDDL
881-
toCDDLNoRoot = toCDDL' False
882+
toCDDLNoRoot :: Huddle -> CDDL
883+
toCDDLNoRoot = toCDDL' False
882884

883885
-- | Convert from Huddle to CDDL for the purpose of pretty-printing.
884886
toCDDL' :: Bool -> Huddle -> CDDL
@@ -888,19 +890,16 @@ toCDDL' mkPseudoRoot hdl =
888890
then (toTopLevelPseudoRoot (roots hdl) NE.<|)
889891
else id
890892
)
891-
$ fmap toCDDLRule (rules hdl)
892-
`appendList` fmap toCDDLGroup (groups hdl)
893-
`appendList` fmap toGenRuleDef (gRules hdl)
893+
$ fmap toCDDLItem (NE.fromList $ items hdl)
894894
where
895+
toCDDLItem (HIRule r) = toCDDLRule r
896+
toCDDLItem (HIGroup g) = toCDDLGroup g
897+
toCDDLItem (HIGRule g) = toGenRuleDef g
895898
toTopLevelPseudoRoot :: [Rule] -> C.WithComments C.Rule
896899
toTopLevelPseudoRoot topRs =
897900
toCDDLRule $
898901
comment "Pseudo-rule introduced by Cuddle to collect root elements" $
899902
"huddle_root_defs" =:= arr (fromList (fmap a topRs))
900-
-- This function is missing from NonEmpty prior to 4.16, so we temporarily
901-
-- add it here.
902-
appendList :: NE.NonEmpty a -> [a] -> NE.NonEmpty a
903-
appendList (x NE.:| xs) ys = x NE.:| xs <> ys
904903
toCDDLRule :: Rule -> C.WithComments C.Rule
905904
toCDDLRule (Named n t0 c) =
906905
C.WithComments

0 commit comments

Comments
 (0)