Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ let package = Package(
)
],
dependencies: [
.package(
url: "https://github.com/swift-primitives/swift-async-primitives.git",
branch: "main"
),
.package(
url: "https://github.com/swift-primitives/swift-either-primitives.git",
branch: "main"
),
.package(
url: "https://github.com/swift-standards/swift-github-standard.git",
branch: "main"
Expand All @@ -27,6 +35,14 @@ let package = Package(
.target(
name: "GitHub",
dependencies: [
.product(
name: "Async Lifecycle Primitives",
package: "swift-async-primitives"
),
.product(
name: "Either Primitives",
package: "swift-either-primitives"
),
.product(
name: "GitHub Standard",
package: "swift-github-standard"
Expand Down
24 changes: 14 additions & 10 deletions Sources/GitHub/GitHub.Organization.Repositories.Client+all.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ extension GitHub.Organization.Repositories.Client {
limit: GitHub.Organization.Repositories.Traversal.Limit,
duplicate: GitHub.Organization.Repositories.Traversal.Duplicate,
order: GitHub.Organization.Repositories.Traversal.Order
) async throws(GitHub.Organization.Repositories.Traversal.Error<Failure>) -> [GitHub.Repository
) async throws(Either<Async.Lifecycle.Error, GitHub.Organization.Repositories.Traversal.Error>)
-> [GitHub.Repository
.Summary]
{
var repositories: [GitHub.Repository.Summary] = []
Expand All @@ -14,21 +15,24 @@ extension GitHub.Organization.Repositories.Client {
var pages: UInt = 0

while let request = current {
guard !Task<Never, Never>.isCancelled else { throw .cancellation }
guard !Task<Never, Never>.isCancelled else { throw .left(.cancelled) }
// swift-linter:disable:next raw value access
// REASON: same-package implementation comparing against the
// Traversal.Limit boundary type's own raw page count.
guard pages < limit.pages.rawValue else { throw .pages }
guard requests.insert(request).inserted else { throw .cycle }
guard pages < limit.pages.rawValue else { throw .right(.pages) }
guard requests.insert(request).inserted else { throw .right(.cycle) }

let page: Page
do throws(Failure) {
let page: GitHub.Organization.Repositories.Page
do throws(Either<Async.Lifecycle.Error, GitHub.Organization.Repositories.Page.Error>) {
page = try await self.page(request)
} catch {
throw .client(error)
switch error {
case .left(let error): throw .left(error)
case .right(let error): throw .right(.page(error))
}
}

guard !Task<Never, Never>.isCancelled else { throw .cancellation }
guard !Task<Never, Never>.isCancelled else { throw .left(.cancelled) }
pages += 1

for repository in page.response.repositories {
Expand All @@ -51,7 +55,7 @@ extension GitHub.Organization.Repositories.Client {

case .reject:
guard positions[repository.id] == nil else {
throw .duplicate(repository.id)
throw .right(.duplicate(repository.id))
}
positions[repository.id] = repositories.endIndex
repositories.append(repository)
Expand All @@ -61,7 +65,7 @@ extension GitHub.Organization.Repositories.Client {
// REASON: same-package implementation comparing against the
// Traversal.Limit boundary type's own raw item count.
guard UInt(repositories.count) <= limit.items.rawValue else {
throw .items
throw .right(.items)
}
}

Expand Down
10 changes: 7 additions & 3 deletions Sources/GitHub/GitHub.Organization.Repositories.Client.swift
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
extension GitHub.Organization.Repositories {
public struct Client<Failure: Swift.Error>: Sendable {
public var page: @Sendable (Request) async throws(Failure) -> Page
public struct Client: Sendable {
public var page:
@Sendable (Request) async throws(Either<Async.Lifecycle.Error, Page.Error>) -> Page

public init(
page: @escaping @Sendable (Request) async throws(Failure) -> Page
page:
@escaping @Sendable (Request) async throws(Either<
Async.Lifecycle.Error, Page.Error
>) -> Page
) {
self.page = page
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
extension GitHub.Organization.Repositories.Page {
public enum Error: Swift.Error, Sendable, Equatable, Hashable {
case transport
case malformedResponse
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
extension GitHub.Organization.Repositories.Client {
extension GitHub.Organization.Repositories {
public struct Page: Equatable, Sendable {
public let response: GitHub.Organization.Repositories.Response
public let next: GitHub.Organization.Repositories.Request?
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
extension GitHub.Organization.Repositories.Traversal {
public enum Error<Failure: Swift.Error>: Swift.Error, Sendable {
case cancellation
case client(Failure)
public enum Error: Swift.Error, Sendable {
case cycle
case duplicate(GitHub.Repository.ID)
case items
case page(GitHub.Organization.Repositories.Page.Error)
case pages
}
}

extension GitHub.Organization.Repositories.Traversal.Error: Equatable
where Failure: Equatable {}
extension GitHub.Organization.Repositories.Traversal.Error: Equatable {}
21 changes: 12 additions & 9 deletions Sources/GitHub/GitHub.Repository.Stargazers.Client+all.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ extension GitHub.Repository.Stargazers.Client {
public func all(
_ request: GitHub.Repository.Stargazers.Request,
limit: GitHub.Repository.Stargazers.Traversal.Limit
) async throws(GitHub.Repository.Stargazers.Traversal.Error<Failure>)
) async throws(Either<Async.Lifecycle.Error, GitHub.Repository.Stargazers.Traversal.Error>)
-> [GitHub.Repository.Stargazers.Stargazer]
{
var stargazers: [GitHub.Repository.Stargazers.Stargazer] = []
Expand All @@ -11,29 +11,32 @@ extension GitHub.Repository.Stargazers.Client {
var pages: UInt = 0

while let request = current {
guard !Task<Never, Never>.isCancelled else { throw .cancellation }
guard !Task<Never, Never>.isCancelled else { throw .left(.cancelled) }
// swift-linter:disable:next raw value access
// REASON: same-package traversal-limit boundary — the page counter
// is compared against the limit newtype's own raw magnitude.
guard pages < limit.pages.rawValue else { throw .pages }
guard requests.insert(request).inserted else { throw .cycle }
guard pages < limit.pages.rawValue else { throw .right(.pages) }
guard requests.insert(request).inserted else { throw .right(.cycle) }

let page: Page
do throws(Failure) {
let page: GitHub.Repository.Stargazers.Page
do throws(Either<Async.Lifecycle.Error, GitHub.Repository.Stargazers.Page.Error>) {
page = try await self.page(request)
} catch {
throw .client(error)
switch error {
case .left(let error): throw .left(error)
case .right(let error): throw .right(.page(error))
}
}

guard !Task<Never, Never>.isCancelled else { throw .cancellation }
guard !Task<Never, Never>.isCancelled else { throw .left(.cancelled) }
pages += 1
stargazers.append(contentsOf: page.response.stargazers)

// swift-linter:disable:next raw value access
// REASON: same-package traversal-limit boundary — the accumulated
// item count is compared against the limit newtype's raw magnitude.
guard UInt(stargazers.count) <= limit.items.rawValue else {
throw .items
throw .right(.items)
}
current = page.next
}
Expand Down
10 changes: 7 additions & 3 deletions Sources/GitHub/GitHub.Repository.Stargazers.Client.swift
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
extension GitHub.Repository.Stargazers {
public struct Client<Failure: Swift.Error>: Sendable {
public var page: @Sendable (Request) async throws(Failure) -> Page
public struct Client: Sendable {
public var page:
@Sendable (Request) async throws(Either<Async.Lifecycle.Error, Page.Error>) -> Page

public init(
page: @escaping @Sendable (Request) async throws(Failure) -> Page
page:
@escaping @Sendable (Request) async throws(Either<
Async.Lifecycle.Error, Page.Error
>) -> Page
) {
self.page = page
}
Expand Down
7 changes: 7 additions & 0 deletions Sources/GitHub/GitHub.Repository.Stargazers.Page.Error.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
extension GitHub.Repository.Stargazers.Page {
public enum Error: Swift.Error, Sendable, Equatable, Hashable {
case transport
case rejected
case malformedResponse
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
extension GitHub.Repository.Stargazers.Client {
extension GitHub.Repository.Stargazers {
public struct Page: Equatable, Sendable {
public let response: GitHub.Repository.Stargazers.Response
public let next: GitHub.Repository.Stargazers.Request?
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
extension GitHub.Repository.Stargazers.Traversal {
public enum Error<Failure: Swift.Error>: Swift.Error, Sendable {
case cancellation
case client(Failure)
public enum Error: Swift.Error, Sendable {
case cycle
case items
case page(GitHub.Repository.Stargazers.Page.Error)
case pages
}
}

extension GitHub.Repository.Stargazers.Traversal.Error: Equatable
where Failure: Equatable {}
extension GitHub.Repository.Stargazers.Traversal.Error: Equatable {}
21 changes: 12 additions & 9 deletions Sources/GitHub/GitHub.User.Repositories.Client+all.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ extension GitHub.User.Repositories.Client {
public func all(
_ request: GitHub.User.Repositories.Request,
limit: GitHub.User.Repositories.Traversal.Limit
) async throws(GitHub.User.Repositories.Traversal.Error<Failure>)
) async throws(Either<Async.Lifecycle.Error, GitHub.User.Repositories.Traversal.Error>)
-> [GitHub.Repository.Metadata]
{
var repositories: [GitHub.Repository.Metadata] = []
Expand All @@ -11,29 +11,32 @@ extension GitHub.User.Repositories.Client {
var pages: UInt = 0

while let request = current {
guard !Task<Never, Never>.isCancelled else { throw .cancellation }
guard !Task<Never, Never>.isCancelled else { throw .left(.cancelled) }
// swift-linter:disable:next raw value access
// REASON: same-package traversal-limit boundary — the page counter
// is compared against the limit newtype's own raw magnitude.
guard pages < limit.pages.rawValue else { throw .pages }
guard requests.insert(request).inserted else { throw .cycle }
guard pages < limit.pages.rawValue else { throw .right(.pages) }
guard requests.insert(request).inserted else { throw .right(.cycle) }

let page: Page
do throws(Failure) {
let page: GitHub.User.Repositories.Page
do throws(Either<Async.Lifecycle.Error, GitHub.User.Repositories.Page.Error>) {
page = try await self.page(request)
} catch {
throw .client(error)
switch error {
case .left(let error): throw .left(error)
case .right(let error): throw .right(.page(error))
}
}

guard !Task<Never, Never>.isCancelled else { throw .cancellation }
guard !Task<Never, Never>.isCancelled else { throw .left(.cancelled) }
pages += 1
repositories.append(contentsOf: page.response.repositories)

// swift-linter:disable:next raw value access
// REASON: same-package traversal-limit boundary — the accumulated
// item count is compared against the limit newtype's raw magnitude.
guard UInt(repositories.count) <= limit.items.rawValue else {
throw .items
throw .right(.items)
}
current = page.next
}
Expand Down
10 changes: 7 additions & 3 deletions Sources/GitHub/GitHub.User.Repositories.Client.swift
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
extension GitHub.User.Repositories {
public struct Client<Failure: Swift.Error>: Sendable {
public var page: @Sendable (Request) async throws(Failure) -> Page
public struct Client: Sendable {
public var page:
@Sendable (Request) async throws(Either<Async.Lifecycle.Error, Page.Error>) -> Page

public init(
page: @escaping @Sendable (Request) async throws(Failure) -> Page
page:
@escaping @Sendable (Request) async throws(Either<
Async.Lifecycle.Error, Page.Error
>) -> Page
) {
self.page = page
}
Expand Down
9 changes: 9 additions & 0 deletions Sources/GitHub/GitHub.User.Repositories.Page.Error.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
extension GitHub.User.Repositories.Page {
public enum Error: Swift.Error, Sendable, Equatable, Hashable {
case transport
case authentication
case forbidden
case rejected
case malformedResponse
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
extension GitHub.User.Repositories.Client {
extension GitHub.User.Repositories {
public struct Page: Equatable, Sendable {
public let response: GitHub.User.Repositories.Response
public let next: GitHub.User.Repositories.Request?
Expand Down
8 changes: 3 additions & 5 deletions Sources/GitHub/GitHub.User.Repositories.Traversal.Error.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
extension GitHub.User.Repositories.Traversal {
public enum Error<Failure: Swift.Error>: Swift.Error, Sendable {
case cancellation
case client(Failure)
public enum Error: Swift.Error, Sendable {
case cycle
case items
case page(GitHub.User.Repositories.Page.Error)
case pages
}
}

extension GitHub.User.Repositories.Traversal.Error: Equatable
where Failure: Equatable {}
extension GitHub.User.Repositories.Traversal.Error: Equatable {}
2 changes: 2 additions & 0 deletions Sources/GitHub/exports.swift
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
@_exported public import Async_Lifecycle_Primitives
@_exported public import Either_Primitives
@_exported public import GitHub_Standard
Loading
Loading