• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ruippeixotog / scala-scraper / 11309684064

12 Oct 2024 11:53PM UTC coverage: 86.667%. Remained the same
11309684064

push

web-flow
Update sbt-pgp to 2.3.0 (#517)

299 of 345 relevant lines covered (86.67%)

2.01 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.63
/core/src/main/scala/net/ruippeixotog/scalascraper/dsl/ScrapingOps.scala
1
package net.ruippeixotog.scalascraper.dsl
2

3
import net.ruippeixotog.scalascraper.model.{Element, ElementQuery}
4
import net.ruippeixotog.scalascraper.scraper.{HtmlExtractor, HtmlValidator}
5
import net.ruippeixotog.scalascraper.util._
6
import scala.util.Try
7

8
import scalaz._
9
import scalaz.syntax.FunctorSyntax
10

11
trait ScrapingOps extends syntax.ToIdOps with std.AllInstances with IdInstances {
12

13
  class ElementsScrapingOps[F[_]: Functor, A, E <: Element](val self: F[A])(implicit toQuery: ToQuery.Aux[A, E])
14
      extends FunctorSyntax[F] {
15

16
    override def F: Functor[F] = Functor[F]
4✔
17

18
    @inline implicit private[this] def aToQuery(a: A): ElementQuery[E] = toQuery(a)
4✔
19

20
    def extract[B](extractor: HtmlExtractor[E, B]) = self.map(extractor.extract(_))
4✔
21

22
    @inline final def apply[B](extractor: HtmlExtractor[E, B]) = extract(extractor)
×
23

24
    @inline final def >>[B](extractor: HtmlExtractor[E, B]) = extract(extractor)
4✔
25

26
    def >>[B, C](extractor1: HtmlExtractor[E, B], extractor2: HtmlExtractor[E, C]) =
27
      self.map { doc => (extractor1.extract(doc), extractor2.extract(doc)) }
2✔
28

29
    def >>[B, C, D](extractor1: HtmlExtractor[E, B], extractor2: HtmlExtractor[E, C], extractor3: HtmlExtractor[E, D]) =
30
      self.map { doc => (extractor1.extract(doc), extractor2.extract(doc), extractor3.extract(doc)) }
2✔
31

32
    def tryExtract[B](extractor: HtmlExtractor[E, B]) =
33
      self.map { doc => Try(extractor.extract(doc)).toOption }
2✔
34

35
    @inline final def tryApply[B](extractor: HtmlExtractor[E, B]) = tryExtract(extractor)
×
36

37
    @inline final def >?>[B](extractor: HtmlExtractor[E, B]) = tryExtract(extractor)
2✔
38

39
    def >?>[B, C](extractor1: HtmlExtractor[E, B], extractor2: HtmlExtractor[E, C]) =
40
      self.map { doc => (Try(extractor1.extract(doc)).toOption, Try(extractor2.extract(doc)).toOption) }
2✔
41

42
    def >?>[B, C, D](
43
        extractor1: HtmlExtractor[E, B],
44
        extractor2: HtmlExtractor[E, C],
45
        extractor3: HtmlExtractor[E, D]
46
    ) =
47
      self.map { doc =>
2✔
48
        val e1 = Try(extractor1.extract(doc)).toOption
2✔
49
        val e2 = Try(extractor2.extract(doc)).toOption
2✔
50
        val e3 = Try(extractor3.extract(doc)).toOption
2✔
51
        (e1, e2, e3)
2✔
52
      }
53

54
    def successIf[R](success: HtmlValidator[E, _]): F[Either[Unit, A]] =
55
      self.map { doc => if (success.matches(doc)) Right(doc) else Left(()) }
4✔
56

57
    def errorIf[R](error: HtmlValidator[E, R]): F[Either[R, A]] =
58
      self.map { doc => if (error.matches(doc)) Left(error.result.get) else Right(doc) }
4✔
59

60
    def errorIf[R](errors: Seq[HtmlValidator[E, R]]): F[Either[R, A]] = {
61
      self.map { doc =>
2✔
62
        errors.foldLeft[Either[R, A]](Right(doc)) { (res, error) =>
2✔
63
          if (res.isLeft || !error.matches(doc)) res else Left(error.result.get)
2✔
64
        }
65
      }
66
    }
67

68
    def validateWith[R](
69
        success: HtmlValidator[E, _],
70
        errors: Seq[HtmlValidator[E, R]],
71
        default: => R = throw new ValidationException
72
    ): F[Either[R, A]] = {
73

74
      self.map { doc =>
2✔
75
        if (success.matches(doc)) Right(doc)
×
76
        else
77
          errors
78
            .foldLeft[Either[R, A]](Right(doc)) { (res, error) =>
2✔
79
              if (res.isLeft || !error.matches(doc)) res else Left(error.result.get)
2✔
80
            }
81
            .fold(Left.apply, _ => Left(default))
2✔
82
      }
83
    }
84

85
    @inline final def >/~[R](success: HtmlValidator[E, _]) = successIf(success)
4✔
86

87
    @inline final def >/~[R](success: HtmlValidator[E, _], error: HtmlValidator[E, R]) =
88
      validateWith(success, error :: Nil)
2✔
89

90
    @inline final def >/~[R](success: HtmlValidator[E, _], errors: Seq[HtmlValidator[E, R]]) =
91
      validateWith(success, errors)
1✔
92

93
    @inline final def >/~[R](success: HtmlValidator[E, _], error: HtmlValidator[E, R], default: R) =
94
      validateWith(success, error :: Nil, default)
2✔
95

96
    @inline final def >/~[R](success: HtmlValidator[E, _], errors: Seq[HtmlValidator[E, R]], default: R) =
97
      validateWith(success, errors, default)
2✔
98
  }
99

100
  implicit def deepFunctorOps[FA, A, E <: Element](
101
      self: FA
102
  )(implicit df: DeepFunctor.AuxA[FA, A], conv: ToQuery.Aux[A, E]): ElementsScrapingOps[df.F, A, E] =
103
    new ElementsScrapingOps[df.F, A, E](df.asF(self))(df.f, conv)
4✔
104
}
105

106
object ScrapingOps extends ScrapingOps
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc