| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- module LinkedIn.QueryRunner where
- import Prelude
- import Control.Alt ((<|>))
- import Control.Monad.Except (ExceptT(..), mapExceptT, runExceptT, throwError)
- import Data.Array as A
- import Data.Either (Either(..), note)
- import Data.Generic.Rep (class Generic)
- import Data.List.Types (NonEmptyList)
- import Data.Maybe (Maybe(..))
- import Data.Show.Generic (genericShow)
- import Data.Traversable (traverse)
- import Effect (Effect)
- import LinkedIn.Queryable (queryAllNodes, queryOneNode)
- import Web.DOM (Node)
- import Web.DOM.Node as N
- import Web.DOM.NodeList as NL
- import Web.DOM.Text as T
- data QueryError =
- QNodeNotFoundError String
- | QNodeListNotFoundError String
- | QNodeUnexpectedType String String
- | QTextNotFoundError
- | QChooseError
- derive instance Generic QueryError _
- derive instance Eq QueryError
- instance Show QueryError where
- show = genericShow
- type QueryRunner a = Node → ExceptT QueryError Effect a
- runQuery ∷ ∀ a. ExceptT QueryError Effect a → Effect (Either QueryError a)
- runQuery = runExceptT
- ignoreNotFound ∷ ∀ a f. Functor f ⇒ ExceptT QueryError f a → ExceptT QueryError f (Maybe a)
- ignoreNotFound = mapExceptT (map ignoreNotFound')
- where
- ignoreNotFound' = case _ of
- (Left (QNodeNotFoundError _ )) -> Right Nothing
- (Left (QNodeListNotFoundError _ )) -> Right Nothing
- (Left q) -> Left q
- (Right n') -> Right (Just n')
- ignoreErrors ∷ ∀ a f. Functor f ⇒ ExceptT QueryError f a → ExceptT QueryError f (Maybe a)
- ignoreErrors = mapExceptT (map ignoreErrors')
- where
- ignoreErrors' = case _ of
- (Left _) -> Right Nothing
- (Right n') -> Right (Just n')
- queryOne ∷ String → QueryRunner Node
- queryOne selector node = ExceptT $ do
- maybeNode <- queryOneNode selector node
- pure $ note (QNodeNotFoundError selector) maybeNode
- queryText ∷ Int -> QueryRunner Node
- queryText idx n = ExceptT $ do
- children <- N.childNodes n
- childrenArr <- NL.toArray children
- let
- maybeText n' = do
- _ <- T.fromNode n'
- pure $ n'
- allTexts = A.mapMaybe maybeText childrenArr
- pure $ note QTextNotFoundError $ A.index allTexts idx
- queryAll ∷ String → QueryRunner (NonEmptyList Node)
- queryAll selector node = ExceptT $ do
- maybeNodes <- queryAllNodes selector node
- pure $ note (QNodeListNotFoundError selector) maybeNodes
- subQueryMany ∷ ∀ a. QueryRunner a → String → QueryRunner (NonEmptyList a)
- subQueryMany query selector n = traverse query =<< queryAll selector n
- subQueryOne ∷ ∀ a. QueryRunner a → String → QueryRunner a
- subQueryOne query selector n = query =<< queryOne selector n
- chooseOne ∷ ∀ a t m. Monad m ⇒ (t → ExceptT QueryError m a) → (t → ExceptT QueryError m a) → (t → ExceptT QueryError m a)
- chooseOne q1 q2 n = do
- maybeN1 <- (ignoreErrors <<< q1) n
- maybeN2 <- (ignoreErrors <<< q2) n
- case maybeN1 <|> maybeN2 of
- Nothing -> throwError QChooseError
- Just n' -> pure n'
- chooseOne3 ∷ ∀ a t m.
- Monad m
- ⇒ (t → ExceptT QueryError m a)
- → (t → ExceptT QueryError m a)
- → (t → ExceptT QueryError m a)
- → (t → ExceptT QueryError m a)
- chooseOne3 q1 q2 q3 n = do
- maybeN1 <- (ignoreErrors <<< q1) n
- maybeN2 <- (ignoreErrors <<< q2) n
- maybeN3 <- (ignoreErrors <<< q3) n
- case maybeN1 <|> maybeN2 <|> maybeN3 of
- Nothing -> throwError QChooseError
- Just n' -> pure n'
|