{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE UndecidableInstances #-}
module Web.Hyperbole.HyperView.Forms
( FromForm (..)
, FromFormF (..)
, GenFields (..)
, fieldNames
, FieldName (..)
, FormFields (..)
, Field
, InputType (..)
, Input (..)
, field
, label
, input
, checkbox
, Radio (..)
, radioGroup
, radio
, select
, form
, textarea
, submit
, formData
, FormOptions (..)
, Validated (..)
, isInvalid
, invalidText
, validate
, Identity
, FE.FromFormKey
, Generic
, GFieldsGen (..)
, GenField (..)
, Form (..)
)
where
import Data.Bifunctor (first)
import Data.Functor.Identity (Identity (..))
import Data.Kind (Type)
import Data.Maybe (fromMaybe)
import Data.String (IsString (..))
import Data.String.Conversions (cs)
import Data.Text (Text, pack)
import Effectful
import GHC.Generics
import Text.Casing (kebab)
import Web.Atomic.Types hiding (Selector)
import Web.FormUrlEncoded (Form (..), FormOptions (..))
import Web.FormUrlEncoded qualified as FE
import Web.Hyperbole.Data.Param
import Web.Hyperbole.Effect.Hyperbole
import Web.Hyperbole.Effect.Request
import Web.Hyperbole.Effect.Response (parseError)
import Web.Hyperbole.HyperView.Event (onSubmit)
import Web.Hyperbole.HyperView.Input (Option (..), checked)
import Web.Hyperbole.HyperView.Types
import Web.Hyperbole.HyperView.ViewAction
import Web.Hyperbole.View
class FromForm (form :: Type) where
fromForm :: FE.Form -> Either String form
default fromForm :: (Generic form, GFormParse (Rep form)) => FE.Form -> Either String form
fromForm Form
f = Rep form Any -> form
forall a x. Generic a => Rep a x -> a
forall x. Rep form x -> form
to (Rep form Any -> form)
-> Either String (Rep form Any) -> Either String form
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Form -> Either String (Rep form Any)
forall p. Form -> Either String (Rep form p)
forall {k} (f :: k -> *) (p :: k).
GFormParse f =>
Form -> Either String (f p)
gFormParse Form
f
class FromFormF (f :: (Type -> Type) -> Type) where
fromFormF :: FE.Form -> Either String (f Identity)
default fromFormF :: (Generic (f Identity), GFormParse (Rep (f Identity))) => FE.Form -> Either String (f Identity)
fromFormF Form
f = Rep (f Identity) Any -> f Identity
forall a x. Generic a => Rep a x -> a
forall x. Rep (f Identity) x -> f Identity
to (Rep (f Identity) Any -> f Identity)
-> Either String (Rep (f Identity) Any)
-> Either String (f Identity)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Form -> Either String (Rep (f Identity) Any)
forall p. Form -> Either String (Rep (f Identity) p)
forall {k} (f :: k -> *) (p :: k).
GFormParse f =>
Form -> Either String (f p)
gFormParse Form
f
instance (FromFormF form) => FromForm (form Identity) where
fromForm :: Form -> Either String (form Identity)
fromForm = Form -> Either String (form Identity)
forall (form :: (* -> *) -> *).
FromFormF form =>
Form -> Either String (form Identity)
fromFormF
formData :: forall form es. (FromForm form, Hyperbole :> es) => Eff es form
formData :: forall form (es :: [Effect]).
(FromForm form, Hyperbole :> es) =>
Eff es form
formData = do
Form
f <- Eff es Form
forall (es :: [Effect]). (Hyperbole :> es) => Eff es Form
formBody
let ef :: Either String form
ef = forall form. FromForm form => Form -> Either String form
fromForm @form Form
f :: Either String form
(String -> Eff es form)
-> (form -> Eff es form) -> Either String form -> Eff es form
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> Eff es form
forall (es :: [Effect]) a. (Hyperbole :> es) => String -> Eff es a
parseError form -> Eff es form
forall a. a -> Eff es a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Either String form
ef
class GenFields f (form :: (Type -> Type) -> Type) where
genFields :: form f
default genFields :: (Generic (form f), GFieldsGen (Rep (form f))) => form f
genFields = Rep (form f) Any -> form f
forall a x. Generic a => Rep a x -> a
forall x. Rep (form f) x -> form f
to Rep (form f) Any
forall p. Rep (form f) p
forall {k} (f :: k -> *) (p :: k). GFieldsGen f => f p
gFieldsGen
fieldNames :: forall form. (GenFields FieldName form) => form FieldName
fieldNames :: forall (form :: (* -> *) -> *).
GenFields FieldName form =>
form FieldName
fieldNames = form FieldName
forall (f :: * -> *) (form :: (* -> *) -> *).
GenFields f form =>
form f
genFields
class GenField a where
genField :: String -> a
instance GenField (FieldName a) where
genField :: String -> FieldName a
genField String
s = Text -> FieldName a
forall {k} (a :: k). Text -> FieldName a
FieldName (Text -> FieldName a) -> Text -> FieldName a
forall a b. (a -> b) -> a -> b
$ String -> Text
pack String
s
instance GenField (Validated a) where
genField :: String -> Validated a
genField = Validated a -> String -> Validated a
forall a b. a -> b -> a
const Validated a
forall {k} (a :: k). Validated a
NotInvalid
instance GenField (Maybe a) where
genField :: String -> Maybe a
genField String
_ = Maybe a
forall a. Maybe a
Nothing
data FormFields id = FormFields id
form :: (ViewAction (Action id)) => Action id -> View (FormFields id) () -> View id ()
form :: forall id.
ViewAction (Action id) =>
Action id -> View (FormFields id) () -> View id ()
form Action id
a View (FormFields id) ()
cnt = do
id
vid <- View id id
forall c. View c c
context
Text -> View id () -> View id ()
forall c. Text -> View c () -> View c ()
tag Text
"form" (View id () -> View id ())
-> (Attributes (View id () -> View id ())
-> Attributes (View id () -> View id ()))
-> View id ()
-> View id ()
forall h.
Attributable h =>
h -> (Attributes h -> Attributes h) -> h
@ Action id
-> Attributes (View id () -> View id ())
-> Attributes (View id () -> View id ())
forall id a.
(ViewAction (Action id), ViewContext a ~ id, Attributable a) =>
Action id -> Attributes a -> Attributes a
onSubmit Action id
a (View id () -> View id ()) -> View id () -> View id ()
forall a b. (a -> b) -> a -> b
$ do
FormFields id -> View (FormFields id) () -> View id ()
forall ctx c. ctx -> View ctx () -> View c ()
addContext (id -> FormFields id
forall id. id -> FormFields id
FormFields id
vid) View (FormFields id) ()
cnt
submit :: View (FormFields id) () -> View (FormFields id) ()
submit :: forall id. View (FormFields id) () -> View (FormFields id) ()
submit = Text -> View (FormFields id) () -> View (FormFields id) ()
forall c. Text -> View c () -> View c ()
tag Text
"button" (View (FormFields id) () -> View (FormFields id) ())
-> (Attributes (View (FormFields id) () -> View (FormFields id) ())
-> Attributes (View (FormFields id) () -> View (FormFields id) ()))
-> View (FormFields id) ()
-> View (FormFields id) ()
forall h.
Attributable h =>
h -> (Attributes h -> Attributes h) -> h
@ Text
-> Text
-> Attributes (View (FormFields id) () -> View (FormFields id) ())
-> Attributes (View (FormFields id) () -> View (FormFields id) ())
forall h.
Attributable h =>
Text -> Text -> Attributes h -> Attributes h
att Text
"type" Text
"submit"
newtype FieldName a = FieldName Text
deriving newtype (Int -> FieldName a -> ShowS
[FieldName a] -> ShowS
FieldName a -> String
(Int -> FieldName a -> ShowS)
-> (FieldName a -> String)
-> ([FieldName a] -> ShowS)
-> Show (FieldName a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall k (a :: k). Int -> FieldName a -> ShowS
forall k (a :: k). [FieldName a] -> ShowS
forall k (a :: k). FieldName a -> String
$cshowsPrec :: forall k (a :: k). Int -> FieldName a -> ShowS
showsPrec :: Int -> FieldName a -> ShowS
$cshow :: forall k (a :: k). FieldName a -> String
show :: FieldName a -> String
$cshowList :: forall k (a :: k). [FieldName a] -> ShowS
showList :: [FieldName a] -> ShowS
Show, String -> FieldName a
(String -> FieldName a) -> IsString (FieldName a)
forall a. (String -> a) -> IsString a
forall k (a :: k). String -> FieldName a
$cfromString :: forall k (a :: k). String -> FieldName a
fromString :: String -> FieldName a
IsString)
field
:: forall (id :: Type) (a :: Type)
. FieldName a
-> View (Input id a) ()
-> View (FormFields id) ()
field :: forall id a.
FieldName a -> View (Input id a) () -> View (FormFields id) ()
field FieldName a
fn =
Input id a -> View (Input id a) () -> View (FormFields id) ()
forall ctx c. ctx -> View ctx () -> View c ()
addContext (FieldName a -> Input id a
forall id a. FieldName a -> Input id a
Input FieldName a
fn)
data InputType
=
NewPassword
| CurrentPassword
| Username
| Email
| Number
| TextInput
| Name
| OneTimeCode
| Organization
| StreetAddress
| Country
| CountryName
| PostalCode
| Search
deriving (Int -> InputType -> ShowS
[InputType] -> ShowS
InputType -> String
(Int -> InputType -> ShowS)
-> (InputType -> String)
-> ([InputType] -> ShowS)
-> Show InputType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> InputType -> ShowS
showsPrec :: Int -> InputType -> ShowS
$cshow :: InputType -> String
show :: InputType -> String
$cshowList :: [InputType] -> ShowS
showList :: [InputType] -> ShowS
Show)
data Input (id :: Type) (a :: Type) = Input
{ forall id a. Input id a -> FieldName a
inputName :: FieldName a
}
label :: View c () -> View c ()
label :: forall c. View c () -> View c ()
label = Text -> View c () -> View c ()
forall c. Text -> View c () -> View c ()
tag Text
"label"
input :: InputType -> View (Input id a) ()
input :: forall id a. InputType -> View (Input id a) ()
input InputType
ft = do
Input (FieldName Text
nm) <- View (Input id a) (Input id a)
forall c. View c c
context
Text -> View (Input id a) () -> View (Input id a) ()
forall c. Text -> View c () -> View c ()
tag Text
"input" (View (Input id a) () -> View (Input id a) ())
-> (Attributes (View (Input id a) () -> View (Input id a) ())
-> Attributes (View (Input id a) () -> View (Input id a) ()))
-> View (Input id a) ()
-> View (Input id a) ()
forall h.
Attributable h =>
h -> (Attributes h -> Attributes h) -> h
@ Text
-> Text
-> Attributes (View (Input id a) () -> View (Input id a) ())
-> Attributes (View (Input id a) () -> View (Input id a) ())
forall h.
Attributable h =>
Text -> Text -> Attributes h -> Attributes h
att Text
"type" (InputType -> Text
forall {a}. IsString a => InputType -> a
inpType InputType
ft) (Attributes (View (Input id a) () -> View (Input id a) ())
-> Attributes (View (Input id a) () -> View (Input id a) ()))
-> (Attributes (View (Input id a) () -> View (Input id a) ())
-> Attributes (View (Input id a) () -> View (Input id a) ()))
-> Attributes (View (Input id a) () -> View (Input id a) ())
-> Attributes (View (Input id a) () -> View (Input id a) ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text
-> Attributes (View (Input id a) () -> View (Input id a) ())
-> Attributes (View (Input id a) () -> View (Input id a) ())
forall h. Attributable h => Text -> Attributes h -> Attributes h
name Text
nm (Attributes (View (Input id a) () -> View (Input id a) ())
-> Attributes (View (Input id a) () -> View (Input id a) ()))
-> (Attributes (View (Input id a) () -> View (Input id a) ())
-> Attributes (View (Input id a) () -> View (Input id a) ()))
-> Attributes (View (Input id a) () -> View (Input id a) ())
-> Attributes (View (Input id a) () -> View (Input id a) ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text
-> Text
-> Attributes (View (Input id a) () -> View (Input id a) ())
-> Attributes (View (Input id a) () -> View (Input id a) ())
forall h.
Attributable h =>
Text -> Text -> Attributes h -> Attributes h
att Text
"autocomplete" (InputType -> Text
auto InputType
ft) (View (Input id a) () -> View (Input id a) ())
-> View (Input id a) () -> View (Input id a) ()
forall a b. (a -> b) -> a -> b
$ View (Input id a) ()
forall c. View c ()
none
where
inpType :: InputType -> a
inpType InputType
NewPassword = a
"password"
inpType InputType
CurrentPassword = a
"password"
inpType InputType
Number = a
"number"
inpType InputType
Email = a
"email"
inpType InputType
Search = a
"search"
inpType InputType
_ = a
"text"
auto :: InputType -> Text
auto :: InputType -> Text
auto = String -> Text
pack (String -> Text) -> (InputType -> String) -> InputType -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS
kebab ShowS -> (InputType -> String) -> InputType -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InputType -> String
forall a. Show a => a -> String
show
checkbox :: Bool -> View (Input id a) ()
checkbox :: forall id a. Bool -> View (Input id a) ()
checkbox Bool
isChecked = do
Input (FieldName Text
nm) <- View (Input id a) (Input id a)
forall c. View c c
context
Text -> View (Input id a) () -> View (Input id a) ()
forall c. Text -> View c () -> View c ()
tag Text
"input" (View (Input id a) () -> View (Input id a) ())
-> (Attributes (View (Input id a) () -> View (Input id a) ())
-> Attributes (View (Input id a) () -> View (Input id a) ()))
-> View (Input id a) ()
-> View (Input id a) ()
forall h.
Attributable h =>
h -> (Attributes h -> Attributes h) -> h
@ Text
-> Text
-> Attributes (View (Input id a) () -> View (Input id a) ())
-> Attributes (View (Input id a) () -> View (Input id a) ())
forall h.
Attributable h =>
Text -> Text -> Attributes h -> Attributes h
att Text
"type" Text
"checkbox" (Attributes (View (Input id a) () -> View (Input id a) ())
-> Attributes (View (Input id a) () -> View (Input id a) ()))
-> (Attributes (View (Input id a) () -> View (Input id a) ())
-> Attributes (View (Input id a) () -> View (Input id a) ()))
-> Attributes (View (Input id a) () -> View (Input id a) ())
-> Attributes (View (Input id a) () -> View (Input id a) ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text
-> Attributes (View (Input id a) () -> View (Input id a) ())
-> Attributes (View (Input id a) () -> View (Input id a) ())
forall h. Attributable h => Text -> Attributes h -> Attributes h
name Text
nm (View (Input id a) () -> View (Input id a) ())
-> View (Input id a) () -> View (Input id a) ()
forall a b. (a -> b) -> a -> b
$ View (Input id a) ()
forall c. View c ()
none View (Input id a) ()
-> (Attributes (View (Input id a) ())
-> Attributes (View (Input id a) ()))
-> View (Input id a) ()
forall h.
Attributable h =>
h -> (Attributes h -> Attributes h) -> h
@ Bool
-> Attributes (View (Input id a) ())
-> Attributes (View (Input id a) ())
forall a. Attributable a => Bool -> Attributes a -> Attributes a
checked Bool
isChecked
data Radio (id :: Type) (a :: Type) (b :: Type) = Selection
{ forall id a b. Radio id a b -> Input id a
inputCtx :: Input id a
, forall id a b. Radio id a b -> b
defaultOption :: b
}
radioGroup :: b -> View (Radio id a b) () -> View (Input id a) ()
radioGroup :: forall b id a. b -> View (Radio id a b) () -> View (Input id a) ()
radioGroup b
defOpt = (Input id a -> Radio id a b)
-> View (Radio id a b) () -> View (Input id a) ()
forall ctx0 ctx1. (ctx0 -> ctx1) -> View ctx1 () -> View ctx0 ()
modifyContext ((Input id a -> Radio id a b)
-> View (Radio id a b) () -> View (Input id a) ())
-> (Input id a -> Radio id a b)
-> View (Radio id a b) ()
-> View (Input id a) ()
forall a b. (a -> b) -> a -> b
$ \Input id a
inp -> Input id a -> b -> Radio id a b
forall id a b. Input id a -> b -> Radio id a b
Selection Input id a
inp b
defOpt
radio :: (Eq b, ToParam b) => b -> View (Radio id a b) ()
radio :: forall b id a. (Eq b, ToParam b) => b -> View (Radio id a b) ()
radio b
val = do
Selection (Input (FieldName Text
nm)) b
defOpt <- View (Radio id a b) (Radio id a b)
forall c. View c c
context
Text -> View (Radio id a b) () -> View (Radio id a b) ()
forall c. Text -> View c () -> View c ()
tag Text
"input"
(View (Radio id a b) () -> View (Radio id a b) ())
-> (Attributes (View (Radio id a b) () -> View (Radio id a b) ())
-> Attributes (View (Radio id a b) () -> View (Radio id a b) ()))
-> View (Radio id a b) ()
-> View (Radio id a b) ()
forall h.
Attributable h =>
h -> (Attributes h -> Attributes h) -> h
@ Text
-> Text
-> Attributes (View (Radio id a b) () -> View (Radio id a b) ())
-> Attributes (View (Radio id a b) () -> View (Radio id a b) ())
forall h.
Attributable h =>
Text -> Text -> Attributes h -> Attributes h
att Text
"type" Text
"radio"
(Attributes (View (Radio id a b) () -> View (Radio id a b) ())
-> Attributes (View (Radio id a b) () -> View (Radio id a b) ()))
-> (Attributes (View (Radio id a b) () -> View (Radio id a b) ())
-> Attributes (View (Radio id a b) () -> View (Radio id a b) ()))
-> Attributes (View (Radio id a b) () -> View (Radio id a b) ())
-> Attributes (View (Radio id a b) () -> View (Radio id a b) ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text
-> Attributes (View (Radio id a b) () -> View (Radio id a b) ())
-> Attributes (View (Radio id a b) () -> View (Radio id a b) ())
forall h. Attributable h => Text -> Attributes h -> Attributes h
name Text
nm
(Attributes (View (Radio id a b) () -> View (Radio id a b) ())
-> Attributes (View (Radio id a b) () -> View (Radio id a b) ()))
-> (Attributes (View (Radio id a b) () -> View (Radio id a b) ())
-> Attributes (View (Radio id a b) () -> View (Radio id a b) ()))
-> Attributes (View (Radio id a b) () -> View (Radio id a b) ())
-> Attributes (View (Radio id a b) () -> View (Radio id a b) ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text
-> Attributes (View (Radio id a b) () -> View (Radio id a b) ())
-> Attributes (View (Radio id a b) () -> View (Radio id a b) ())
forall h. Attributable h => Text -> Attributes h -> Attributes h
value (b -> ParamValue
forall a. ToParam a => a -> ParamValue
toParam b
val).value
(Attributes (View (Radio id a b) () -> View (Radio id a b) ())
-> Attributes (View (Radio id a b) () -> View (Radio id a b) ()))
-> (Attributes (View (Radio id a b) () -> View (Radio id a b) ())
-> Attributes (View (Radio id a b) () -> View (Radio id a b) ()))
-> Attributes (View (Radio id a b) () -> View (Radio id a b) ())
-> Attributes (View (Radio id a b) () -> View (Radio id a b) ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool
-> Attributes (View (Radio id a b) () -> View (Radio id a b) ())
-> Attributes (View (Radio id a b) () -> View (Radio id a b) ())
forall a. Attributable a => Bool -> Attributes a -> Attributes a
checked (b
defOpt b -> b -> Bool
forall a. Eq a => a -> a -> Bool
== b
val)
(View (Radio id a b) () -> View (Radio id a b) ())
-> View (Radio id a b) () -> View (Radio id a b) ()
forall a b. (a -> b) -> a -> b
$ View (Radio id a b) ()
forall c. View c ()
none
select :: (Eq opt) => opt -> View (Option opt id) () -> View (Input id a) ()
select :: forall opt id a.
Eq opt =>
opt -> View (Option opt id) () -> View (Input id a) ()
select opt
defOpt View (Option opt id) ()
options = do
Input (FieldName Text
nm) <- View (Input id a) (Input id a)
forall c. View c c
context
Text -> View (Input id a) () -> View (Input id a) ()
forall c. Text -> View c () -> View c ()
tag Text
"select" (View (Input id a) () -> View (Input id a) ())
-> (Attributes (View (Input id a) () -> View (Input id a) ())
-> Attributes (View (Input id a) () -> View (Input id a) ()))
-> View (Input id a) ()
-> View (Input id a) ()
forall h.
Attributable h =>
h -> (Attributes h -> Attributes h) -> h
@ Text
-> Attributes (View (Input id a) () -> View (Input id a) ())
-> Attributes (View (Input id a) () -> View (Input id a) ())
forall h. Attributable h => Text -> Attributes h -> Attributes h
name Text
nm (View (Input id a) () -> View (Input id a) ())
-> View (Input id a) () -> View (Input id a) ()
forall a b. (a -> b) -> a -> b
$ Option opt id -> View (Option opt id) () -> View (Input id a) ()
forall ctx c. ctx -> View ctx () -> View c ()
addContext (opt -> Option opt id
forall {k} opt (id :: k). opt -> Option opt id
Option opt
defOpt) View (Option opt id) ()
options
textarea :: Maybe Text -> View (Input id a) ()
textarea :: forall id a. Maybe Text -> View (Input id a) ()
textarea Maybe Text
mDefaultText = do
Input (FieldName Text
nm) <- View (Input id a) (Input id a)
forall c. View c c
context
Text -> View (Input id a) () -> View (Input id a) ()
forall c. Text -> View c () -> View c ()
tag Text
"textarea" (View (Input id a) () -> View (Input id a) ())
-> (Attributes (View (Input id a) () -> View (Input id a) ())
-> Attributes (View (Input id a) () -> View (Input id a) ()))
-> View (Input id a) ()
-> View (Input id a) ()
forall h.
Attributable h =>
h -> (Attributes h -> Attributes h) -> h
@ Text
-> Attributes (View (Input id a) () -> View (Input id a) ())
-> Attributes (View (Input id a) () -> View (Input id a) ())
forall h. Attributable h => Text -> Attributes h -> Attributes h
name Text
nm (View (Input id a) () -> View (Input id a) ())
-> View (Input id a) () -> View (Input id a) ()
forall a b. (a -> b) -> a -> b
$ Text -> View (Input id a) ()
forall c. Text -> View c ()
text (Text -> View (Input id a) ()) -> Text -> View (Input id a) ()
forall a b. (a -> b) -> a -> b
$ Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe Text
"" Maybe Text
mDefaultText
data Validated a = Invalid Text | NotInvalid | Valid
deriving (Int -> Validated a -> ShowS
[Validated a] -> ShowS
Validated a -> String
(Int -> Validated a -> ShowS)
-> (Validated a -> String)
-> ([Validated a] -> ShowS)
-> Show (Validated a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall k (a :: k). Int -> Validated a -> ShowS
forall k (a :: k). [Validated a] -> ShowS
forall k (a :: k). Validated a -> String
$cshowsPrec :: forall k (a :: k). Int -> Validated a -> ShowS
showsPrec :: Int -> Validated a -> ShowS
$cshow :: forall k (a :: k). Validated a -> String
show :: Validated a -> String
$cshowList :: forall k (a :: k). [Validated a] -> ShowS
showList :: [Validated a] -> ShowS
Show)
instance Semigroup (Validated a) where
Invalid Text
t <> :: Validated a -> Validated a -> Validated a
<> Validated a
_ = Text -> Validated a
forall {k} (a :: k). Text -> Validated a
Invalid Text
t
Validated a
_ <> Invalid Text
t = Text -> Validated a
forall {k} (a :: k). Text -> Validated a
Invalid Text
t
Validated a
Valid <> Validated a
_ = Validated a
forall {k} (a :: k). Validated a
Valid
Validated a
_ <> Validated a
Valid = Validated a
forall {k} (a :: k). Validated a
Valid
Validated a
a <> Validated a
_ = Validated a
a
instance Monoid (Validated a) where
mempty :: Validated a
mempty = Validated a
forall {k} (a :: k). Validated a
NotInvalid
isInvalid :: Validated a -> Bool
isInvalid :: forall {k} (a :: k). Validated a -> Bool
isInvalid (Invalid Text
_) = Bool
True
isInvalid Validated a
_ = Bool
False
invalidText :: forall a id. Validated a -> View (Input id a) ()
invalidText :: forall a id. Validated a -> View (Input id a) ()
invalidText Validated a
v = do
case Validated a
v of
Invalid Text
t -> Text -> View (Input id a) ()
forall c. Text -> View c ()
text Text
t
Validated a
_ -> View (Input id a) ()
forall c. View c ()
none
validate :: Bool -> Text -> Validated a
validate :: forall {k} (a :: k). Bool -> Text -> Validated a
validate Bool
True Text
t = Text -> Validated a
forall {k} (a :: k). Text -> Validated a
Invalid Text
t
validate Bool
False Text
_ = Validated a
forall {k} (a :: k). Validated a
NotInvalid
type family Field (context :: Type -> Type) a
type instance Field Identity a = a
type instance Field FieldName a = FieldName a
type instance Field Validated a = Validated a
type instance Field Maybe a = Maybe a
type instance Field (Either String) a = Either String a
class GFormParse f where
gFormParse :: FE.Form -> Either String (f p)
instance (GFormParse f, GFormParse g) => GFormParse (f :*: g) where
gFormParse :: forall (p :: k). Form -> Either String ((:*:) f g p)
gFormParse Form
f = do
f p
a <- Form -> Either String (f p)
forall (p :: k). Form -> Either String (f p)
forall {k} (f :: k -> *) (p :: k).
GFormParse f =>
Form -> Either String (f p)
gFormParse Form
f
g p
b <- Form -> Either String (g p)
forall (p :: k). Form -> Either String (g p)
forall {k} (f :: k -> *) (p :: k).
GFormParse f =>
Form -> Either String (f p)
gFormParse Form
f
(:*:) f g p -> Either String ((:*:) f g p)
forall a. a -> Either String a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((:*:) f g p -> Either String ((:*:) f g p))
-> (:*:) f g p -> Either String ((:*:) f g p)
forall a b. (a -> b) -> a -> b
$ f p
a f p -> g p -> (:*:) f g p
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: g p
b
instance (GFormParse f) => GFormParse (M1 D d f) where
gFormParse :: forall (p :: k). Form -> Either String (M1 D d f p)
gFormParse Form
f = f p -> M1 D d f p
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (f p -> M1 D d f p)
-> Either String (f p) -> Either String (M1 D d f p)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Form -> Either String (f p)
forall (p :: k). Form -> Either String (f p)
forall {k} (f :: k -> *) (p :: k).
GFormParse f =>
Form -> Either String (f p)
gFormParse Form
f
instance (GFormParse f) => GFormParse (M1 C c f) where
gFormParse :: forall (p :: k). Form -> Either String (M1 C c f p)
gFormParse Form
f = f p -> M1 C c f p
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (f p -> M1 C c f p)
-> Either String (f p) -> Either String (M1 C c f p)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Form -> Either String (f p)
forall (p :: k). Form -> Either String (f p)
forall {k} (f :: k -> *) (p :: k).
GFormParse f =>
Form -> Either String (f p)
gFormParse Form
f
instance (Selector s, FromParam a) => GFormParse (M1 S s (K1 R a)) where
gFormParse :: forall (p :: k). Form -> Either String (M1 S s (K1 R a) p)
gFormParse Form
f = do
let sel :: String
sel = M1 S s (K1 R (Any a)) Any -> String
forall {k} (s :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
(f :: k1 -> *) (a :: k1).
Selector s =>
t s f a -> String
forall k1 (t :: Meta -> (k1 -> *) -> k1 -> *) (f :: k1 -> *)
(a :: k1).
t s f a -> String
selName (M1 S s (K1 R (f a)) p
forall {k} {f :: * -> *} {p :: k}. M1 S s (K1 R (f a)) p
forall a. HasCallStack => a
undefined :: M1 S s (K1 R (f a)) p)
Maybe Text
mt :: Maybe Text <- (Text -> String)
-> Either Text (Maybe Text) -> Either String (Maybe Text)
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first Text -> String
forall a b. ConvertibleStrings a b => a -> b
cs (Either Text (Maybe Text) -> Either String (Maybe Text))
-> Either Text (Maybe Text) -> Either String (Maybe Text)
forall a b. (a -> b) -> a -> b
$ Text -> Form -> Either Text (Maybe Text)
FE.lookupMaybe (String -> Text
forall a b. ConvertibleStrings a b => a -> b
cs String
sel) Form
f
a
a <- ShowS -> Either String a -> Either String a
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (\String
err -> String
sel String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
": " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
err) (Either String a -> Either String a)
-> Either String a -> Either String a
forall a b. (a -> b) -> a -> b
$ Maybe Text -> Either String a
forall a. FromParam a => Maybe Text -> Either String a
decodeFormValue Maybe Text
mt
M1 S s (K1 R a) p -> Either String (M1 S s (K1 R a) p)
forall a. a -> Either String a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (M1 S s (K1 R a) p -> Either String (M1 S s (K1 R a) p))
-> M1 S s (K1 R a) p -> Either String (M1 S s (K1 R a) p)
forall a b. (a -> b) -> a -> b
$ K1 R a p -> M1 S s (K1 R a) p
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (K1 R a p -> M1 S s (K1 R a) p)
-> (a -> K1 R a p) -> a -> M1 S s (K1 R a) p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> K1 R a p
forall k i c (p :: k). c -> K1 i c p
K1 (a -> M1 S s (K1 R a) p) -> a -> M1 S s (K1 R a) p
forall a b. (a -> b) -> a -> b
$ a
a
class GFieldsGen f where
gFieldsGen :: f p
instance GFieldsGen U1 where
gFieldsGen :: forall (p :: k). U1 p
gFieldsGen = U1 p
forall k (p :: k). U1 p
U1
instance (GFieldsGen f, GFieldsGen g) => GFieldsGen (f :*: g) where
gFieldsGen :: forall (p :: k). (:*:) f g p
gFieldsGen = f p
forall (p :: k). f p
forall {k} (f :: k -> *) (p :: k). GFieldsGen f => f p
gFieldsGen f p -> g p -> (:*:) f g p
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: g p
forall (p :: k). g p
forall {k} (f :: k -> *) (p :: k). GFieldsGen f => f p
gFieldsGen
instance (Selector s, GenField a) => GFieldsGen (M1 S s (K1 R a)) where
gFieldsGen :: forall (p :: k). M1 S s (K1 R a) p
gFieldsGen =
let sel :: String
sel = M1 S s (K1 R (Any a)) Any -> String
forall {k} (s :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
(f :: k1 -> *) (a :: k1).
Selector s =>
t s f a -> String
forall k1 (t :: Meta -> (k1 -> *) -> k1 -> *) (f :: k1 -> *)
(a :: k1).
t s f a -> String
selName (M1 S s (K1 R (f a)) p
forall {k} {f :: * -> *} {p :: k}. M1 S s (K1 R (f a)) p
forall a. HasCallStack => a
undefined :: M1 S s (K1 R (f a)) p)
in K1 R a p -> M1 S s (K1 R a) p
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (K1 R a p -> M1 S s (K1 R a) p)
-> (a -> K1 R a p) -> a -> M1 S s (K1 R a) p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> K1 R a p
forall k i c (p :: k). c -> K1 i c p
K1 (a -> M1 S s (K1 R a) p) -> a -> M1 S s (K1 R a) p
forall a b. (a -> b) -> a -> b
$ forall a. GenField a => String -> a
genField @a String
sel
instance (GFieldsGen f) => GFieldsGen (M1 D d f) where
gFieldsGen :: forall (p :: k). M1 D d f p
gFieldsGen = f p -> M1 D d f p
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 f p
forall (p :: k). f p
forall {k} (f :: k -> *) (p :: k). GFieldsGen f => f p
gFieldsGen
instance (GFieldsGen f) => GFieldsGen (M1 C c f) where
gFieldsGen :: forall (p :: k). M1 C c f p
gFieldsGen = f p -> M1 C c f p
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 f p
forall (p :: k). f p
forall {k} (f :: k -> *) (p :: k). GFieldsGen f => f p
gFieldsGen