Skip to content

Commit 6dc1c6f

Browse files
committed
Compiling
1 parent b5860b9 commit 6dc1c6f

File tree

1 file changed

+73
-32
lines changed

1 file changed

+73
-32
lines changed

src/Codec/CBOR/Cuddle/CBOR/Validator.hs

Lines changed: 73 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ import Data.Bifunctor
1919
import Data.Bits hiding (And)
2020
import Data.ByteString qualified as BS
2121
import Data.ByteString.Lazy qualified as BSL
22+
import Data.Either (lefts, rights)
2223
import Data.Function ((&))
23-
import Data.Functor ((<&>), ($>))
24+
import Data.Functor ((<&>))
2425
import Data.Functor.Identity
2526
import Data.IntSet qualified as IS
2627
import Data.List.NonEmpty qualified as NE
@@ -662,7 +663,7 @@ flattenGroup cddl nodes =
662663
data Filter
663664
= NoFilter
664665
| Filter {mapFilter :: Rule, arrayFilter :: Rule}
665-
deriving Show
666+
deriving (Show)
666667

667668
-- | A tree of possible expansions of a rule matching the size of a container to
668669
-- validate. This tree contains filters at each node, such that we can
@@ -694,6 +695,14 @@ mergeTrees (a : as) = foldl' go a as
694695
go (Branch xs) b = Branch $ fmap (flip go b) xs
695696
go (FilterBranch f x) b = FilterBranch f $ go x b
696697

698+
-- | Merge two trees by adding them as choices at the top-level using the
699+
-- `Branch` constructor.
700+
mergeTopBranch :: ExpansionTree' a -> ExpansionTree' a -> ExpansionTree' a
701+
mergeTopBranch (Branch t1) (Branch t2) = Branch $ t1 <> t2
702+
mergeTopBranch (Branch t1) t2 = Branch (t1 <> [t2])
703+
mergeTopBranch t1 (Branch t2) = Branch (t1 : t2)
704+
mergeTopBranch t1 t2 = Branch [t1, t2]
705+
697706
-- | Clamp a tree to contain only expressions with a fixed number of elements.
698707
clampTree :: Int -> ExpansionTree -> ExpansionTree
699708
clampTree sz a = maybe (Branch []) id (go a)
@@ -831,31 +840,31 @@ validateExpandedList ::
831840
validateExpandedList terms rules = go rules
832841
where
833842
go :: ExpansionTree -> m (Rule -> CDDLResult)
834-
go (Leaf choice) = do
843+
go (Leaf choice) = do
835844
res <- validateListWithExpandedRules terms choice
836845
case res of
837846
[] -> pure Valid
838847
_ -> case last res of
839848
(_, CBORTermResult _ (Valid _)) -> pure Valid
840849
_ -> pure $ \r -> ListExpansionFail r rules (Leaf res)
841-
go (FilterBranch f x) = validateTerm (NE.head terms) (arrayFilter f) >>= \case
842-
(CBORTermResult _ (Valid _)) -> go x
843-
-- In this case we insert a leaf since we haven't actually validated the
844-
-- subnodes.
845-
err -> pure $ \r -> ListExpansionFail r rules $ FilterBranch f $ Leaf [(r, err)]
850+
go (FilterBranch f x) =
851+
validateTerm (NE.head terms) (arrayFilter f) >>= \case
852+
(CBORTermResult _ (Valid _)) -> go x
853+
-- In this case we insert a leaf since we haven't actually validated the
854+
-- subnodes.
855+
err -> pure $ \r -> ListExpansionFail r rules $ FilterBranch f $ Leaf [(r, err)]
846856
go (Branch xs) = goBranch xs
847857

848858
goBranch [] = pure $ \r -> ListExpansionFail r rules $ Branch []
849-
goBranch (x:xs) = go x <&> ($ dummyRule) >>= \case
850-
Valid _ -> pure Valid
851-
ListExpansionFail _ _ errors -> prependBranchErrors errors <$> goBranch xs
859+
goBranch (x : xs) =
860+
go x <&> ($ dummyRule) >>= \case
861+
Valid _ -> pure Valid
862+
ListExpansionFail _ _ errors -> prependBranchErrors errors <$> goBranch xs
852863

853864
prependBranchErrors errors res = case res dummyRule of
854-
Valid _ -> Valid
865+
Valid _ -> Valid
855866
ListExpansionFail _ _ errors2 -> \r ->
856-
ListExpansionFail r rules $ errors <> errors2
857-
858-
867+
ListExpansionFail r rules $ mergeTopBranch errors errors2
859868

860869
validateList ::
861870
MonadReader CDDL m => [Term] -> Rule -> m CDDLResult
@@ -866,7 +875,7 @@ validateList terms rule =
866875
Array rules ->
867876
case terms of
868877
[] -> ifM (and <$> mapM isOptional rules) (pure Valid) (pure InvalidRule)
869-
t:ts ->
878+
t : ts ->
870879
ask >>= \cddl ->
871880
let sequencesOfRules =
872881
runReader (expandRules (length terms) $ flattenGroup cddl rules) cddl
@@ -877,6 +886,29 @@ validateList terms rule =
877886
--------------------------------------------------------------------------------
878887
-- Maps
879888

889+
-- | Does the map comtain a key matching this rule?
890+
--
891+
-- If so, return the matching term. Otherwise, return the list of all the terms
892+
-- that failed to match
893+
containsMatchingKey ::
894+
forall m.
895+
MonadReader CDDL m =>
896+
NE.NonEmpty (Term, Term) ->
897+
Rule ->
898+
m (Either [ANonMatchedItem] AMatchedItem)
899+
containsMatchingKey terms rule = do
900+
let tryKey (k, v) = do
901+
result <- validateTerm k rule
902+
case result of
903+
CBORTermResult _ (Valid _) -> pure $ Right (AMatchedItem k v rule)
904+
CBORTermResult _ res -> pure $ Left (ANonMatchedItem k v [Left (rule, res)])
905+
906+
results <- traverse tryKey (NE.toList terms)
907+
case rights results of
908+
(m:_) -> pure $ Right m
909+
[] -> pure $ Left $ lefts results
910+
911+
880912
validateMapWithExpandedRules ::
881913
forall m.
882914
MonadReader CDDL m =>
@@ -916,25 +948,34 @@ validateMapWithExpandedRules =
916948
validateExpandedMap ::
917949
forall m.
918950
MonadReader CDDL m =>
919-
[(Term, Term)] ->
920-
[[Rule]] ->
951+
NE.NonEmpty (Term, Term) ->
952+
ExpansionTree ->
921953
m (Rule -> CDDLResult)
922954
validateExpandedMap terms rules = go rules
923955
where
924-
go :: [[Rule]] -> m (Rule -> CDDLResult)
925-
go [] = pure $ \r -> MapExpansionFail r rules []
926-
go (choice : choices) = do
927-
res <- validateMapWithExpandedRules terms choice
956+
go :: ExpansionTree -> m (Rule -> CDDLResult)
957+
go (Leaf choice) = do
958+
res <- validateMapWithExpandedRules (NE.toList terms) choice
928959
case res of
929960
(_, Nothing) -> pure Valid
930-
(matches, Just notMatched) ->
931-
go choices
932-
>>= ( \case
933-
Valid _ -> pure Valid
934-
MapExpansionFail _ _ errors ->
935-
pure $ \r -> MapExpansionFail r rules ((matches, notMatched) : errors)
936-
)
937-
. ($ dummyRule)
961+
(matches, Just notMatched) -> pure $ \r ->
962+
MapExpansionFail r rules [(matches, notMatched)]
963+
go (FilterBranch f x) =
964+
containsMatchingKey terms (mapFilter f) >>= \case
965+
Right _ -> go x
966+
Left errs -> pure $ \r -> MapExpansionFail r rules $ ([], ) <$> errs
967+
go (Branch xs) = goBranch xs
968+
969+
goBranch [] = pure $ \r -> MapExpansionFail r rules []
970+
goBranch (x : xs) =
971+
go x <&> ($ dummyRule) >>= \case
972+
Valid _ -> pure Valid
973+
MapExpansionFail _ _ errors -> prependBranchErrors errors <$> goBranch xs
974+
975+
prependBranchErrors errors res = case res dummyRule of
976+
Valid _ -> Valid
977+
MapExpansionFail _ _ errors2 -> \r ->
978+
MapExpansionFail r rules $ errors <> errors2
938979

939980
validateMap ::
940981
MonadReader CDDL m =>
@@ -946,11 +987,11 @@ validateMap terms rule =
946987
Map rules ->
947988
case terms of
948989
[] -> ifM (and <$> mapM isOptional rules) (pure Valid) (pure InvalidRule)
949-
_ ->
990+
x:xs ->
950991
ask >>= \cddl ->
951992
let sequencesOfRules =
952993
runReader (expandRules (length terms) $ flattenGroup cddl rules) cddl
953-
in validateExpandedMap terms sequencesOfRules
994+
in validateExpandedMap (x NE.:| xs) sequencesOfRules
954995
Choice opts -> validateChoice (validateMap terms) opts
955996
_ -> pure UnapplicableRule
956997

0 commit comments

Comments
 (0)