Swift Workshop Booking Project
Combine checked state changes and explicit refused requests in a small value model.
How it works
A booking counter has one valid capacity and a current booked count. A request succeeds only if it is positive and fits; a failure must preserve the earlier state. This model is intentionally in-memory and single-threaded. The Actor lesson owns the separate concurrent variant.
Run this Swift example
Install the toolchain for your platform from Swift.org, then check swift --version. The reviewed portable baseline is Swift 6.4.2 in Swift 6 mode on Ubuntu 26.04 x86_64 through the PC’s existing WSL installation. These are real Linux executions, not claims of Windows-native or Apple-platform test results. Windows Swift has separate C++/SDK prerequisites in its official setup guide.
Save the complete source as booking-project.swift in a new learning folder. On Linux/macOS compile with swiftc -swift-version 6 -parse-as-library booking-project.swift -o lesson, then run ./lesson. On a configured Windows toolchain use an output such as lesson.exe and run .\lesson.exe. The parse-as-library option supports the explicit @main entry point used by these sources. Compile each ordinary lesson separately.
Bhylu has no Swift browser runner. The JavaScript/Python editors do not run these sources; Apache, PHP and MySQL are not required. Downloads are source text, never executable teaching endpoints.
Download the complete booking-project.swift · Download all source files with hash checks
For the optional collection, save download-examples.mjs in a new folder and run node download-examples.mjs. A local preview uses node download-examples.mjs http://127.0.0.1:8000/examples/swift/. It refuses an existing bhylu-swift-examples folder and installs or executes no Swift automatically. Apple-only files remain separate Xcode learning examples, not a portable Swift package target.
Example
struct BookingCounter {
let capacity: Int
private(set) var booked = 0
var free: Int { capacity - booked }
init?(capacity: Int) { guard capacity >= 0 else { return nil }; self.capacity = capacity }
mutating func book(_ amount: Int) -> Bool {
guard amount > 0, amount <= free else { return false }
booked += amount
return true
}
}
@main
struct Lesson {
static func main() {
var counter = BookingCounter(capacity: 5)!
for amount in [2, 0, 4, 3] { print(counter.book(amount), counter.booked) }
print("free", counter.free)
}
}
Expected result
true 2 false 2 false 2 true 5 free 0
The known fixed capacity is force-unwrapped only after using a literal fixture whose validity is visible; ordinary external input should use optional binding. The sequence includes two refused requests between successes. The package tests additional ranges and maximum-Int boundaries.
A real Swift package
The source collection includes Package.swift, a WorkshopCore library, a WorkshopCLI executable and actual XCTest files. Inside bhylu-swift-examples run node setup-lab.mjs. It checks source hashes before creating a new pottery-lab folder and refuses existing output. Change to pottery-lab and run swift test, then swift run WorkshopCLI. No third-party package dependency is needed. A properly installed platform toolchain supplies its own runtime/SDK; the private review setup is not shipped to readers.
Package.swift
// swift-tools-version: 6.0
import PackageDescription
let package = Package(
name: "PotteryLab",
products: [
.library(name: "WorkshopCore", targets: ["WorkshopCore"]),
.executable(name: "WorkshopCLI", targets: ["WorkshopCLI"])
],
targets: [
.target(name: "WorkshopCore"),
.executableTarget(name: "WorkshopCLI", dependencies: ["WorkshopCore"]),
.testTarget(name: "WorkshopCoreTests", dependencies: ["WorkshopCore"])
]
)
WorkshopCore.swift
import Foundation
public struct BookingCounter: Sendable {
public let capacity: Int
public private(set) var booked = 0
public var free: Int { capacity - booked }
public init?(capacity: Int) {
guard capacity >= 0 else { return nil }
self.capacity = capacity
}
public mutating func book(_ amount: Int) -> Bool {
guard amount > 0, amount <= free else { return false }
booked += amount
return true
}
}
public struct Booking: Sendable {
public let id: String
public let room: String
public let minutes: Int
public init(id: String, room: String, minutes: Int) {
self.id = id; self.room = room; self.minutes = minutes
}
}
public enum ReportError: Error { case invalid }
public func roomTotals(_ rows: [Booking]) throws -> [String: Int] {
guard rows.count <= 1000 else { throw ReportError.invalid }
var seen: Set<String> = []
var totals: [String: Int] = [:]
for row in rows {
guard !row.id.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty,
!row.room.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty,
(1...240).contains(row.minutes), seen.insert(row.id).inserted else { throw ReportError.invalid }
totals[row.room, default: 0] += row.minutes
}
return totals
}
WorkshopCLI.swift
import WorkshopCore
@main struct WorkshopCLI {
static func main() throws {
guard var desk = BookingCounter(capacity: 5) else { fatalError("Invalid fixture") }
for amount in [2, 0, 4, 3] { print(desk.book(amount), desk.booked) }
print("free", desk.free)
let totals = try roomTotals([
Booking(id: "W-21", room: "Cedar", minutes: 20),
Booking(id: "W-22", room: "Ash", minutes: 35),
Booking(id: "W-23", room: "Cedar", minutes: 25)
])
for key in totals.keys.sorted() { print(key, totals[key] ?? 0) }
}
}
WorkshopCoreTests.swift
Download WorkshopCoreTests.swift
import XCTest
@testable import WorkshopCore
final class WorkshopCoreTests: XCTestCase {
func testCapacityRefusalsAndIndependentSequence() {
XCTAssertNil(BookingCounter(capacity: -1))
for capacity in 0...20 {
guard var desk = BookingCounter(capacity: capacity) else { return XCTFail("Valid capacity refused") }
var expected = 0
for amount in [1, 2, 0, -1, 4, 1, 19, 1] {
let accepted = amount > 0 && Int64(expected) + Int64(amount) <= Int64(capacity)
if accepted { expected += amount }
XCTAssertEqual(desk.book(amount), accepted)
XCTAssertEqual(desk.booked, expected)
XCTAssertEqual(desk.free, capacity - expected)
}
}
}
func testMaximumIntDoesNotOverflowOnRefusal() {
guard var desk = BookingCounter(capacity: Int.max) else { return XCTFail("Maximum capacity refused") }
XCTAssertTrue(desk.book(Int.max - 1))
XCTAssertFalse(desk.book(2))
XCTAssertEqual(desk.booked, Int.max - 1)
XCTAssertTrue(desk.book(1))
XCTAssertEqual(desk.free, 0)
XCTAssertFalse(desk.book(1))
}
func testReportIndependentTotalsAndEmptyInput() throws {
for size in 0...30 {
let rows = (0..<size).map { Booking(id: String($0), room: $0 % 3 == 0 ? "Cedar" : "Ash", minutes: $0 + 1) }
let actual = try roomTotals(rows)
let cedar = (0..<size).filter { $0 % 3 == 0 }.reduce(0) { $0 + $1 + 1 }
let ash = (0..<size).filter { $0 % 3 != 0 }.reduce(0) { $0 + $1 + 1 }
XCTAssertEqual(actual["Cedar", default: 0], cedar)
XCTAssertEqual(actual["Ash", default: 0], ash)
}
}
func testReportRejectsInvalidWholeInput() {
let cases: [[Booking]] = [
[Booking(id: "", room: "Cedar", minutes: 1)],
[Booking(id: "x", room: " ", minutes: 1)],
[Booking(id: "x", room: "Cedar", minutes: 0)],
[Booking(id: "x", room: "Cedar", minutes: 241)],
[Booking(id: "x", room: "Cedar", minutes: 1), Booking(id: "x", room: "Ash", minutes: 2)],
(0..<1001).map { Booking(id: String($0), room: "Cedar", minutes: 1) }
]
for rows in cases { XCTAssertThrowsError(try roomTotals(rows)) }
}
}
Primary references: The Swift Programming Language and Apple framework documentation. Use the selected platform’s current requirements. Fictional workshop examples do not establish production safety or deployment approval.