|
3 | 3 | {-# LANGUAGE FunctionalDependencies #-} |
4 | 4 | {-# LANGUAGE LambdaCase #-} |
5 | 5 | {-# LANGUAGE OverloadedStrings #-} |
| 6 | +{-# LANGUAGE RecordWildCards #-} |
6 | 7 | {-# LANGUAGE TypeFamilies #-} |
7 | 8 |
|
8 | 9 | -- | Module for building CDDL in Haskell |
@@ -99,6 +100,7 @@ import Data.List qualified as L |
99 | 100 | import Data.List.NonEmpty qualified as NE |
100 | 101 | import Data.Map.Ordered.Strict (OMap, (|<>)) |
101 | 102 | import Data.Map.Ordered.Strict qualified as OMap |
| 103 | +import Data.Set qualified as Set |
102 | 104 | import Data.String (IsString (fromString)) |
103 | 105 | import Data.Text qualified as T |
104 | 106 | import Data.Tuple.Optics (Field2 (..)) |
@@ -1061,24 +1063,53 @@ collectFromInit rules = |
1061 | 1063 | -- Conversion to CDDL |
1062 | 1064 | -------------------------------------------------------------------------------- |
1063 | 1065 |
|
| 1066 | +data HuddleConfig = HuddleConfig |
| 1067 | + { hcMakePseudoRoot :: Bool |
| 1068 | + , hcFailOnDuplicateDefinitions :: Bool |
| 1069 | + } |
| 1070 | + |
| 1071 | +defaultHuddleConfig :: HuddleConfig |
| 1072 | +defaultHuddleConfig = |
| 1073 | + HuddleConfig |
| 1074 | + { hcMakePseudoRoot = True |
| 1075 | + , hcFailOnDuplicateDefinitions = True |
| 1076 | + } |
| 1077 | + |
1064 | 1078 | -- | Convert from Huddle to CDDL, generating a top level root element. |
1065 | 1079 | toCDDL :: Huddle -> CDDL |
1066 | | -toCDDL = toCDDL' True |
| 1080 | +toCDDL = toCDDL' defaultHuddleConfig |
1067 | 1081 |
|
1068 | 1082 | -- | Convert from Huddle to CDDL, skipping a root element. |
1069 | 1083 | toCDDLNoRoot :: Huddle -> CDDL |
1070 | | -toCDDLNoRoot = toCDDL' False |
| 1084 | +toCDDLNoRoot = |
| 1085 | + toCDDL' |
| 1086 | + defaultHuddleConfig |
| 1087 | + { hcMakePseudoRoot = False |
| 1088 | + } |
1071 | 1089 |
|
1072 | 1090 | -- | Convert from Huddle to CDDL for the purpose of pretty-printing. |
1073 | | -toCDDL' :: Bool -> Huddle -> CDDL |
1074 | | -toCDDL' mkPseudoRoot hdl = |
| 1091 | +toCDDL' :: HuddleConfig -> Huddle -> CDDL |
| 1092 | +toCDDL' HuddleConfig {..} hdl = |
1075 | 1093 | C.fromRules |
1076 | | - $ ( if mkPseudoRoot |
1077 | | - then (toTopLevelPseudoRoot (roots hdl) NE.<|) |
1078 | | - else id |
1079 | | - ) |
| 1094 | + . failOnDuplicate |
| 1095 | + . makePseudoRoot |
1080 | 1096 | $ fmap toCDDLItem (NE.fromList $ fmap (view _2) $ toList $ items hdl) |
1081 | 1097 | where |
| 1098 | + makePseudoRoot |
| 1099 | + | hcMakePseudoRoot = (toTopLevelPseudoRoot (roots hdl) NE.<|) |
| 1100 | + | otherwise = id |
| 1101 | + |
| 1102 | + failOnDuplicate rs |
| 1103 | + | hcFailOnDuplicateDefinitions = go mempty $ toList rs |
| 1104 | + | otherwise = rs |
| 1105 | + where |
| 1106 | + go _ [] = rs |
| 1107 | + go s (x : xs) |
| 1108 | + | n `Set.member` s = error . T.unpack $ "Duplicate definitions found for '" <> n <> "'" |
| 1109 | + | otherwise = go (Set.insert n s) xs |
| 1110 | + where |
| 1111 | + n = C.name (C.ruleName x) |
| 1112 | + |
1082 | 1113 | toCDDLItem (HIRule r) = toCDDLRule r |
1083 | 1114 | toCDDLItem (HIGroup g) = toCDDLGroup g |
1084 | 1115 | toCDDLItem (HIGRule g) = toGenRuleDef g |
|
0 commit comments