sunroof-compiler-0.2: Language/Sunroof/Selector.hs
{-# LANGUAGE ScopedTypeVariables #-}
-- | 'JSSelector' are used to access fields of Javascript objects.
module Language.Sunroof.Selector
( JSSelector
, label, index
, unboxSelector
, (!)
) where
import Data.String ( IsString(..) )
import Data.Proxy ( Proxy(Proxy) )
import Language.Sunroof.JavaScript ( Expr, E(Dot), ExprE(ExprE) )
import Language.Sunroof.Classes ( Sunroof(..) )
import Language.Sunroof.JS.String ( JSString, string )
import Language.Sunroof.JS.Number ( JSNumber )
-- | A 'JSSelector' selects a field or attribute from a Javascript object.
-- The phantom type is the type of the selected value. Note the selected
-- field or attributes may also array entries ('index').
data JSSelector a = JSSelector Expr
-- | Selectors can be created from the name of their attribute.
instance IsString (JSSelector a) where
fromString = JSSelector . unbox . string
instance Show (JSSelector a) where
show (JSSelector ids) = show ids
-- | Create a selector for a named field or attribute.
-- For type safty it is adivsed to use this with an
-- accompanying type signature. Example:
--
-- > array ! label "length"
--
-- See '!' for further information on usage.
label :: JSString -> JSSelector a
label = JSSelector . unbox
-- | Create a selector for an indexed value (e.g. array access).
-- For type safty it is adivsed to use this with an
-- accompanying type signature. Example:
--
-- > array ! index 4
--
-- See '!' for further information on usage.
index :: JSNumber -> JSSelector a
index = JSSelector . unbox
-- | Provided for internal usage by the compiler. Unwraps the
-- selector.
unboxSelector :: JSSelector a -> Expr
unboxSelector (JSSelector e) = e
---------------------------------------------------------------
infixl 1 !
-- | Operator to use a selector on a Javascript object. Examples:
--
-- > array ! label "length"
-- > array ! index 4
(!) :: forall o a . (Sunroof o, Sunroof a) => o -> JSSelector a -> a
(!) arr (JSSelector idx) = box $ Dot (ExprE $ unbox arr)
(ExprE $ idx)
(typeOf (Proxy :: Proxy a))