QueryRunner.purs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. module LinkedIn.QueryRunner where
  2. import Prelude
  3. import Control.Monad.Except (ExceptT(..), except, mapExceptT, runExceptT)
  4. import Data.Argonaut.Encode (class EncodeJson)
  5. import Data.Argonaut.Encode.Generic (genericEncodeJson)
  6. import Data.Array as A
  7. import Data.Either (Either(..), note)
  8. import Data.Generic.Rep (class Generic)
  9. import Data.List.Types (NonEmptyList)
  10. import Data.Maybe (Maybe(..))
  11. import Data.Show.Generic (genericShow)
  12. import Effect (Effect)
  13. import LinkedIn.Queryable (class Queryable, getChildrenArray, queryAllNodes, queryOneNode, toNode)
  14. import Web.DOM (Node)
  15. import Web.DOM.Text as T
  16. data QueryError =
  17. QNodeNotFoundError String
  18. | QNodeListNotFoundError String
  19. | QNodeUnexpectedType String String
  20. | QTextNotFoundError
  21. | QChooseError
  22. instance EncodeJson QueryError where
  23. encodeJson a = genericEncodeJson a
  24. derive instance Generic QueryError _
  25. derive instance Eq QueryError
  26. instance Show QueryError where
  27. show = genericShow
  28. instance Semigroup QueryError where
  29. append a _ = a
  30. type Query q a = q → ExceptT QueryError Effect a
  31. runQuery ∷ ∀ a. ExceptT QueryError Effect a → Effect (Either QueryError a)
  32. runQuery = runExceptT
  33. ignoreNotFound ∷ ∀ a f. Functor f ⇒ ExceptT QueryError f a → ExceptT QueryError f (Maybe a)
  34. ignoreNotFound = mapExceptT (map ignoreNotFound')
  35. where
  36. ignoreNotFound' = case _ of
  37. (Left (QNodeNotFoundError _ )) -> Right Nothing
  38. (Left (QNodeListNotFoundError _ )) -> Right Nothing
  39. (Left q) -> Left q
  40. (Right n') -> Right (Just n')
  41. ignoreErrors ∷ ∀ a f. Functor f ⇒ ExceptT QueryError f a → ExceptT QueryError f (Maybe a)
  42. ignoreErrors = mapExceptT (map ignoreErrors')
  43. where
  44. ignoreErrors' = case _ of
  45. (Left _) -> Right Nothing
  46. (Right n') -> Right (Just n')
  47. querySelf ∷ forall q. Queryable q => Query q Node
  48. querySelf node = except $ Right $ toNode node
  49. queryOne ∷ forall q. Queryable q => String → Query q Node
  50. queryOne selector node = ExceptT $ do
  51. maybeNode <- queryOneNode selector node
  52. pure $ note (QNodeNotFoundError selector) maybeNode
  53. queryText ∷ forall q. Queryable q => Int -> Query q Node
  54. queryText idx n = ExceptT $ do
  55. childrenArr <- getChildrenArray n
  56. let
  57. maybeText n' = do
  58. _ <- T.fromNode n'
  59. pure $ n'
  60. allTexts = A.mapMaybe maybeText childrenArr
  61. pure $ note QTextNotFoundError $ A.index allTexts idx
  62. queryAll ∷ forall q. Queryable q => String → Query q (NonEmptyList Node)
  63. queryAll selector node = ExceptT $ do
  64. maybeNodes <- queryAllNodes selector node
  65. pure $ note (QNodeListNotFoundError selector) maybeNodes