-- SPDX-FileCopyrightText: 2022 Sarah Vaupel -- -- SPDX-License-Identifier: AGPL-3.0-or-later module Handler.Utils.Corrections where import Import -- CorrectionInfo has seeming redundancies, but these are useful for aggregation -- INVARIANT: isJust ciTot `implies` ciCorrected > 0 data CorrectionInfo = CorrectionInfo { ciSubmittors, ciSubmissions, ciAssigned, ciCorrected :: Integer , ciCorrector :: Maybe UserId , ciTot, ciMin, ciMax :: Maybe NominalDiffTime } instance Semigroup CorrectionInfo where corrA <> corrB = assert (isJust (ciTot corrA) `implies` (ciCorrected corrA > 0)) $ assert (isJust (ciTot corrB) `implies` (ciCorrected corrB > 0)) CorrectionInfo { ciSubmittors = ciSubmittors `mergeWith` (+) , ciSubmissions = ciSubmissions `mergeWith` (+) , ciAssigned = ciAssigned `mergeWith` (+) , ciCorrected = ciCorrected `mergeWith` (+) , ciCorrector = ciCorrector `mergeWith` keepEqual , ciTot = ciTot `mergeWith` ignoreNothing (+) , ciMin = ciMin `mergeWith` ignoreNothing min , ciMax = ciMax `mergeWith` ignoreNothing max } where mergeWith :: (CorrectionInfo -> a) -> (a -> a -> c) -> c mergeWith prj f = on f prj corrA corrB keepEqual (Just x) (Just y) | x==y = Just x keepEqual Nothing other = other keepEqual other Nothing = other keepEqual _ _ = Nothing instance Monoid CorrectionInfo where mappend = (<>) mempty = CorrectionInfo { ciSubmittors = 0 , ciSubmissions = 0 , ciAssigned = 0 , ciCorrected = 0 , ciCorrector = Nothing , ciMin = Nothing , ciTot = Nothing , ciMax = Nothing }