@@ -2,6 +2,8 @@
22{-# LANGUAGE DefaultSignatures #-}
33{-# LANGUAGE FlexibleInstances #-}
44{-# LANGUAGE OverloadedStrings #-}
5+{-# LANGUAGE Rank2Types #-}
6+{-# LANGUAGE ScopedTypeVariables #-}
57{-# LANGUAGE TypeSynonymInstances #-}
68-- |
79-- Convert Haskell values to and from route pieces.
@@ -13,6 +15,7 @@ module Web.PathPieces (
1315 WrappedPathPiece(..),
1416) where
1517
18+import Data.Monoid
1619import Data.Int
1720import Data.Word
1821import qualified Data.Text as S
@@ -21,6 +24,8 @@ import Data.Version (Version)
2124import Data.Time (Day)
2225import Text.Read (readMaybe)
2326
27+import Unsafe.Coerce
28+
2429#if MIN_VERSION_base(4,8,0)
2530import Data.Void (Void)
2631#endif
@@ -65,6 +70,33 @@ instance PathPiece Version
6570instance PathPiece Void
6671#endif
6772
73+instance PathPiece All
74+instance PathPiece Any
75+
76+instance PathPiece a => PathPiece (Dual a) where
77+ toPathPiece = unsafeToPathPiece1
78+ fromPathPiece = unsafeFromPathPiece1
79+
80+instance PathPiece a => PathPiece (Sum a) where
81+ toPathPiece = unsafeToPathPiece1
82+ fromPathPiece = unsafeFromPathPiece1
83+
84+instance PathPiece a => PathPiece (Product a) where
85+ toPathPiece = unsafeToPathPiece1
86+ fromPathPiece = unsafeFromPathPiece1
87+
88+instance PathPiece a => PathPiece (First a) where
89+ toPathPiece = unsafeToPathPiece1
90+ fromPathPiece = unsafeFromPathPiece1
91+
92+instance PathPiece a => PathPiece (Last a) where
93+ toPathPiece = unsafeToPathPiece1
94+ fromPathPiece = unsafeFromPathPiece1
95+
96+instance PathPiece a => PathPiece (Maybe a) where
97+ toPathPiece = unsafeToPathPiece1
98+ fromPathPiece = unsafeFromPathPiece1
99+
68100-- | Wrapped @'PathPiece'@ value.
69101newtype WrappedPathPiece a = WrappedPathPiece { unwrapPathPiece :: a }
70102
@@ -74,9 +106,11 @@ instance PathPiece a => ToHttpApiData (WrappedPathPiece a) where
74106instance PathPiece a => FromHttpApiData (WrappedPathPiece a) where
75107 parseUrlPiece = fmap WrappedPathPiece . parseMaybeHttpApiData fromPathPiece
76108
77−instance PathPiece a => PathPiece (Maybe a) where
78− toPathPiece = toUrlPiece . fmap WrappedPathPiece
79− fromPathPiece = either (const Nothing) (Just . fmap unwrapPathPiece) . parseUrlPiece
109+unsafeToPathPiece1 :: forall f a. (PathPiece a, ToHttpApiData (f (WrappedPathPiece a))) => f a -> S.Text
110+unsafeToPathPiece1 = toUrlPiece . (unsafeCoerce :: f a -> f (WrappedPathPiece a))
111+
112+unsafeFromPathPiece1 :: forall f a. (PathPiece a, FromHttpApiData (f (WrappedPathPiece a))) => S.Text -> Maybe (f a)
113+unsafeFromPathPiece1 = either (const Nothing) (Just . (unsafeCoerce :: f (WrappedPathPiece a) -> f a)) . parseUrlPiece
80114
81115-- | Convert Haskell values to and from sequence of route pieces.
82116class PathMultiPiece s where