{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ViewPatterns #-}

module Matcha.Path where

import Data.Either (rights)
import Data.Text (Text)
import Web.HttpApiData (
    FromHttpApiData (parseUrlPiece),
    ToHttpApiData (toUrlPiece),
 )

pattern Param :: (ToHttpApiData a, FromHttpApiData a) => a -> Text
pattern $mParam :: forall {r} {a}.
(ToHttpApiData a, FromHttpApiData a) =>
Text -> (a -> r) -> ((# #) -> r) -> r
$bParam :: forall a. (ToHttpApiData a, FromHttpApiData a) => a -> Text
Param x <- (parseUrlPiece -> Right x)
    where
        Param a
x = a -> Text
forall a. ToHttpApiData a => a -> Text
toUrlPiece a
x

pattern Blob :: (ToHttpApiData a, FromHttpApiData a) => [a] -> [Text]
pattern $mBlob :: forall {r} {a}.
(ToHttpApiData a, FromHttpApiData a) =>
[Text] -> ([a] -> r) -> ((# #) -> r) -> r
$bBlob :: forall a. (ToHttpApiData a, FromHttpApiData a) => [a] -> [Text]
Blob l <- (rights . map parseUrlPiece -> l)
    where
        Blob [a]
l = (a -> Text) -> [a] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map a -> Text
forall a. ToHttpApiData a => a -> Text
toUrlPiece [a]
l

pattern (:/) :: (ToHttpApiData a, FromHttpApiData a) => a -> [Text] -> [Text]
pattern h $m:/ :: forall {r} {a}.
(ToHttpApiData a, FromHttpApiData a) =>
[Text] -> (a -> [Text] -> r) -> ((# #) -> r) -> r
$b:/ :: forall a.
(ToHttpApiData a, FromHttpApiData a) =>
a -> [Text] -> [Text]
:/ t <- ((parseUrlPiece -> Right h) : t)
    where
        a
h :/ [Text]
t = a -> Text
forall a. ToHttpApiData a => a -> Text
toUrlPiece a
h Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: [Text]
t

pattern (:/*) :: (ToHttpApiData a, ToHttpApiData b, FromHttpApiData a, FromHttpApiData b) => a -> [b] -> [Text]
pattern h $m:/* :: forall {r} {a} {b}.
(ToHttpApiData a, ToHttpApiData b, FromHttpApiData a,
 FromHttpApiData b) =>
[Text] -> (a -> [b] -> r) -> ((# #) -> r) -> r
$b:/* :: forall a b.
(ToHttpApiData a, ToHttpApiData b, FromHttpApiData a,
 FromHttpApiData b) =>
a -> [b] -> [Text]
:/* t <- ((parseUrlPiece -> Right h) : Blob t)
    where
        a
h :/* [b]
t = a -> Text
forall a. ToHttpApiData a => a -> Text
toUrlPiece a
h Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: (b -> Text) -> [b] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map b -> Text
forall a. ToHttpApiData a => a -> Text
toUrlPiece [b]
t

infixr 8 :/
infixr 9 :/*

pattern MyUrl :: Int -> Float -> [Bool] -> [Text]
pattern $mMyUrl :: forall {r}.
[Text] -> (Int -> Float -> [Bool] -> r) -> ((# #) -> r) -> r
$bMyUrl :: Int -> Float -> [Bool] -> [Text]
MyUrl x y bs = (x :: Int) :/ (y :: Float) :/ Blob @Bool bs

pattern MyOtherUrl :: Int -> Float -> [Bool] -> [Text]
pattern $mMyOtherUrl :: forall {r}.
[Text] -> (Int -> Float -> [Bool] -> r) -> ((# #) -> r) -> r
$bMyOtherUrl :: Int -> Float -> [Bool] -> [Text]
MyOtherUrl x y bs = (x :: Int) :/ (y :: Float) :/* bs

url :: [Text]
url :: [Text]
url = (Int
5 :: Int) Int -> [Text] -> [Text]
forall a.
(ToHttpApiData a, FromHttpApiData a) =>
a -> [Text] -> [Text]
:/ (Float
5.6 :: Float) Float -> [Text] -> [Text]
forall a.
(ToHttpApiData a, FromHttpApiData a) =>
a -> [Text] -> [Text]
:/ forall a. (ToHttpApiData a, FromHttpApiData a) => [a] -> [Text]
Blob @Bool [Bool
True, Bool
False, Bool
False, Bool
True, Bool
False]

matchUrl :: [Text] -> Maybe (Int, Float)
matchUrl :: [Text] -> Maybe (Int, Float)
matchUrl (Int
int :/ Float
float :/* ([] :: [Text])) = (Int, Float) -> Maybe (Int, Float)
forall a. a -> Maybe a
Just (Int
int, Float
float)
matchUrl [Text]
_ = Maybe (Int, Float)
forall a. Maybe a
Nothing