Skip to content

Commit 154a3a9

Browse files
committed
refactor Duration parser
at this point we need to upgrade to [email protected]
1 parent 4c8a92e commit 154a3a9

File tree

2 files changed

+50
-24
lines changed

2 files changed

+50
-24
lines changed

src/Data/Formatter/Internal.purs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,20 @@ digit = do
2727
'9' → pure 9
2828
_ → P.fail "Incorrect digit, impossible situation"
2929

30+
-- https://github.com/purescript-contrib/purescript-parsing/issues/50
31+
-- digit ∷ ∀ m. Monad m ⇒ P.ParserT String m Int
32+
-- digit = PS.oneOfAs $
33+
-- [ Tuple '0' 0
34+
-- , Tuple '1' 1
35+
-- , Tuple '2' 2
36+
-- , Tuple '3' 3
37+
-- , Tuple '4' 4
38+
-- , Tuple '5' 5
39+
-- , Tuple '6' 6
40+
-- , Tuple '7' 7
41+
-- , Tuple '8' 8
42+
-- , Tuple '9' 9]
43+
3044
repeat a. Monoid a a Int a
3145
repeat = repeat' mempty
3246
where

src/Data/Formatter/Interval.purs

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
module Data.Formatter.Interval
2-
-- TODO parser should't be exposed
32
( parseDuration
43
) where
54

@@ -11,10 +10,14 @@ import Text.Parsing.Parser.Combinators as PC
1110
import Text.Parsing.Parser.String as PS
1211
import Control.Alt ((<|>))
1312
import Data.Array (some)
14-
import Data.Function (on)
13+
import Data.Foldable (class Foldable, fold)
1514
import Data.Formatter.Internal (digit, foldDigits)
15+
import Data.Function (on)
1616
import Data.Int (toNumber, floor)
17-
import Data.Monoid (mempty)
17+
import Data.Maybe (Maybe, maybe)
18+
import Data.Monoid (class Monoid, mempty)
19+
import Data.Traversable (sequence)
20+
import Data.Tuple (Tuple(..))
1821

1922

2023
numOfDigits Int Int
@@ -40,31 +43,40 @@ number = (+)
4043
<$> (integer <#> toNumber)
4144
<*> (PC.option 0.0 $ PC.try $ PS.oneOf ['.', ','] *> fractional)
4245

46+
durationParser :: Array (Tuple (Number -> I.Duration) String) -> P.Parser String I.Duration
47+
durationParser arr = arr
48+
<#> applyDurations
49+
# sequence
50+
<#> foldFoldableMaybe
51+
52+
applyDurations :: Tuple (Number -> I.Duration) String -> P.Parser String (Maybe I.Duration)
53+
applyDurations (Tuple f c) = PC.optionMaybe $ PC.try (f <$> component c)
54+
55+
foldFoldableMaybe :: f a. (Foldable f, Monoid a) => f (Maybe a) -> a
56+
foldFoldableMaybe = fold >>> unMaybe
57+
58+
unMaybe :: a. (Monoid a) => Maybe a -> a
59+
unMaybe = maybe mempty id
60+
4361
component String P.Parser String Number
4462
component designator = number <* PS.string designator
4563

46-
tryOr :: a. a P.Parser String a P.Parser String a
47-
tryOr a p = PC.option a $ PC.try p
64+
tryM :: a. (Monoid a) => P.Parser String a P.Parser String a
65+
tryM p = PC.option mempty $ PC.try p
66+
67+
parseIsoDuration :: P.Parser String I.IsoDuration
68+
parseIsoDuration = do
69+
dur ← parseDuration
70+
case I.mkIsoDuration dur of
71+
Nothing -> PC.fail "extracted Duration is not valid ISO duration"
72+
Just a -> pure a
4873

4974
parseDuration :: P.Parser String I.Duration
50-
parseDuration = PS.string "P" *> (weekDuration <|> fullDuration) <* PS.eof
75+
parseDuration =
76+
PS.string "P" *> (weekDuration <|> fullDuration) <* PS.eof
5177
where
52-
weekDuration :: P.Parser String I.Duration
53-
weekDuration = PC.try $ I.week <$> component "W"
54-
55-
fullDuration P.Parser String I.Duration
78+
weekDuration = durationParser [ Tuple I.week "W" ]
5679
fullDuration = append <$> durationDatePart <*> durationTimePart
57-
58-
durationDatePart P.Parser String I.Duration
59-
durationDatePart = (\y m d → I.year y <> I.month m <> I.day d)
60-
<$> (tryOr 0.0 $ component "Y")
61-
<*> (tryOr 0.0 $ component "M")
62-
<*> (tryOr 0.0 $ component "D")
63-
64-
durationTimePart P.Parser String I.Duration
65-
durationTimePart = tryOr mempty $
66-
PS.string "T" *>
67-
pure (\h m s → I.hours h <> I.minutes m <> I.seconds s)
68-
<*> (tryOr 0.0 $ component "H")
69-
<*> (tryOr 0.0 $ component "M")
70-
<*> (tryOr 0.0 $ component "S")
80+
durationDatePart = durationParser [ Tuple I.year "Y" , Tuple I.month "M" , Tuple I.day "D" ]
81+
durationTimePart = tryM $ PS.string "T" *>
82+
(durationParser [ Tuple I.hours "H" , Tuple I.minutes "M" , Tuple I.seconds "S" ])

0 commit comments

Comments
 (0)