Skip to content

Commit 62e869a

Browse files
Merge pull request #30 from timo-schmid/endpoint-search-streaming
Endpoints Search.repositories and Search.users
2 parents 4b2a4aa + 7039e7a commit 62e869a

20 files changed

+11336
-203
lines changed

Diff for: build.sbt

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ lazy val commonSettings = Seq(
8989

9090
"io.circe" %% "circe-core" % circeV,
9191
"io.circe" %% "circe-literal" % circeV % Test,
92+
"io.circe" %% "circe-parser" % circeV % Test,
9293
// "io.circe" %% "circe-generic" % circeV,
93-
// "io.circe" %% "circe-parser" % circeV,
9494

9595
// "io.chrisdavenport" %% "log4cats-core" % log4catsV,
9696
//
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package io.chrisdavenport.github.data
2+
3+
sealed trait Order
4+
5+
object Order {
6+
7+
case object Ascending extends Order
8+
case object Descending extends Order
9+
10+
def toOptionalParam(order: Order): Option[String] =
11+
order match {
12+
case Ascending => Some("asc")
13+
case Descending => Some("desc")
14+
}
15+
16+
}

Diff for: core/src/main/scala/io/chrisdavenport/github/data/SearchResult.scala

-36
Original file line numberDiff line numberDiff line change
@@ -14,40 +14,4 @@ object SearchResult {
1414
cursor.downField("items").as[List[A]]
1515
).mapN(SearchResult.apply)
1616

17-
sealed trait Sort
18-
19-
object Sort {
20-
21-
case object Stars extends Sort
22-
case object Forks extends Sort
23-
case object HelpWantedIssues extends Sort
24-
case object Updated extends Sort
25-
case object BestMatch extends Sort
26-
27-
def toOptionalParam(sort: Sort): Option[String] =
28-
sort match {
29-
case Stars => Some("stars")
30-
case Forks => Some("forks")
31-
case HelpWantedIssues => Some("help-wanted-issues")
32-
case Updated => Some("updated")
33-
case BestMatch => None
34-
}
35-
36-
}
37-
38-
sealed trait Order
39-
40-
object Order {
41-
42-
case object Ascending extends Order
43-
case object Descending extends Order
44-
45-
def toOptionalParam(order: Order): Option[String] =
46-
order match {
47-
case Ascending => Some("asc")
48-
case Descending => Some("desc")
49-
}
50-
51-
}
52-
5317
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package io.chrisdavenport.github.data
2+
3+
sealed trait Sort
4+
5+
object Sort {
6+
7+
case object BestMatch extends Repository with User
8+
case object Stars extends Repository
9+
case object Forks extends Repository
10+
case object HelpWantedIssues extends Repository
11+
case object Updated extends Repository
12+
case object Followers extends User
13+
case object Repositories extends User
14+
case object Joined extends User
15+
16+
sealed trait Repository extends io.chrisdavenport.github.data.Sort
17+
sealed trait User extends io.chrisdavenport.github.data.Sort
18+
19+
def toOptionalParam(sort: Sort): Option[String] =
20+
sort match {
21+
case BestMatch => None
22+
case Stars => Some("stars")
23+
case Forks => Some("forks")
24+
case HelpWantedIssues => Some("help-wanted-issues")
25+
case Updated => Some("updated")
26+
case Followers => Some("followers")
27+
case Repositories => Some("repositories")
28+
case Joined => Some("joined")
29+
}
30+
31+
}

Diff for: core/src/main/scala/io/chrisdavenport/github/data/Teams.scala

-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
package io.chrisdavenport.github.data
22

3-
import cats.implicits._
43
import org.http4s.Uri
5-
import org.http4s.circe._
6-
import java.time.Instant
74
import io.circe._
85
import io.circe.syntax._
96

Diff for: core/src/main/scala/io/chrisdavenport/github/data/Users.scala

+10-10
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,15 @@ object Users {
9090
name: Option[String],
9191
email: Option[String],
9292
company: Option[String],
93-
createdAt: Instant,
93+
createdAt: Option[Instant],
9494
blog: Option[String],
9595
location: Option[String],
9696
bio: Option[String],
9797
hireable: Option[Boolean],
98-
publicRepos: Int,
99-
publicGists: Int,
100-
followers: Int,
101-
following: Int,
98+
publicRepos: Option[Int],
99+
publicGists: Option[Int],
100+
followers: Option[Int],
101+
following: Option[Int],
102102
uri: Uri,
103103
htmlUri: Uri,
104104
avatarUri: Uri,
@@ -112,15 +112,15 @@ object Users {
112112
c.downField("name").as[Option[String]],
113113
c.downField("email").as[Option[String]],
114114
c.downField("company").as[Option[String]],
115-
c.downField("created_at").as[Instant],
115+
c.downField("created_at").as[Option[Instant]],
116116
c.downField("blog").as[Option[String]],
117117
c.downField("location").as[Option[String]],
118118
c.downField("bio").as[Option[String]],
119119
c.downField("hireable").as[Option[Boolean]],
120-
c.downField("public_repos").as[Int],
121-
c.downField("public_gists").as[Int],
122-
c.downField("followers").as[Int],
123-
c.downField("following").as[Int],
120+
c.downField("public_repos").as[Option[Int]],
121+
c.downField("public_gists").as[Option[Int]],
122+
c.downField("followers").as[Option[Int]],
123+
c.downField("following").as[Option[Int]],
124124
c.downField("url").as[Uri],
125125
c.downField("html_url").as[Uri],
126126
c.downField("avatar_url").as[Uri]

Diff for: core/src/main/scala/io/chrisdavenport/github/endpoints/Search.scala

+34-7
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ package io.chrisdavenport.github.endpoints
22

33
import cats.data._
44
import cats.effect._
5+
import fs2.Stream
56
import io.chrisdavenport.github.data.Repositories._
6-
import org.http4s._
77
import org.http4s.implicits._
88
import org.http4s.client.Client
99
import io.chrisdavenport.github.Auth
10-
import io.chrisdavenport.github.data.SearchResult
11-
import io.chrisdavenport.github.data.SearchResult.{Order, Sort}
10+
import io.chrisdavenport.github.data.{Order, SearchResult, Sort}
11+
import io.chrisdavenport.github.data.Users.User
1212
import io.chrisdavenport.github.internals.GithubMedia._
1313
import io.chrisdavenport.github.internals.RequestConstructor
1414

@@ -17,20 +17,47 @@ object Search {
1717
/**
1818
* Repository Search Endpoint
1919
* https://developer.github.com/v3/search/#search-repositories
20+
* @param q The search query string
21+
* @param sort The sorting method
22+
* @param order The sorting order
23+
* @param auth The authentication mechanism
24+
* @tparam F The effect type
2025
*/
2126
def repository[F[_]: Sync](
2227
q: String,
23-
sort: Option[Sort],
28+
sort: Option[Sort.Repository],
2429
order: Option[Order],
2530
auth: Option[Auth]
26-
): Kleisli[F, Client[F], SearchResult[Repo]] =
27-
RequestConstructor.runRequestWithNoBody[F, SearchResult[Repo]](
31+
): Kleisli[Stream[F, *], Client[F], SearchResult[Repo]] =
32+
RequestConstructor.runPaginatedRequest[F, SearchResult[Repo]](
2833
auth,
29-
Method.GET,
3034
(uri"search" / "repositories")
3135
.withQueryParam("q", q)
3236
.withOptionQueryParam("sort", sort.flatMap(Sort.toOptionalParam))
3337
.withOptionQueryParam("order", order.flatMap(Order.toOptionalParam))
3438
)
3539

40+
/**
41+
* User Search Endpoint
42+
* https://developer.github.com/v3/search/#search-users
43+
* @param q The search query string
44+
* @param sort The sorting method
45+
* @param order The sorting order
46+
* @param auth The authentication mechanism
47+
* @tparam F The effect type
48+
*/
49+
def users[F[_]: Sync](
50+
q: String,
51+
sort: Option[Sort.User],
52+
order: Option[Order],
53+
auth: Option[Auth]
54+
): Kleisli[Stream[F, *], Client[F], SearchResult[User]] =
55+
RequestConstructor.runPaginatedRequest[F, SearchResult[User]](
56+
auth,
57+
(uri"search" / "users")
58+
.withQueryParam("q", q)
59+
.withOptionQueryParam("sort", sort.flatMap(Sort.toOptionalParam))
60+
.withOptionQueryParam("order", order.flatMap(Order.toOptionalParam))
61+
)
62+
3663
}

Diff for: core/src/main/scala/io/chrisdavenport/github/internals/RequestConstructor.scala

+11-3
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,17 @@ object RequestConstructor {
5252
)
5353
}
5454

55-
final class GithubError private[RequestConstructor] (val status: Status, val body: String) extends Exception(
56-
s"Github Error Occured- Status:$status Body: $body"
57-
)
55+
final class GithubError private[github] (val status: Status, val body: String) extends Exception(
56+
s"Github Error Occured - Status: $status Body: $body"
57+
) {
58+
59+
override def equals(obj: Any): Boolean =
60+
obj match {
61+
case other: GithubError if other.status === status && other.body === body => true
62+
case _ => false
63+
}
64+
65+
}
5866

5967
private val RE_LINK: Regex = "[\\s]*<(.*)>; rel=\"(.*)\"".r
6068

0 commit comments

Comments
 (0)