{-# LANGUAGE DeriveDataTypeable #-}{-# LANGUAGE RecordWildCards #-}moduleData.Fortune.Stats(FortuneStats(..),StatsProblem(..),checkStats,statsAreValid)whereimportData.MaybeimportData.SemigroupimportData.Typeable-- |Some statistics about the fortunes in a database. These are stored in -- the index file and used to speed up various calculations that would otherwise-- require re-reading lots of files.dataFortuneStats=FortuneStats{numFortunes::!(SumInt),offsetAfter::!(MaxInt),minChars::!(MinInt),maxChars::!(MaxInt),minLines::!(MinInt),maxLines::!(MaxInt)}deriving(Eq,Show)wrap(a,b,c,(d,e,f))=FortuneStatsabcdefunwrap(FortuneStatsabcdef)=(a,b,c,(d,e,f))instanceSemigroupFortuneStatswheres1<>s2=wrap(unwraps1<>unwraps2)instanceMonoidFortuneStatswheremempty=wrapmempty;mappend=(<>)-- |Errors that can be thrown when stats are read from an index file.-- These errors describe various logical inconsistencies that generally-- indicate that the index file is corrupted somehow.dataStatsProblem=NegativeCount!Int|NegativeLength!Int|NegativeOffset!Int|LengthsWithoutEntries|EntriesWithoutLengths|MaxLengthLessThanMinLength|InconsistentLengthsForOneEntryderiving(Eq,Ord,Read,Show,Typeable)checkStatsFortuneStats{numFortunes=Sumn,offsetAfter=Maxo,..}|n>0&&o<0=Just(NegativeOffseto)|otherwise=casen`compare`0ofLT->Just(NegativeCountn)EQ->ifall(mempty==)[maxChars,maxLines]&&all(mempty==)[minChars,minLines]thenNothingelseJustLengthsWithoutEntriesGT->getFirst$First(checkLengthsminCharsmaxChars)<>First(checkLengthsminLinesmaxLines)wherecheckLengths(Minmn)(Maxmx)|mx<0=Just(NegativeLengthmx)|mn<0=Just(NegativeLengthmn)|otherwise=casemx`compare`mnofLT->JustMaxLengthLessThanMinLengthEQ->NothingGT|n==1->JustInconsistentLengthsForOneEntry|otherwise->NothingstatsAreValid=isNothing.checkStats