Quellcode durchsuchen

Add URL path parser

jherve vor 1 Jahr
Ursprung
Commit
9c82bdac87
3 geänderte Dateien mit 166 neuen und 0 gelöschten Zeilen
  1. 1 0
      spago.dhall
  2. 107 0
      src/LinkedIn/PageUrl.purs
  3. 58 0
      test/PageUrl.purs

+ 1 - 0
spago.dhall

@@ -14,6 +14,7 @@ You can edit this file as you like.
   , "enums"
   , "foldable-traversable"
   , "free"
+  , "int64"
   , "integers"
   , "lists"
   , "maybe"

+ 107 - 0
src/LinkedIn/PageUrl.purs

@@ -0,0 +1,107 @@
+module LinkedIn.PageUrl (PageUrl(..), JobOfferId(..), pageUrlP) where
+
+import Prelude
+
+import Control.Alt ((<|>))
+import Data.Generic.Rep (class Generic)
+import Data.Int64 (Int64)
+import Data.Int64 as I64
+import Data.Maybe (Maybe(..))
+import Data.Show.Generic (genericShow)
+import Data.String (codePointFromChar)
+import Parsing (Parser, fail)
+import Parsing.Combinators (try)
+import Parsing.String (char, string)
+import Parsing.String.Basic (takeWhile)
+
+newtype JobOfferId = JobOfferId Int64
+
+derive instance Eq JobOfferId
+derive instance Generic JobOfferId _
+instance Show JobOfferId where
+  show = genericShow
+
+data PageUrl =
+  UrlProfileMain String
+  | UrlProjects String
+  | UrlSkills String
+  | UrlWorkExperience String
+  | UrlEducation String
+  | UrlLanguage String
+  | UrlJobOffer JobOfferId
+
+derive instance Eq PageUrl
+derive instance Generic PageUrl _
+instance Show PageUrl where
+  show = genericShow
+
+pathComponentP :: String -> Parser String Unit
+pathComponentP s = do
+  _ <- char('/')
+  _ <- string(s)
+  pure unit
+
+unknownPathComponentP ∷ Parser String String
+unknownPathComponentP = do
+  _ <- char('/')
+  takeWhile (\c -> c /= codePointFromChar '/')
+
+profileMainP ∷ Parser String PageUrl
+profileMainP = do
+  _ <- pathComponentP("in")
+  name <- unknownPathComponentP
+  pure $ UrlProfileMain name
+
+detailsP ∷ String -> Parser String String
+detailsP s = do
+  _ <- pathComponentP("in")
+  name <- unknownPathComponentP
+  _ <- pathComponentP("details")
+  _ <- pathComponentP(s)
+  _ <- char('/')
+
+  pure name
+
+projectP ∷ Parser String PageUrl
+projectP = do
+  name <- detailsP("projects")
+  pure $ UrlProjects name
+
+skillsP ∷ Parser String PageUrl
+skillsP = do
+  name <- detailsP("skills")
+  pure $ UrlSkills name
+
+workExperienceP ∷ Parser String PageUrl
+workExperienceP = do
+  name <- detailsP("experience")
+  pure $ UrlWorkExperience name
+
+educationP ∷ Parser String PageUrl
+educationP = do
+  name <- detailsP("education")
+  pure $ UrlEducation name
+
+languagesP ∷ Parser String PageUrl
+languagesP = do
+  name <- detailsP("languages")
+  pure $ UrlLanguage name
+
+jobViewP :: Parser String PageUrl
+jobViewP = do
+  _ <- pathComponentP("jobs")
+  _ <- pathComponentP("view")
+  id <- unknownPathComponentP
+
+  case I64.fromString id of
+    Nothing -> fail "Not an int"
+    Just i -> pure $ UrlJobOffer (JobOfferId i)
+
+pageUrlP ∷ Parser String PageUrl
+pageUrlP = try projectP
+  <|> try skillsP
+  <|> try workExperienceP
+  <|> try educationP
+  <|> try languagesP
+  <|> try profileMainP
+  <|> try jobViewP

+ 58 - 0
test/PageUrl.purs

@@ -0,0 +1,58 @@
+module Test.PageUrl
+  ( main
+  )
+  where
+
+import Prelude
+
+import Data.Either (Either(..), isLeft)
+import Data.Int64 (Int64)
+import Data.Int64 as I64
+import Data.Maybe (fromJust)
+import Effect (Effect)
+import LinkedIn.PageUrl (JobOfferId(..), PageUrl(..), pageUrlP)
+import Parsing (runParser)
+import Partial.Unsafe (unsafePartial)
+import Test.Assert (assert, assertEqual)
+
+toI64 ∷ String → Int64
+toI64 s = unsafePartial $ fromJust $ I64.fromString s
+
+main :: Effect Unit
+main = do
+  assertEqual {
+    actual: runParser "/in/username/details/projects/" pageUrlP,
+    expected: Right(UrlProjects "username")
+  }
+
+  assertEqual {
+    actual: runParser "/in/username/details/skills/" pageUrlP,
+    expected: Right(UrlSkills "username")
+  }
+
+  assertEqual {
+    actual: runParser "/in/username/details/experience/" pageUrlP,
+    expected: Right(UrlWorkExperience "username")
+  }
+
+  assertEqual {
+    actual: runParser "/in/username/details/languages/" pageUrlP,
+    expected: Right(UrlLanguage "username")
+  }
+
+  assertEqual {
+    actual: runParser "/in/username/details/education/" pageUrlP,
+    expected: Right(UrlEducation "username")
+  }
+
+  assertEqual {
+    actual: runParser "/jobs/view/3764313323/" pageUrlP,
+    expected: Right(UrlJobOffer (JobOfferId (toI64 "3764313323")))
+  }
+
+  assertEqual {
+    actual: runParser "/in/username/" pageUrlP,
+    expected: Right(UrlProfileMain "username")
+  }
+
+  assert $ isLeft $ runParser "/not/an/url/" pageUrlP