Skip to content

Commit 9a30a49

Browse files
committed
docs: add missing docs
1 parent 02c61d9 commit 9a30a49

File tree

6 files changed

+752
-36
lines changed

6 files changed

+752
-36
lines changed

LICENSE

Lines changed: 674 additions & 0 deletions
Large diffs are not rendered by default.

megaparsec-utils.cabal

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@ author: drlkf
1515
maintainer: [email protected]
1616
copyright: 2024 drlkf
1717
license: GPL-3
18+
license-file: LICENSE
1819
build-type: Simple
20+
tested-with:
21+
GHC == 9.8
22+
, GHC == 9.6
23+
, GHC == 9.4
1924
extra-source-files:
2025
README.md
2126
CHANGELOG.md
@@ -34,14 +39,13 @@ library
3439
src
3540
ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints
3641
build-depends:
37-
aeson
42+
aeson >=2.0 && <3
3843
, base >=4.7 && <5
39-
, extra
40-
, megaparsec
41-
, parser-combinators
42-
, text
43-
, time
44-
, uuid
44+
, megaparsec >=9.0 && <10
45+
, parser-combinators >=1.0 && <2
46+
, text >=2.0 && <3
47+
, time >=1.10 && <2
48+
, uuid >=1.3 && <2
4549
default-language: Haskell2010
4650

4751
test-suite megaparsec-utils-test
@@ -56,14 +60,13 @@ test-suite megaparsec-utils-test
5660
ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints -threaded -rtsopts -with-rtsopts=-N
5761
build-depends:
5862
QuickCheck
59-
, aeson
63+
, aeson >=2.0 && <3
6064
, base >=4.7 && <5
61-
, extra
6265
, hspec
63-
, megaparsec
66+
, megaparsec >=9.0 && <10
6467
, megaparsec-utils
65-
, parser-combinators
66-
, text
67-
, time
68-
, uuid
68+
, parser-combinators >=1.0 && <2
69+
, text >=2.0 && <3
70+
, time >=1.10 && <2
71+
, uuid >=1.3 && <2
6972
default-language: Haskell2010

package.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ github: drlkf/megaparsec-utils
99
homepage: https://github.com/drlkf/megaparsec-utils
1010
bug-reports: https://github.com/drlkf/megaparsec-utils/issues
1111
category: Parsing
12+
tested-with:
13+
- GHC == 9.8
14+
- GHC == 9.6
15+
- GHC == 9.4
1216

1317
extra-source-files:
1418
- README.md

src/Text/Megaparsec/Time.hs

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
{-# LANGUAGE FlexibleContexts #-}
22

3+
{- |
4+
Module : Text.Megaparsec.Time
5+
Description : Various parsers for types related to time.
6+
Copyright : (c) drlkf, 2024
7+
License : GPL-3
8+
Maintainer : [email protected]
9+
Stability : experimental
10+
-}
11+
312
module Text.Megaparsec.Time
4-
( dateParser
13+
( DayResult
14+
15+
, dateParser
516
, dayParser
617
, durationParser
718
, gregorianDayParser
@@ -14,8 +25,8 @@ module Text.Megaparsec.Time
1425
import Control.Applicative (optional, (<|>))
1526
import Control.Monad (replicateM, void)
1627
import Control.Monad.Combinators (choice, some)
28+
import Data.Char (toLower)
1729
import Data.Functor (($>))
18-
import Data.List.Extra (lower)
1930
import Data.Maybe (fromMaybe)
2031
import Data.Time (Day, DayOfWeek (..),
2132
NominalDiffTime, TimeOfDay (..),
@@ -26,13 +37,22 @@ import Text.Megaparsec.Char (char, digitChar, space, space1,
2637
string')
2738
import Text.Megaparsec.Utils (posNumParser)
2839

40+
-- | Representation of a parser result with either a number of days relative to
41+
-- the current day, or a 'DayOfWeek'.
2942
type DayResult = Either Int DayOfWeek
3043

44+
-- | Parse a tuple containing a day or not, and a 'TimeOfDay'.
3145
dateParser
3246
:: Ord e
3347
=> Parsec e String (Maybe DayResult, TimeOfDay)
3448
dateParser = (,) <$> optional (try (dayParser <* space1)) <*> timeParser
3549

50+
-- | Parse a day using one of the following, all case-insensitive:
51+
--
52+
-- * a short (3-letters) or long day name e.g @mon@ or @monday@
53+
-- * @yesterday@ or @tomorrow@
54+
-- * a day number relative to the current day i.e @+2@ is two days from today
55+
-- * an absolute number for a 'DayOfWeek', refer to its 'Num' instance for more information.
3656
dayParser
3757
:: Ord e
3858
=> Parsec e String DayResult
@@ -43,14 +63,16 @@ dayParser = choice
4363
, Left <$> (string' "tomorrow" $> 1)
4464
, Right <$> absoluteDay
4565
, Left <$> relativeDay
46-
] where shortDay = choice $ map (ciString (lower . take 3 . show)) weekDays
47-
longDay = choice $ map (ciString (lower . show)) weekDays
66+
] where shortDay = choice $ map (ciString (fmap toLower . take 3 . show)) weekDays
67+
longDay = choice $ map (ciString (fmap toLower . show)) weekDays
4868
ciString f d = try (string' (f d)) $> d
4969
weekDays = [Monday .. Friday]
5070
sign = (char '-' $> negate) <|> (char '+' $> id)
5171
absoluteDay = toEnum . read <$> some digitChar
5272
relativeDay = ($) <$> sign <*> (read <$> some digitChar)
5373

74+
-- | Parse a 'NominalDiffTime' using strings like @1h23m45s@, with all
75+
-- components being optional as long as one is present.
5476
durationParser
5577
:: Ord e
5678
=> Parsec e String NominalDiffTime
@@ -60,14 +82,15 @@ durationParser = try hours <|> try minutes <|> secondsParser
6082
m <- fromMaybe zero <$> optional (try minutes)
6183
s <- fromMaybe zero <$> optional secondsParser
6284

63-
return $ h + m + s
85+
return (h + m + s)
6486

6587
minutes = do
6688
m <- minutesParser <* space
6789
s <- fromMaybe zero <$> optional secondsParser
6890

69-
return $ m + s
91+
return (m + s)
7092

93+
-- | Parse a Gregorian 'Day' from a @%d\/%m\/%Y@ format.
7194
gregorianDayParser
7295
:: Ord e
7396
=> Parsec e String Day
@@ -76,30 +99,34 @@ gregorianDayParser = do
7699
parseTimeM False defaultTimeLocale "%F" s <|>
77100
parseTimeM False defaultTimeLocale "%d/%m/%Y" s
78101

102+
-- | Parse a 'NominalDiffTime' from a number of hours from a string like @1h@.
79103
hoursParser
80104
:: Ord e
81105
=> Parsec e String NominalDiffTime
82106
hoursParser = secondsToNominalDiffTime . (* 3600) <$> posNumParser <* char 'h'
83107

108+
-- | Parse a 'NominalDiffTime' from a number of minutes from a string like @1m@.
84109
minutesParser
85110
:: Ord e
86111
=> Parsec e String NominalDiffTime
87112
minutesParser = secondsToNominalDiffTime . (* 60) <$> posNumParser <* char 'm'
88113

114+
-- | Parse a 'NominalDiffTime' from a number of seconds from a string like @1s@.
89115
secondsParser
90116
:: Ord e
91117
=> Parsec e String NominalDiffTime
92118
secondsParser = secondsToNominalDiffTime <$> posNumParser <* optional (char 's')
93119

120+
-- | Parse a 'TimeOfDay' from a string like @01:23@.
94121
timeParser
95122
:: Ord e
96123
=> Parsec e String TimeOfDay
97124
timeParser = do
98-
h <- read <$> replicateM 2 digitChar
99-
void $ char ':'
125+
h <- read <$> replicateM 2 digitChar <* char ':'
100126
m <- read <$> replicateM 2 digitChar
101127

102128
return $ TimeOfDay h m 0
103129

130+
-- | Zero seconds in 'NominalDiffTime'.
104131
zero :: NominalDiffTime
105132
zero = secondsToNominalDiffTime 0

src/Text/Megaparsec/Utils.hs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22
{-# LANGUAGE ScopedTypeVariables #-}
33
{-# LANGUAGE TypeFamilies #-}
44

5+
{- |
6+
Module : Text.Megaparsec.Utils
7+
Description : Various generic parsers and combinators.
8+
Copyright : (c) drlkf, 2024
9+
License : GPL-3
10+
Maintainer : [email protected]
11+
Stability : experimental
12+
-}
13+
514
module Text.Megaparsec.Utils
615
( boolParser
716
, boundedEnumShowParser
@@ -62,7 +71,7 @@ commaSeparated
6271
-> Parsec e String (NonEmpty a)
6372
commaSeparated p = (:|) <$> p <*> many (char ',' >> p)
6473

65-
-- | Parse any occurrence of a given parser. Consumes any input before occurence.
74+
-- | Parse any occurrence of a given parser. Consumes any input before occurrence.
6675
occurrence
6776
:: Ord e
6877
=> Parsec e String a
@@ -94,27 +103,24 @@ posNumParser
94103
=> Parsec e String a
95104
posNumParser = read <$> some digitChar
96105

97-
-- | Parse an integer, without any spaces between minus sign and digits.
106+
-- | Parse an integer, without any space between minus sign and digits.
98107
numParser
99108
:: Ord e
100109
=> Parsec e String Int
101110
numParser = (char '-' >> negate <$> posNumParser) <|> posNumParser
102111

103-
-- | Convert a 'Parsec' parser into a 'Parser' suited for 'FromJSON' instances.
112+
-- | Convert a 'Parsec' parser into a 'Parser' suited for 'Data.Aeson.FromJSON'
113+
-- instances.
104114
parsecToJSONParser
105115
:: ShowErrorComponent e
106-
-- ^ Parser name.
107-
=> String
108-
-- ^ Parser.
109-
-> Parsec e String a
110-
-- ^ Input value.
111-
-> Value
112-
-> Parser a
116+
=> String -- ^ Parser name.
117+
-> Parsec e String a -- ^ Parser.
118+
-> (Value -> Parser a)
113119
parsecToJSONParser n p =
114120
withText n $ either (fail . errorBundlePretty) pure . runParser p n . T.unpack
115121

116122
-- | Convert a 'Parsec' parser into a 'ReadS' parser. Useful for defining 'Read'
117-
-- instances with 'Megaparsec'.
123+
-- instances with 'Text.Megaparsec'.
118124
parsecToReadsPrec
119125
:: Parsec e String a
120126
-> ReadS a

test/Text/Megaparsec/TimeSpec.hs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ module Text.Megaparsec.TimeSpec
66

77
import Control.Monad (forM_)
88
import Data.Bifunctor (Bifunctor (first))
9+
import Data.Char (toLower)
910
import Data.Either (isLeft)
10-
import Data.List.Extra (lower)
1111
import Data.Time (Day, DayOfWeek (..), TimeOfDay (..),
1212
defaultTimeLocale, formatTime,
1313
fromGregorian, secondsToNominalDiffTime)
@@ -92,8 +92,10 @@ spec = do
9292
Right (Right d)
9393

9494
it "lowercase" . forAll (arbitrary `suchThat` weekday) $ \d ->
95-
parseOrPrettyError dayParser (lower (formatTime defaultTimeLocale format d)) `shouldBe`
96-
Right (Right d)
95+
parseOrPrettyError
96+
dayParser
97+
(fmap toLower (formatTime defaultTimeLocale format d))
98+
`shouldBe` Right (Right d)
9799

98100
it "weekend" . forAll (arbitrary `suchThat` (not . weekday)) $ \d ->
99101
parseOrPrettyError dayParser (formatTime defaultTimeLocale format d) `shouldSatisfy`

0 commit comments

Comments
 (0)