Skip to content

Commit

Permalink
Added BLoC code base (#2)
Browse files Browse the repository at this point in the history
## Description

<!--- 
Please include a summary of the change and which issue is fixed. Please
also include relevant motivation and context.
-->

This PR adds the BLoC code base, although it is not yet functional. This
will enable us to begin coding each object according to our internal
roadmap.

## Type of change

<!--- Please delete options that are not relevant. -->

- [x] New feature (non-breaking change which adds functionality)

## Checklist

<!--- Please delete options that are not relevant. -->

- [x] My code follows the code style of this project.
  • Loading branch information
o-nnerb committed Feb 7, 2024
1 parent 4bbb14d commit 071f2cf
Show file tree
Hide file tree
Showing 29 changed files with 1,229 additions and 5 deletions.
6 changes: 3 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ let package = Package(
.library(
name: "Bloc",
targets: ["Bloc"]
),
)
],
dependencies: [
.package(
url: "https://github.com/apple/swift-docc-plugin",
from: "1.3.0"
),
)
],
targets: [
.target(
Expand All @@ -30,6 +30,6 @@ let package = Package(
.testTarget(
name: "BlocTests",
dependencies: ["Bloc"]
),
)
]
)
2 changes: 0 additions & 2 deletions Sources/Bloc/Bloc.swift

This file was deleted.

64 changes: 64 additions & 0 deletions Sources/Bloc/Bloc/Bloc.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
See LICENSE for this package's licensing information.
*/

import Foundation

public class Bloc<Event, State>: BlocBase<State>, BlocEventSink {

// MARK: - Public properties

open var transformer: EventTransformer<Event> {
fatalError("getter:transformer has not been implemented")
}

// MARK: - Private properties

private let lock = Lock()
private let eventController = StreamController<Event>()

// MARK: - Unsafe properties

private var _handlers = [BlocHandler]()
private var _emitters = [BlocEmitter<State>]()

// MARK: - Inits

public override init(_ state: State) {
super.init(state)
}

// MARK: - Open methods

open func onEvent(_ event: Event) {
fatalError("onEvent(_:) has not been implemented")
}

open func onTransition(_ transition: Transition<Event, State>) {
fatalError("onTransition(_:) has not been implemented")
}

open override func close() async throws {
fatalError("close(_:) has not been implemented")
}

// MARK: - Public methods

public func add<E>(_ event: E) {
assert(event is Event, {
"""
\(event) of type \(E.self) is not a value of type \(Event.self)
"""
}())

fatalError("add(_:) has not been implemented")
}

public func on<E>(
_ eventType: E.Type,
_ handler: EventHandler<E, State>,
transformer: EventTransformer<E>? = nil
) {
fatalError("on(_:) has not been implemented")
}
}
67 changes: 67 additions & 0 deletions Sources/Bloc/Bloc/BlocBase.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
See LICENSE for this package's licensing information.
*/

import Foundation

open class BlocBase<State>: StateStreamableSource, Emittable, ErrorSink, @unchecked Sendable {

// MARK: - Open properties

open var observer: BlocObserver {
fatalError("getter:observer has not been implemented")
}

// MARK: - Public properties

public var stream: Stream<State> {
fatalError("getter:stream has not been implemented")
}

public var isClosed: Bool {
fatalError("getter:isClosed has not been implemented")
}

public var state: State {
lock.withLock { _state }
}

// MARK: - Private properties

private let lock = Lock()
private let streamController = StreamController<State>()

// MARK: - Unsafe properties

private var _emitted = false
private var _state: State

// MARK: - Inits

public init(_ state: State) {
defer { observer.onCreate(self) }
self._state = state
}

// MARK: - Open methods

open func onChange(_ change: Change<State>) {
fatalError("onChange(_:) has not been implemented")
}

open func addError(_ error: Error) {
fatalError("addError(_:) has not been implemented")
}

open func onError(_ error: Error) {
fatalError("onError(_:) has not been implemented")
}

open func close() async throws {
fatalError("close() has not been implemented")
}

public func emit(_ state: State) throws {
fatalError("emit(_:) has not been implemented")
}
}
14 changes: 14 additions & 0 deletions Sources/Bloc/Bloc/Cubit.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
See LICENSE for this package's licensing information.
*/

import Foundation

open class Cubit<State>: BlocBase<State> {

// MARK: - Inits

public override init(_ state: State) {
super.init(state)
}
}
12 changes: 12 additions & 0 deletions Sources/Bloc/Bloc/Models/BlocEventSink.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
See LICENSE for this package's licensing information.
*/

import Foundation

public protocol BlocEventSink<Event>: ErrorSink {

associatedtype Event: Sendable

func add<E>(_ event: E)
}
19 changes: 19 additions & 0 deletions Sources/Bloc/Bloc/Models/BlocHandler.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
See LICENSE for this package's licensing information.
*/

import Foundation

struct BlocHandler: Sendable {

let isType: @Sendable (Sendable) -> Bool
let type: Sendable.Type

init(
isType: @escaping @Sendable (Sendable) -> Bool,
type: Sendable.Type
) {
self.isType = isType
self.type = type
}
}
12 changes: 12 additions & 0 deletions Sources/Bloc/Bloc/Models/Closable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
See LICENSE for this package's licensing information.
*/

import Foundation

public protocol Closable: Sendable {

var isClosed: Bool { get }

func close() async throws
}
7 changes: 7 additions & 0 deletions Sources/Bloc/Bloc/Models/DefaultBlocObserver.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
See LICENSE for this package's licensing information.
*/

import Foundation

struct DefaultBlocObserver: BlocObserver {}
12 changes: 12 additions & 0 deletions Sources/Bloc/Bloc/Models/Emittable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
See LICENSE for this package's licensing information.
*/

import Foundation

public protocol Emittable<State>: Sendable {

associatedtype State: Sendable

func emit(_ state: State) throws
}
10 changes: 10 additions & 0 deletions Sources/Bloc/Bloc/Models/ErrorSink.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
See LICENSE for this package's licensing information.
*/

import Foundation

public protocol ErrorSink: Closable {

func addError(_ error: Error)
}
7 changes: 7 additions & 0 deletions Sources/Bloc/Bloc/Models/EventHandler.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
See LICENSE for this package's licensing information.
*/

import Foundation

public typealias EventHandler<Event: Sendable, State: Sendable> = (Event, State) async throws -> Void
7 changes: 7 additions & 0 deletions Sources/Bloc/Bloc/Models/EventMapper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
See LICENSE for this package's licensing information.
*/

import Foundation

public typealias EventMapper<Event: Sendable> = (Event) throws -> Stream<Event>
10 changes: 10 additions & 0 deletions Sources/Bloc/Bloc/Models/EventTransformer.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
See LICENSE for this package's licensing information.
*/

import Foundation

public typealias EventTransformer<Event: Sendable> = (
Stream<Event>,
EventMapper<Event>
) throws -> Stream<Event>
10 changes: 10 additions & 0 deletions Sources/Bloc/Bloc/Models/StateStreamable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
See LICENSE for this package's licensing information.
*/

import Foundation

public protocol StateStreamable<State>: Streamable {

var state: State { get }
}
7 changes: 7 additions & 0 deletions Sources/Bloc/Bloc/Models/StateStreamableSource.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
See LICENSE for this package's licensing information.
*/

import Foundation

public protocol StateStreamableSource<State>: StateStreamable, Closable {}
12 changes: 12 additions & 0 deletions Sources/Bloc/Bloc/Models/Streamable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
See LICENSE for this package's licensing information.
*/

import Foundation

public protocol Streamable<State>: Sendable {

associatedtype State: Sendable

var stream: Stream<State> { get }
}
76 changes: 76 additions & 0 deletions Sources/Bloc/Emitter/BlocEmitter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
See LICENSE for this package's licensing information.
*/

import Foundation

class BlocEmitter<State>: Emitter, @unchecked Sendable {

// MARK: - Internal properties

var result: Void {
get async throws {
fatalError("getter:result has not been implemented")
}
}

var isDone: Bool {
fatalError("getter:isDone has not been implemented")
}

// MARK: - Private properties

private let lock = Lock()
private let completer = AsyncSemaphore()

private let emit: @Sendable (State) -> Void

// MARK: - Unsafe properties

private var _activeTasks = [Task<Void, Error>]()

private var _isCanceled = false
private var _isCompleted = false

// MARK: - Inits

init(_ emit: @escaping @Sendable (State) -> Void) {
self.emit = emit
}

// MARK: - Internal methods

func onEach<T>(
_ stream: Stream<T>,
onData: @escaping @Sendable (T) -> Void,
onError: (@Sendable (Error) -> Void)?
) async throws {
fatalError("onEach(_:onData:onError:) has not been implemented")
}

func forEach<T>(
_ stream: Stream<T>,
onData: @escaping (T) -> State,
onError: (@Sendable (Error) -> Void)?
) async throws {
fatalError("forEach(_:onData:onError:) has not been implemented")
}

func callAsFunction(_ state: State) {
fatalError("callAsFunction(_:) has not been implemented")
}

func cancel() {
fatalError("cancel() has not been implemented")
}

func complete() {
fatalError("complete() has not been implemented")
}

// MARK: - Private methods

private func close() {
fatalError("close() has not been implemented")
}
}
Loading

0 comments on commit 071f2cf

Please sign in to comment.