├── .buildkite
└── pipeline.yml
├── .github
└── workflows
│ └── swift.yml
├── .gitignore
├── .justfile
├── .swift-version
├── .swiftformat
├── .swiftlint.yml
├── .swiftpm
├── configuration
│ └── Package.resolved
└── xcode
│ ├── package.xcworkspace
│ └── contents.xcworkspacedata
│ └── xcshareddata
│ └── xcschemes
│ ├── Everything-Package.xcscheme
│ ├── Everything.xcscheme
│ └── EverythingHelpers.xcscheme
├── .vscode
└── settings.json
├── LICENSE.md
├── Package.resolved
├── Package.swift
├── README.md
├── Sources
├── Everything
│ ├── Algorithms
│ │ ├── AStarSearch.swift
│ │ ├── BloomFilter.swift
│ │ ├── CRC16.swift
│ │ ├── Comparison.swift
│ │ ├── DamerauLevenshtein.swift
│ │ ├── ExponentialMovingAverageIrregular.swift
│ │ ├── Heap.swift
│ │ ├── OrderedSet.swift
│ │ ├── PriorityQueue.swift
│ │ ├── Search.swift
│ │ └── Visitor.swift
│ ├── AppKit
│ │ └── AppKit+Extensions.swift
│ ├── CSV
│ │ ├── CSVDecoder.swift
│ │ └── CSVFormatter.swift
│ ├── Coding
│ │ ├── AnyDecodable.swift
│ │ ├── BinaryEncoding.swift
│ │ ├── FormEncoder.swift
│ │ └── Streams.swift
│ ├── Color
│ │ ├── CGColor+More.swift
│ │ ├── ColorConvertible.swift
│ │ ├── ColorParser.swift
│ │ └── SystemColorPalette.swift
│ ├── Combine
│ │ ├── Combine.swift
│ │ ├── ConcreteSubscription.swift
│ │ ├── DisplayLinkPublisher.swift
│ │ └── FSEventPublisher.swift
│ ├── Concurrency
│ │ ├── Atomic.swift
│ │ ├── Concurrency.swift
│ │ └── Threading.swift
│ ├── CoreLocation
│ │ ├── CoreLocation+Extensions.swift
│ │ └── CoreLocation+Extensions2.swift
│ ├── DataFormatting
│ │ └── Converters.swift
│ ├── DataStructures
│ │ └── IdentifiableSet.swift
│ ├── FileSystem
│ │ ├── FSPath+Extensions.swift
│ │ ├── FSPath.swift
│ │ ├── FileBookmarks.swift
│ │ └── FileSystem.swift
│ ├── FormatStyle.swift
│ ├── Foundation
│ │ ├── AnyCodingKey.swift
│ │ ├── BlockValueTransformer.swift
│ │ ├── Casts.swift
│ │ ├── CharacterSet+Extensions.swift
│ │ ├── Collections+Extensions.swift
│ │ ├── Date+Extensions.swift
│ │ ├── Errors.swift
│ │ ├── FileManager+xattr.swift
│ │ ├── Foundation+Misc.swift
│ │ ├── NSXML+Extensions.swift
│ │ ├── NumberFormatter+Extensions.swift
│ │ ├── Optional+Extensions.swift
│ │ ├── Padding.swift
│ │ ├── Process+Extensions.swift
│ │ ├── Scanner+Extensions.swift
│ │ ├── Shlex.swift
│ │ ├── String+Escaping.swift
│ │ ├── String+Extensions.swift
│ │ ├── URL+Extensions.swift
│ │ ├── UnsafeBufferPointer+Extensions.swift
│ │ └── printColumnar.swift
│ ├── Functional
│ │ └── Functional.swift
│ ├── HID
│ │ └── VirtualKeyCode.swift
│ ├── Math
│ │ ├── Clamp.swift
│ │ ├── Fuzzy.swift
│ │ ├── Lerp.swift
│ │ ├── Math.swift
│ │ └── signExtend.swift
│ ├── Memory
│ │ ├── Align.swift
│ │ ├── BitRange.swift
│ │ ├── BitSet.swift
│ │ ├── Bits.swift
│ │ ├── Endianness.swift
│ │ └── Memory.swift
│ ├── Misc
│ │ ├── Benchmark.swift
│ │ ├── BinaryCoding.swift
│ │ ├── Box.swift
│ │ ├── Cache.swift
│ │ ├── CompositeHash.swift
│ │ ├── CustomTupleConvertable.swift
│ │ ├── Errno.swift
│ │ ├── Hashing.swift
│ │ ├── Identified.swift
│ │ ├── Logging.swift
│ │ ├── LolUID.swift
│ │ ├── MachTime.swift
│ │ ├── Misc.swift
│ │ ├── Named.swift
│ │ ├── OutputStream.swift
│ │ ├── Random.swift
│ │ ├── Tagged+Radians.swift
│ │ ├── Tagged.swift
│ │ ├── Timestamp.swift
│ │ ├── TrivialID.swift
│ │ └── Version.swift
│ ├── Parsing
│ │ ├── CollectionScanner.swift
│ │ └── YACharacterSet.swift
│ ├── PropertyWrappers
│ │ └── PropertyWrappers.swift
│ ├── RadixedIntegerFormatStyle.swift
│ ├── Scratch
│ │ └── Scratch.swift
│ └── SwiftUI
│ │ ├── Binding+Extensions.swift
│ │ ├── Button+Extensions.swift
│ │ ├── Image+Extensions.swift
│ │ ├── InigoColorPalette.swift
│ │ ├── Styles.swift
│ │ ├── Styles.swift.gyb
│ │ ├── SwiftUI+Extensions.swift
│ │ └── ViewAdapter.swift
└── EverythingUnsafeConformances
│ └── EverythingUnsafeConformances.swift
├── TestPlans
└── Everything.xctestplan
├── Tests
├── EverythingTests
│ ├── BitRange_Tests.swift
│ ├── BitsTests.swift
│ ├── CSVTests.swift
│ ├── CollectionScannerTests.swift
│ ├── CombineTests.swift
│ ├── ComparisonTests.swift
│ ├── HeapTests.swift
│ ├── IdentifiableSetTests.swift
│ ├── ParsingTests
│ │ └── CharacterSetTests.swift
│ ├── PathTests.swift
│ ├── ProcessTest.swift
│ ├── RandomTests.swift
│ ├── SIMDTests.swift
│ ├── TaggedTests.swift
│ ├── Utilities.swift
│ ├── VersionTests.swift
│ └── XCTestManifests.swift
└── SwiftParsingTests
│ ├── CharacterSetTests.swift
│ ├── JSONPathParsingTests.swift
│ ├── ParserTests.swift
│ ├── ScannerTests.swift
│ ├── SwiftParsingTests.swift
│ ├── SwiftTransformParsingTests.swift
│ ├── XCTestManifests.swift
│ └── sample.json
└── Utilities
└── gyb.py
/.buildkite/pipeline.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - commands:
3 | - "swift build"
4 | - commands:
5 | - "swift test"
6 | - commands:
7 | - "xcodebuild -scheme 'Everything' -allowProvisioningUpdates -destination 'generic/platform=macOS'"
8 | - commands:
9 | - "xcodebuild -scheme 'Everything' -allowProvisioningUpdates -destination 'generic/platform=iOS'"
10 | - commands:
11 | - "swiftlint lint --quiet"
12 |
--------------------------------------------------------------------------------
/.github/workflows/swift.yml:
--------------------------------------------------------------------------------
1 | # This workflow will build a Swift project
2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-swift
3 |
4 | name: Swift
5 |
6 | on:
7 | push:
8 | pull_request:
9 |
10 | jobs:
11 | build:
12 | runs-on: macos-15
13 | steps:
14 | - uses: maxim-lobanov/setup-xcode@v1
15 | with:
16 | xcode-version: 16
17 | - uses: actions/checkout@v3
18 | - name: Build
19 | run: swift build -v
20 | - name: Run tests
21 | run: swift test -v
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by https://www.toptal.com/developers/gitignore/api/swift
2 | # Edit at https://www.toptal.com/developers/gitignore?templates=swift
3 |
4 | ### Swift ###
5 | # Xcode
6 | #
7 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
8 |
9 | ## User settings
10 | xcuserdata/
11 |
12 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
13 | *.xcscmblueprint
14 | *.xccheckout
15 |
16 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
17 | build/
18 | DerivedData/
19 | *.moved-aside
20 | *.pbxuser
21 | !default.pbxuser
22 | *.mode1v3
23 | !default.mode1v3
24 | *.mode2v3
25 | !default.mode2v3
26 | *.perspectivev3
27 | !default.perspectivev3
28 |
29 | ## Obj-C/Swift specific
30 | *.hmap
31 |
32 | ## App packaging
33 | *.ipa
34 | *.dSYM.zip
35 | *.dSYM
36 |
37 | ## Playgrounds
38 | timeline.xctimeline
39 | playground.xcworkspace
40 |
41 | # Swift Package Manager
42 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
43 | # Packages/
44 | # Package.pins
45 | # Package.resolved
46 | # *.xcodeproj
47 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
48 | # hence it is not needed unless you have added a package configuration file to your project
49 | # .swiftpm
50 |
51 | .build/
52 |
53 | # CocoaPods
54 | # We recommend against adding the Pods directory to your .gitignore. However
55 | # you should judge for yourself, the pros and cons are mentioned at:
56 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
57 | # Pods/
58 | # Add this line if you want to avoid checking in source code from the Xcode workspace
59 | # *.xcworkspace
60 |
61 | # Carthage
62 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
63 | # Carthage/Checkouts
64 |
65 | Carthage/Build/
66 |
67 | # Accio dependency management
68 | Dependencies/
69 | .accio/
70 |
71 | # fastlane
72 | # It is recommended to not store the screenshots in the git repo.
73 | # Instead, use fastlane to re-generate the screenshots whenever they are needed.
74 | # For more information about the recommended setup visit:
75 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
76 |
77 | fastlane/report.xml
78 | fastlane/Preview.html
79 | fastlane/screenshots/**/*.png
80 | fastlane/test_output
81 |
82 | # Code Injection
83 | # After new code Injection tools there's a generated folder /iOSInjectionProject
84 | # https://github.com/johnno1962/injectionforxcode
85 |
86 | iOSInjectionProject/
87 |
88 | # End of https://www.toptal.com/developers/gitignore/api/swift
89 |
--------------------------------------------------------------------------------
/.justfile:
--------------------------------------------------------------------------------
1 | set shell := ["/opt/homebrew/bin/fish", "-c"]
2 | sources := "Sources/Everything"
3 | templates := `find "Sources/Everything" -name "*.gyb"`
4 |
5 | default:
6 | @just --list
7 |
8 | generate:
9 | for template in (find {{sources}} -name "*.gyb"); \
10 | python3 Utilities/gyb.py "$template" > (path change-extension "" "$template"); \
11 | end
12 |
--------------------------------------------------------------------------------
/.swift-version:
--------------------------------------------------------------------------------
1 | 5.7
2 |
--------------------------------------------------------------------------------
/.swiftformat:
--------------------------------------------------------------------------------
1 | --disable andOperator
2 | --disable emptyBraces
3 | --disable fileHeader
4 | --disable redundantParens
5 | --disable trailingClosures
6 | --enable isEmpty
7 |
8 | --elseposition next-line
9 | --ifdef indent
10 | --patternlet inline
11 | --stripunusedargs closure-only
12 | --closingparen balanced
13 | --wraparguments preserve
14 | --wrapcollections before-first
15 |
--------------------------------------------------------------------------------
/.swiftpm/configuration/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "originHash" : "388e1203aa7d5ef762341756acc598f0e386ebb81c5400e025daa7ee152f117d",
3 | "pins" : [
4 | {
5 | "identity" : "swift-algorithms",
6 | "kind" : "remoteSourceControl",
7 | "location" : "https://github.com/apple/swift-algorithms",
8 | "state" : {
9 | "revision" : "f6919dfc309e7f1b56224378b11e28bab5bccc42",
10 | "version" : "1.2.0"
11 | }
12 | },
13 | {
14 | "identity" : "swift-numerics",
15 | "kind" : "remoteSourceControl",
16 | "location" : "https://github.com/apple/swift-numerics.git",
17 | "state" : {
18 | "revision" : "0a5bc04095a675662cf24757cc0640aa2204253b",
19 | "version" : "1.0.2"
20 | }
21 | }
22 | ],
23 | "version" : 3
24 | }
25 |
--------------------------------------------------------------------------------
/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.swiftpm/xcode/xcshareddata/xcschemes/Everything-Package.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
43 |
49 |
50 |
51 |
57 |
63 |
64 |
65 |
66 |
67 |
72 |
73 |
76 |
77 |
78 |
79 |
81 |
87 |
88 |
89 |
90 |
91 |
101 |
102 |
108 |
109 |
115 |
116 |
117 |
118 |
120 |
121 |
124 |
125 |
126 |
--------------------------------------------------------------------------------
/.swiftpm/xcode/xcshareddata/xcschemes/Everything.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
34 |
35 |
36 |
37 |
39 |
45 |
46 |
47 |
48 |
49 |
59 |
60 |
66 |
67 |
73 |
74 |
75 |
76 |
78 |
79 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/.swiftpm/xcode/xcshareddata/xcschemes/EverythingHelpers.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
42 |
43 |
49 |
50 |
56 |
57 |
58 |
59 |
61 |
62 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "cSpell.words": [
3 | "CCITT",
4 | "Damerau",
5 | "postorder",
6 | "preorder",
7 | "redblobgames"
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2022, Jonathan Wight
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | 1. Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | 3. Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "pins" : [
3 | {
4 | "identity" : "swift-algorithms",
5 | "kind" : "remoteSourceControl",
6 | "location" : "https://github.com/apple/swift-algorithms",
7 | "state" : {
8 | "revision" : "bcd4f369ac962bc3e5244c9df778739f8f5bdbf1",
9 | "version" : "1.1.0"
10 | }
11 | },
12 | {
13 | "identity" : "swift-numerics",
14 | "kind" : "remoteSourceControl",
15 | "location" : "https://github.com/apple/swift-numerics",
16 | "state" : {
17 | "revision" : "0a5bc04095a675662cf24757cc0640aa2204253b",
18 | "version" : "1.0.2"
19 | }
20 | }
21 | ],
22 | "version" : 2
23 | }
24 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version: 6.0
2 |
3 | import PackageDescription
4 |
5 | let package = Package(
6 | name: "Everything",
7 | platforms: [
8 | .iOS(.v17),
9 | .macOS(.v14),
10 | .macCatalyst(.v17),
11 | .tvOS(.v17),
12 | .visionOS(.v1),
13 | ],
14 | products: [
15 | .library(name: "Everything", targets: ["Everything"]),
16 | .library(name: "EverythingUnsafeConformances", targets: ["EverythingUnsafeConformances"]),
17 | ],
18 | dependencies: [
19 | .package(url: "https://github.com/apple/swift-algorithms", from: "1.1.0"),
20 | ],
21 | targets: [
22 | .target(
23 | name: "Everything",
24 | dependencies: [
25 | .product(name: "Algorithms", package: "swift-algorithms"),
26 |
27 | ]
28 | ),
29 | .target(name: "EverythingUnsafeConformances"),
30 | .testTarget(name: "EverythingTests", dependencies: ["Everything"]),
31 | ],
32 | swiftLanguageModes: [.v6]
33 | )
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Everything
2 |
3 | Literally everything
4 |
5 | This repository and Swift Package is ~~where my Swift source code goes to die~~ a collection of various small functions and types that don't really merit the overhead of me creating and maintaining their own repository.
6 |
7 | You probably should not link to this Swift Package directly as I make no guarantees about backwards compatibility. Instead I suggest you copy and paste the code from this repository into yours if you find any part of it useful.
8 |
--------------------------------------------------------------------------------
/Sources/Everything/Algorithms/AStarSearch.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | // swiftlint:disable:next static_operator
4 | private func < (lhs: T?, rhs: T?) -> Bool {
5 | switch (lhs, rhs) {
6 | case (let l?, let r?):
7 | return l < r
8 |
9 | case (nil, _?):
10 | return true
11 |
12 | default:
13 | return false
14 | }
15 | }
16 |
17 | public struct AStarSearch {
18 | public typealias Cost = Int
19 |
20 | public var neighbors: ((Location) -> [Location])!
21 | public var cost: ((Location, Location) -> Cost)!
22 | public var heuristic: ((Location, Location) -> Cost)!
23 |
24 | public init() {}
25 |
26 | // swiftlint:disable identifier_name
27 | public func search(_ start: Location, goal: Location) -> [Location] {
28 | var frontier = PriorityQueue()
29 | frontier.put(start, priority: 0)
30 |
31 | var came_from: [Location: Location] = [:]
32 | var cost_so_far: [Location: Cost] = [:]
33 |
34 | came_from[start] = start
35 | cost_so_far[start] = 0
36 |
37 | while !frontier.isEmpty {
38 | let current = frontier.get()!
39 |
40 | if current == goal {
41 | break
42 | }
43 |
44 | for next in neighbors(current) {
45 | let new_cost = cost_so_far[current]! + cost(current, next)
46 | if cost_so_far[next] == nil || new_cost < cost_so_far[next] {
47 | cost_so_far[next] = new_cost
48 | let priority = new_cost * heuristic(goal, next)
49 | frontier.put(next, priority: priority)
50 | came_from[next] = current
51 | }
52 | }
53 | }
54 |
55 | if came_from[goal] == nil {
56 | return []
57 | }
58 |
59 | var path: [Location] = []
60 | var current = goal
61 | while current != start {
62 | if let from = came_from[current] {
63 | path.append(from)
64 | current = from
65 | }
66 | }
67 | return Array(path.reversed())
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Sources/Everything/Algorithms/BloomFilter.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | struct BloomFilter {
4 | let count: Int
5 | var storage: [UInt8]
6 | // swiftlint:disable:next opening_brace
7 | var hashFunctions: [(Element) -> Int] = [{ $0.hashValue }]
8 |
9 | init(count: Int) {
10 | self.count = count
11 | storage = [UInt8](repeating: 0, count: count / 8)
12 | }
13 |
14 | func contains(_ member: Element) -> Bool {
15 | for hashFunction in hashFunctions {
16 | let (index, shift) = indexShift(member, hashFunction: hashFunction)
17 | if (storage[index] & 1 << shift) == 0 {
18 | return false
19 | }
20 | }
21 | return true
22 | }
23 |
24 | mutating func insert(_ member: Element) {
25 | for hashFunction in hashFunctions {
26 | let (index, shift) = indexShift(member, hashFunction: hashFunction)
27 | storage[index] |= 1 << shift
28 | }
29 | }
30 |
31 | internal func indexShift(_ member: Element, hashFunction: (Element) -> Int) -> (Int, UInt8) {
32 | let hash = Int(bitPattern: UInt(bitPattern: hashFunction(member)) % UInt(count))
33 | let index = hash % storage.count
34 | let shift = UInt8(hash / storage.count)
35 | return (index, shift)
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Sources/Everything/Algorithms/CRC16.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | // CRC-16-CCITT X.25
4 |
5 | // TODO: Use DataProtocol
6 |
7 | public struct CRC16 {
8 | public typealias CRCType = UInt16
9 | public internal(set) var crc: CRCType!
10 |
11 | public init() {}
12 |
13 | public static func accumulate(_ buffer: UnsafeBufferPointer, crc: CRCType = 0xFFFF) -> CRCType {
14 | var accum = crc
15 | for b in buffer {
16 | var tmp = CRCType(b) ^ (accum & 0xFF)
17 | tmp = (tmp ^ (tmp << 4)) & 0xFF
18 | accum = (accum >> 8) ^ (tmp << 8) ^ (tmp << 3) ^ (tmp >> 4)
19 | }
20 | return accum
21 | }
22 |
23 | public mutating func accumulate(_ buffer: UnsafeBufferPointer) {
24 | if crc == nil {
25 | crc = 0xFFFF
26 | }
27 | crc = Self.accumulate(buffer, crc: crc)
28 | }
29 | }
30 |
31 | public extension CRC16 {
32 | mutating func accumulate(_ bytes: [UInt8]) {
33 | bytes.withUnsafeBufferPointer { (body: UnsafeBufferPointer) in
34 | accumulate(body)
35 | }
36 | }
37 |
38 | mutating func accumulate(_ string: String) {
39 | string.withCString { (ptr: UnsafePointer) in
40 | let count = Int(strlen(ptr))
41 | ptr.withMemoryRebound(to: UInt8.self, capacity: count) { ptr in
42 | let buffer = UnsafeBufferPointer(start: ptr, count: count)
43 | accumulate(buffer)
44 | }
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Sources/Everything/Algorithms/Comparison.swift:
--------------------------------------------------------------------------------
1 | public enum Comparison {
2 | case lesser
3 | case equal
4 | case greater
5 | }
6 |
7 | public func compare(_ lhs: T, _ rhs: T) -> Comparison {
8 | if lhs == rhs {
9 | return .equal
10 | }
11 | if lhs < rhs {
12 | return .lesser
13 | }
14 | return .greater
15 | }
16 |
17 | public extension Comparison {
18 | static func comparisonSummary(_ comparisons: [Comparison]) -> Comparison {
19 | for comparison in comparisons {
20 | switch comparison {
21 | case .lesser:
22 | return .lesser
23 |
24 | case .greater:
25 | return .lesser
26 |
27 | case .equal:
28 | continue
29 | }
30 | }
31 | return .equal
32 | }
33 |
34 | init(sequence1 _: Sequence1, _: some Sequence) where Sequence1.Iterator.Element: Comparable {
35 | self = .equal
36 | }
37 | }
38 |
39 | /**
40 | Return the elements of the 2-tuple as an ordered 2-tuple
41 |
42 | - example
43 | let (a,b) = ordered(("B", "A"))
44 | */
45 | public func ordered(_ tuple: (T, T)) -> (T, T) {
46 | let (lhs, rhs) = tuple
47 | if lhs <= rhs {
48 | return (lhs, rhs)
49 | }
50 | return (rhs, lhs)
51 | }
52 |
--------------------------------------------------------------------------------
/Sources/Everything/Algorithms/DamerauLevenshtein.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | public protocol StringDifferenceAlgorithm {
4 | static func distance(_ a: String, _ b: String) -> Int
5 | }
6 |
7 | public enum DamerauLevenshteinAlgorithm: StringDifferenceAlgorithm {
8 | public static func distance(_ a: String, _ b: String) -> Int {
9 | distance(Array(a), Array(b))
10 | }
11 |
12 | public static func distance(_ a: [Character], _ b: [Character]) -> Int {
13 | func len(_ x: [Character]) -> Int {
14 | x.count
15 | }
16 | if min(a.count, b.count) == 0 {
17 | return max(a.count, b.count)
18 | }
19 | let indicator = a[wrapping: -1] == b[wrapping: -1] ? 0 : 1
20 | let new_a = Array(a.dropLast())
21 | let new_b = Array(b.dropLast())
22 | let another_a = Array(a.dropLast(2))
23 | let another_b = Array(b.dropLast(2))
24 | if len(a) > 1, len(b) > 1, a[wrapping: -1] == b[wrapping: -2], a[wrapping: -2] == b[wrapping: -1] {
25 | return min(distance(a, new_b) + 1, distance(new_a, b) + 1, distance(new_a, new_b) + indicator, distance(another_a, another_b) + 1)
26 | }
27 | return min(distance(new_a, b) + 1, distance(a, new_b) + 1, distance(new_a, new_b) + indicator)
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Sources/Everything/Algorithms/ExponentialMovingAverageIrregular.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | // TODO: This could just be a function that returns a closure.
4 | // https://oroboro.com/irregular-ema/
5 | public struct ExponentialMovingAverageIrregular: Sendable {
6 | private typealias Sample = (time: Double, value: Double)
7 |
8 | public private(set) var exponentialMovingAverage: Double = 0
9 | private let alpha: Double
10 | private var lastSample: Sample?
11 |
12 | public init(alpha: Double = 0.2) {
13 | self.alpha = alpha
14 | }
15 |
16 | @discardableResult
17 | public mutating func update(time: Double, value: Double) -> Double {
18 | let newMovingAverage: Double
19 | if let lastSample {
20 | let deltaTime = time - lastSample.time
21 | let a = deltaTime / alpha
22 | let u = exp(a * -1)
23 | let v = (1 - u) / a
24 | newMovingAverage = (u * exponentialMovingAverage) + ((v - u) * lastSample.value) + ((1 - v) * value)
25 | } else {
26 | newMovingAverage = value
27 | }
28 | lastSample = (time: time, value: value)
29 | exponentialMovingAverage = newMovingAverage
30 | return exponentialMovingAverage
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Sources/Everything/Algorithms/Heap.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | // https://en.wikipedia.org/wiki/Binary_heap
4 | public struct BinaryHeap {
5 | public typealias Comparator = (Element, Element) -> Bool
6 | public let comparator: Comparator
7 |
8 | public typealias Storage = [Element]
9 | public var array: Storage = []
10 |
11 | public init(comparator: @escaping Comparator) {
12 | self.comparator = comparator
13 | }
14 |
15 | public init(values: [Element], comparator: @escaping Comparator) {
16 | array = values
17 | self.comparator = comparator
18 | build(&array)
19 | }
20 |
21 | public var count: Int {
22 | array.count
23 | }
24 |
25 | public mutating func push(_ element: Element) {
26 | assert(valid(array))
27 | var index = array.count
28 | array.append(element)
29 | while let parentIndex = parentIndexOfElementAtIndex(index) {
30 | if comparator(array[index], array[parentIndex]) {
31 | array.swapAt(index, parentIndex)
32 | index = parentIndex
33 | } else {
34 | break
35 | }
36 | }
37 | assert(valid(array))
38 | }
39 |
40 | public mutating func pop() -> Element? {
41 | assert(valid(array))
42 | guard let root = array.first else {
43 | return nil
44 | }
45 | array[0] = array.last!
46 | array.removeLast()
47 | heapify(0)
48 | assert(valid(array))
49 | return root
50 | }
51 |
52 | public var isEmpty: Bool {
53 | array.isEmpty
54 | }
55 | }
56 |
57 | private extension BinaryHeap {
58 | func parentIndexOfElementAtIndex(_ index: Int) -> Int? {
59 | index < array.count ? (index - 1) / 2 : nil
60 | }
61 |
62 | func childIndicesOfElementAtIndex(_ index: Int) -> (Int?, Int?) {
63 | let lhsIndex = 2 * index + 1
64 | let rhsIndex = 2 * index + 2
65 | return (lhsIndex < array.count ? lhsIndex : nil, rhsIndex < array.count ? rhsIndex : nil)
66 | }
67 |
68 | mutating func heapify(_ index: Int) {
69 | heapify(&array, index)
70 | }
71 |
72 | func heapify(_ elements: inout [Element], _ index: Int) {
73 | let left = 2 * index + 1
74 | let right = 2 * index + 2
75 | var largest = index
76 | if left < elements.count, comparator(elements[left], elements[largest]) {
77 | largest = left
78 | }
79 | if right < elements.count, comparator(elements[right], elements[largest]) {
80 | largest = right
81 | }
82 | if largest != index {
83 | elements.swapAt(index, largest)
84 | heapify(&elements, largest)
85 | }
86 | }
87 |
88 | // TODO: Not working yet.
89 | func build(_ elements: inout [Element]) {
90 | assertionFailure()
91 |
92 | for i in stride(from: elements.count - 1, through: 0, by: -1) {
93 | heapify(&elements, i)
94 | }
95 | }
96 |
97 | func valid(_ elements: [Element], index: Int = 0) -> Bool {
98 | guard !elements.isEmpty else {
99 | return true
100 | }
101 | let (lhs, rhs) = childIndicesOfElementAtIndex(index)
102 | if let lhs {
103 | if comparator(elements[lhs], elements[index]) {
104 | return false
105 | }
106 | if !valid(elements, index: lhs) {
107 | return false
108 | }
109 | }
110 | if let rhs {
111 | if comparator(elements[rhs], elements[index]) {
112 | return false
113 | }
114 | if !valid(elements, index: rhs) {
115 | return false
116 | }
117 | }
118 | return true
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/Sources/Everything/Algorithms/OrderedSet.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | public struct OrderedSet where Element: Hashable {
4 | internal var set: Set
5 | internal var array: [Element]
6 |
7 | public init() {
8 | set = []
9 | array = []
10 | }
11 | }
12 |
13 | extension OrderedSet: Sequence {
14 | public struct Iterator: IteratorProtocol {
15 | internal var base: Array.Iterator
16 | public mutating func next() -> Element? {
17 | base.next()
18 | }
19 | }
20 |
21 | public func makeIterator() -> Iterator {
22 | Iterator(base: array.makeIterator())
23 | }
24 | }
25 |
26 | extension OrderedSet: Collection {
27 | public struct Index: Comparable {
28 | internal let base: Array.Index
29 |
30 | public static func < (lhs: OrderedSet.Index, rhs: OrderedSet.Index) -> Bool {
31 | lhs.base < rhs.base
32 | }
33 | }
34 |
35 | public var startIndex: Index {
36 | Index(base: array.startIndex)
37 | }
38 |
39 | public var endIndex: Index {
40 | Index(base: array.endIndex)
41 | }
42 |
43 | public subscript(position: Index) -> Element {
44 | array[position.base]
45 | }
46 |
47 | public func index(after i: Index) -> Index {
48 | Index(base: array.index(after: i.base))
49 | }
50 |
51 | public var isEmpty: Bool {
52 | array.isEmpty
53 | }
54 |
55 | public var count: Int {
56 | array.count
57 | }
58 | }
59 |
60 | // extension OrderedSet: RandomAccessCollection {
61 | //
62 | // }
63 |
64 | extension OrderedSet: SetAlgebra {
65 | public __consuming func union(_ other: __owned OrderedSet) -> OrderedSet {
66 | unimplemented()
67 | }
68 |
69 | public __consuming func intersection(_ other: OrderedSet) -> OrderedSet {
70 | unimplemented()
71 | }
72 |
73 | public __consuming func symmetricDifference(_ other: __owned OrderedSet) -> OrderedSet {
74 | unimplemented()
75 | }
76 |
77 | public mutating func insert(_ newMember: __owned Element) -> (inserted: Bool, memberAfterInsert: Element) {
78 | let result = set.insert(newMember)
79 | if result.inserted {
80 | array.append(newMember)
81 | }
82 | return result
83 | }
84 |
85 | public mutating func remove(_ member: Element) -> Element? {
86 | if let result = set.remove(member) {
87 | array.removeAll { $0 == result }
88 | return result
89 | }
90 | return nil
91 | }
92 |
93 | public mutating func update(with newMember: __owned Element) -> Element? {
94 | unimplemented()
95 | // if let result = set.update(with: newMember) {
96 | // unimplemented()
97 | // }
98 | // else {
99 | // return nil
100 | // }
101 | }
102 |
103 | public mutating func formUnion(_ other: __owned OrderedSet) {
104 | unimplemented()
105 | }
106 |
107 | public mutating func formIntersection(_ other: OrderedSet) {
108 | unimplemented()
109 | }
110 |
111 | public mutating func formSymmetricDifference(_ other: __owned OrderedSet) {
112 | unimplemented()
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/Sources/Everything/Algorithms/PriorityQueue.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | public struct PriorityQueue {
4 | public var binaryHeap: BinaryHeap<(Element, Priority)>
5 |
6 | public init() {
7 | binaryHeap = BinaryHeap<(Element, Priority)> {
8 | $0.1 < $1.1
9 | }
10 | }
11 |
12 | public var count: Int {
13 | binaryHeap.count
14 | }
15 |
16 | public var isEmpty: Bool {
17 | binaryHeap.isEmpty
18 | }
19 |
20 | public mutating func get() -> Element? {
21 | guard let (element, _) = binaryHeap.pop() else {
22 | return nil
23 | }
24 | return element
25 | }
26 |
27 | public mutating func put(_ element: Element, priority: Priority) {
28 | binaryHeap.push((element, priority))
29 | }
30 | }
31 |
32 | extension PriorityQueue: Sequence {
33 | public typealias Iterator = PriorityQueueGenerator
34 | public func makeIterator() -> Iterator {
35 | Iterator(queue: self)
36 | }
37 | }
38 |
39 | public struct PriorityQueueGenerator: IteratorProtocol {
40 | public typealias Element = Value
41 | internal var queue: PriorityQueue
42 | public init(queue: PriorityQueue) {
43 | self.queue = queue
44 | }
45 |
46 | public mutating func next() -> Element? {
47 | queue.get()
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Sources/Everything/Algorithms/Search.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | // http: //www.redblobgames.com/pathfinding/a-star/introduction.html
4 | // http: //www.redblobgames.com/pathfinding/a-star/implementation.html#sec-1-3
5 |
6 | public func breadth_first_search(_ start: Location, goal: Location, neighbors: (Location) -> [Location]) -> [Location] {
7 | var frontier = [Location]()
8 | frontier.put(start)
9 | // var came_from: [Location: Location!] = [start: nil]
10 | var came_from: [Location: Location] = [:]
11 |
12 | while frontier.isEmpty == false {
13 | let current = frontier.get()!
14 | if current == goal {
15 | break
16 | }
17 | for next in neighbors(current) where came_from[next] == nil {
18 | frontier.put(next)
19 | came_from[next] = current
20 | }
21 | }
22 |
23 | if came_from[goal] == nil {
24 | return []
25 | }
26 |
27 | var path: [Location] = []
28 | var current = goal
29 | while current != start {
30 | if let from = came_from[current] {
31 | path.append(from)
32 | current = from
33 | }
34 | }
35 | return Array(path.reversed())
36 | }
37 |
38 | // MARK: -
39 |
40 | private extension Array {
41 | mutating func put(_ newElement: Element) {
42 | append(newElement)
43 | }
44 |
45 | // Complexity O(count)
46 | mutating func get() -> Element? {
47 | guard let element = first else {
48 | return nil
49 | }
50 | remove(at: 0)
51 | return element
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Sources/Everything/Algorithms/Visitor.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | public struct Visitor: Sequence where Children: Sequence, Children.Element == Node {
4 | public enum Order {
5 | case preorder // (self, children)
6 | case postorder // (children, self)
7 | }
8 |
9 | let _makeIterator: () -> AnyIterator
10 |
11 | public init(root: Node, children: KeyPath, order: Order = .preorder) {
12 | switch order {
13 | case .preorder:
14 | _makeIterator = {
15 | var stack: [Node] = []
16 | var current: Node? = root
17 | return AnyIterator {
18 | guard !stack.isEmpty || current != nil else {
19 | return nil
20 | }
21 | let result = current
22 | // TODO: .reversed() is inefficient
23 | stack.append(contentsOf: current![keyPath: children].reversed())
24 | current = stack.popLast()
25 | return result
26 | }
27 | }
28 |
29 | case .postorder:
30 | // TODO: BROKEN - returns in reverse order
31 | _makeIterator = {
32 | var out: [Node] = []
33 | var s: [Node] = [root]
34 | return AnyIterator {
35 | if !out.isEmpty {
36 | return out.popLast()
37 | }
38 | if !s.isEmpty {
39 | let current = s.popLast()
40 | out.append(current!)
41 | s.append(contentsOf: current![keyPath: children])
42 | return out.popLast()
43 | }
44 | return nil
45 | }
46 | }
47 | }
48 | }
49 |
50 | public func makeIterator() -> AnyIterator {
51 | _makeIterator()
52 | }
53 | }
54 |
55 | private extension Array {
56 | mutating func popFirst() -> Element? {
57 | defer {
58 | self = Array(self.dropFirst())
59 | }
60 | return first
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/Sources/Everything/AppKit/AppKit+Extensions.swift:
--------------------------------------------------------------------------------
1 | #if os(macOS)
2 | import AppKit
3 | import Foundation
4 |
5 | public extension NSStoryboard {
6 | convenience init(name: String) {
7 | self.init(name: name, bundle: nil)
8 | }
9 | }
10 | #endif // os(macOS)
11 |
--------------------------------------------------------------------------------
/Sources/Everything/CSV/CSVDecoder.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | struct CSVDecoder {
4 | }
5 |
6 | public struct CSVReader {
7 | let data: Data
8 | public enum LineEnding {
9 | case CR
10 | case LF
11 | case CRLF
12 | }
13 |
14 | let lineEndings: LineEnding
15 |
16 | public init(data: Data, lineEndings: LineEnding = .CRLF) {
17 | self.data = data
18 | self.lineEndings = lineEndings
19 | }
20 |
21 | public init(url: URL, lineEndings: LineEnding = .CRLF) throws {
22 | let data = try Data(contentsOf: url, options: .mappedIfSafe)
23 | self = Self(data: data, lineEndings: lineEndings)
24 | // TODO: Dont ignore BOM on other encodings
25 | }
26 |
27 | public func makeIterator() -> AnyIterator<[String]> {
28 | let lineEndings: [UInt8]
29 | switch self.lineEndings {
30 | case .LF:
31 | lineEndings = [0x0A]
32 |
33 | case .CR:
34 | lineEndings = [0x0D]
35 |
36 | case .CRLF:
37 | lineEndings = [0x0D, 0x0A]
38 | }
39 |
40 | var fileScanner = CollectionScanner(elements: data)
41 |
42 | // MS Excel inserts a BOM even for UTF-8 files.
43 | _ = fileScanner.scan(value: [0xEF, 0xBB, 0xBF])
44 |
45 | let lineIterator = fileScanner.iterator(forComponentsSeparatedBy: lineEndings)
46 | return AnyIterator<[String]> {
47 | guard let line = lineIterator.next() else {
48 | return nil
49 | }
50 | let lineString = String(decoding: line, as: UTF8.self)
51 | var lineScanner = CollectionScanner(elements: lineString)
52 | // TODO: Handle quotes and escapes and all that jazz. UNIT TESTS
53 | return lineScanner.scanCSVFields()
54 | }
55 | }
56 | }
57 |
58 | public struct CSVDictReader {
59 | let reader: CSVReader
60 |
61 | public init(data: Data, lineEndings: CSVReader.LineEnding = .CRLF) {
62 | reader = CSVReader(data: data, lineEndings: lineEndings)
63 | }
64 |
65 | public init(url: URL, lineEndings: CSVReader.LineEnding = .CRLF) throws {
66 | reader = try CSVReader(url: url, lineEndings: lineEndings)
67 | }
68 |
69 | public func makeIterator() -> AnyIterator<[String: String]> {
70 | let recordIterator = reader.makeIterator()
71 | guard let keys = recordIterator.next() else {
72 | return NilIterator().eraseToAnyIterator()
73 | }
74 | return AnyIterator {
75 | guard let values = recordIterator.next() else {
76 | return nil
77 | }
78 | return Dictionary(uniqueKeysWithValues: zip(keys, values))
79 | }
80 | }
81 | }
82 |
83 | public struct SharedKeys {
84 | let keys: [Key]
85 | }
86 |
87 | public struct SharedKeysDictionary {
88 | let keys: SharedKeys
89 | let values: [Value]
90 | }
91 |
92 | public extension CollectionScanner {
93 | mutating func scanCSVFields() -> [String] where C == String {
94 | var fields: [String] = []
95 | while !atEnd {
96 | assertChange(value: current) {
97 | if scan(value: "\"") {
98 | var field = ""
99 | while !atEnd {
100 | if let chunk = scanUpTo(value: "\"").map(String.init) {
101 | field.append(chunk)
102 | }
103 | _ = scan(value: "\"")
104 | if peek() == "\"" {
105 | _ = scan(value: "\"")
106 | field.append("\"")
107 | } else {
108 | fields.append(field)
109 | break
110 | }
111 | }
112 | } else if let field = scanUpTo(value: ",").map(String.init) {
113 | fields.append(field)
114 | }
115 | if scan(value: ",") {
116 | if atEnd {
117 | fields.append("")
118 | }
119 | }
120 | }
121 | }
122 | return fields
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/Sources/Everything/CSV/CSVFormatter.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | public struct CSVFormatter {
4 | public struct Options {
5 | public var quote: String = "\""
6 | public var delimiter: String = ","
7 | public var recordDelimiter: String = "\n"
8 |
9 | public enum QuoteLevel {
10 | case none
11 | case all
12 | case minimal
13 | case nonnumeric
14 | }
15 |
16 | public var quoteLevel: QuoteLevel = .minimal
17 | public var doubleQuote = true
18 | public var escape: String?
19 | public var skipInitialSpace = false
20 |
21 | public init() {
22 | }
23 | }
24 |
25 | public var options = Options()
26 |
27 | public init(options: Options = Options()) {
28 | self.options = options
29 | }
30 |
31 | public func formatField(_ field: String) -> String {
32 | let specials = options.quote + options.delimiter + options.recordDelimiter
33 | var field = field
34 | let quote: Bool
35 | switch options.quoteLevel {
36 | case .none:
37 | quote = false
38 |
39 | case .all, .nonnumeric:
40 | quote = true
41 |
42 | case .minimal:
43 | quote = field.contains {
44 | specials.contains($0)
45 | }
46 | }
47 |
48 | if quote && options.doubleQuote {
49 | field = field.replacingOccurrences(of: options.quote, with: options.quote + options.quote)
50 | } else if let escape = options.escape, options.quoteLevel == .none {
51 | field = field.replacingOccurrences(of: escape, with: escape + escape)
52 | field = field.replacingOccurrences(of: options.quote, with: escape + options.quote)
53 | field = field.replacingOccurrences(of: options.delimiter, with: escape + options.delimiter)
54 | field = field.replacingOccurrences(of: options.recordDelimiter, with: escape + options.recordDelimiter)
55 | }
56 | return quote ? options.quote + field + options.quote : field
57 | }
58 |
59 | public func formatFields(_ fields: [String]) -> String {
60 | fields.map {
61 | formatField($0)
62 | }
63 | .joined(separator: options.delimiter)
64 | + options.recordDelimiter
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/Sources/Everything/Coding/AnyDecodable.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | public struct AnyDecodable: Decodable {
4 | public var value: Any
5 |
6 | private struct CodingKeys: CodingKey {
7 | var stringValue: String
8 | var intValue: Int?
9 | init?(intValue: Int) {
10 | stringValue = "\(intValue)"
11 | self.intValue = intValue
12 | }
13 |
14 | init?(stringValue: String) { self.stringValue = stringValue }
15 | }
16 |
17 | public init(from decoder: Decoder) throws {
18 | if let container = try? decoder.container(keyedBy: CodingKeys.self) {
19 | var result = [String: Any]()
20 | try container.allKeys.forEach { key throws in
21 | result[key.stringValue] = try container.decode(Self.self, forKey: key).value
22 | }
23 | value = result
24 | } else if var container = try? decoder.unkeyedContainer() {
25 | var result = [Any]()
26 | while !container.isAtEnd {
27 | result.append(try container.decode(Self.self).value)
28 | }
29 | value = result
30 | } else if let container = try? decoder.singleValueContainer() {
31 | if let intVal = try? container.decode(Int.self) {
32 | value = intVal
33 | } else if let doubleVal = try? container.decode(Double.self) {
34 | value = doubleVal
35 | } else if let boolVal = try? container.decode(Bool.self) {
36 | value = boolVal
37 | } else if let stringVal = try? container.decode(String.self) {
38 | value = stringVal
39 | } else {
40 | throw DecodingError.dataCorruptedError(in: container, debugDescription: "the container contains nothing serialisable")
41 | }
42 | } else {
43 | throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Could not serialise"))
44 | }
45 | }
46 | }
47 |
48 | //let json = """
49 | //{
50 | //"id": 12345,
51 | //"name": "Giuseppe",
52 | //"last_name": "Lanza",
53 | //"age": 31,
54 | //"happy": true,
55 | //"rate": 1.5,
56 | //"classes": ["maths", "phisics"],
57 | //"dogs": [
58 | //{
59 | //"name": "Gala",
60 | //"age": 1
61 | //}, {
62 | //"name": "Aria",
63 | //"age": 3
64 | //}
65 | //]
66 | //}
67 | //"""
68 |
69 | // func test() {
70 | // let jsonData = json.data(using: .utf8)!
71 | // let stud = try! JSONDecoder().decode(AnyDecodable.self, from: jsonData).value as! [String: Any]
72 | // print(stud)
73 | // }
74 |
--------------------------------------------------------------------------------
/Sources/Everything/Coding/BinaryEncoding.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | public func encode(_ N: UInt64) -> [UInt8] {
4 | var result: [UInt8] = []
5 | var N = N
6 | repeat {
7 | let byte = UInt8(N & 0b0111_1111)
8 | N = N >> 7
9 | print(N)
10 | result.insert(byte | (N != 0 ? 128 : 0), at: 0)
11 | }
12 | while N > 0
13 | return result
14 | }
15 |
--------------------------------------------------------------------------------
/Sources/Everything/Coding/FormEncoder.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import SwiftUI
3 |
4 | public struct FormEncoder: Encoder {
5 | public var codingPath: [CodingKey] = []
6 |
7 | public var userInfo: [CodingUserInfoKey: Any] = [:]
8 |
9 | public init() {
10 | }
11 |
12 | public func container(keyedBy type: Key.Type) -> KeyedEncodingContainer where Key: CodingKey {
13 | KeyedEncodingContainer(MyKeyedEncodingContainer())
14 | }
15 |
16 | public func unkeyedContainer() -> UnkeyedEncodingContainer {
17 | unimplemented()
18 | }
19 |
20 | public func singleValueContainer() -> SingleValueEncodingContainer {
21 | unimplemented()
22 | }
23 |
24 | // MARK: -
25 |
26 | struct MyKeyedEncodingContainer: KeyedEncodingContainerProtocol where Key: CodingKey {
27 | var codingPath: [CodingKey] = []
28 |
29 | var views: [AnyView] = []
30 |
31 | mutating func encodeNil(forKey key: Key) throws {
32 | unimplemented()
33 | }
34 |
35 | mutating func encode(_ value: Bool, forKey key: Key) throws {
36 | unimplemented()
37 | }
38 |
39 | mutating func encode(_ value: String, forKey key: Key) throws {
40 | unimplemented()
41 | }
42 |
43 | mutating func encode(_ value: Double, forKey key: Key) throws {
44 | let view = HStack {
45 | Text(key.stringValue)
46 | Text(String(describing: value))
47 | }
48 | views.append(AnyView(view))
49 | }
50 |
51 | mutating func encode(_ value: Float, forKey key: Key) throws {
52 | unimplemented()
53 | }
54 |
55 | mutating func encode(_ value: Int, forKey key: Key) throws {
56 | unimplemented()
57 | }
58 |
59 | mutating func encode(_ value: Int8, forKey key: Key) throws {
60 | unimplemented()
61 | }
62 |
63 | mutating func encode(_ value: Int16, forKey key: Key) throws {
64 | unimplemented()
65 | }
66 |
67 | mutating func encode(_ value: Int32, forKey key: Key) throws {
68 | unimplemented()
69 | }
70 |
71 | mutating func encode(_ value: Int64, forKey key: Key) throws {
72 | unimplemented()
73 | }
74 |
75 | mutating func encode(_ value: UInt, forKey key: Key) throws {
76 | unimplemented()
77 | }
78 |
79 | mutating func encode(_ value: UInt8, forKey key: Key) throws {
80 | unimplemented()
81 | }
82 |
83 | mutating func encode(_ value: UInt16, forKey key: Key) throws {
84 | unimplemented()
85 | }
86 |
87 | mutating func encode(_ value: UInt32, forKey key: Key) throws {
88 | unimplemented()
89 | }
90 |
91 | mutating func encode(_ value: UInt64, forKey key: Key) throws {
92 | unimplemented()
93 | }
94 |
95 | mutating func encode(_ value: some Encodable, forKey key: Key) throws {
96 | unimplemented()
97 | }
98 |
99 | mutating func nestedContainer(keyedBy keyType: NestedKey.Type, forKey key: Key) -> KeyedEncodingContainer where NestedKey: CodingKey {
100 | unimplemented()
101 | }
102 |
103 | mutating func nestedUnkeyedContainer(forKey key: Key) -> UnkeyedEncodingContainer {
104 | unimplemented()
105 | }
106 |
107 | mutating func superEncoder() -> Encoder {
108 | unimplemented()
109 | }
110 |
111 | mutating func superEncoder(forKey key: Key) -> Encoder {
112 | unimplemented()
113 | }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/Sources/Everything/Coding/Streams.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | // public protocol BinaryOutputStream {
4 | // mutating func append(_ value: UInt8)
5 | // mutating func append(_ value: UnsafeBufferPointer)
6 | // mutating func append(_ value: UnsafeRawBufferPointer)
7 | // }
8 | //
9 | //// TODO: We can just make Data/Array conform to this
10 | // public class Output: BinaryOutputStream {
11 | // public var bytes: [UInt8] = []
12 | //
13 | // public func append(_ value: UInt8) {
14 | // bytes.append(value)
15 | // }
16 | //
17 | // public func append(_ value: UnsafeBufferPointer) {
18 | // bytes += value
19 | // }
20 | //
21 | // public func append(_ value: UnsafeRawBufferPointer) {
22 | // append(value.bindMemory(to: UInt8.self))
23 | // }
24 | // }
25 |
26 | // extension Output: CustomStringConvertible {
27 | // public var description: String {
28 | // return String(describing: bytes)
29 | // }
30 | // }
31 |
32 | public protocol OutputStream {
33 | mutating func write(bytes: T) throws where T: Collection, T.Element == UInt8
34 | mutating func write(_ value: String) throws
35 | mutating func write(_ value: T) throws
36 | }
37 |
38 | public class BinaryOutputStream: OutputStream where Buffer: RangeReplaceableCollection, Buffer.Element == UInt8 {
39 | public private(set) var buffer: Buffer
40 |
41 | public enum StringEncodingStrategy {
42 | case undecorated
43 | case nilTerminated
44 | case lengthPrefixed
45 | case custom((BinaryOutputStream, String) throws -> Void)
46 | }
47 |
48 | public var stringEncodingStrategy: StringEncodingStrategy = .undecorated
49 | public var stringEncoding: String.Encoding = .utf8
50 | public var allowLossyStringConversion = false
51 |
52 | var current: Buffer.Index
53 |
54 | public init(buffer: Buffer) {
55 | self.buffer = buffer
56 | current = buffer.startIndex
57 | }
58 |
59 | public func write(bytes: some Collection) throws {
60 | let end = buffer.index(current, offsetBy: bytes.count)
61 | buffer.replaceSubrange(current ..< end, with: bytes)
62 | current = end
63 | }
64 |
65 | public func write(_ value: String) throws {
66 | switch stringEncodingStrategy {
67 | case .undecorated:
68 | guard let data = value.data(using: stringEncoding, allowLossyConversion: allowLossyStringConversion) else {
69 | throw GeneralError.valueConversionFailure
70 | }
71 | try write(bytes: data)
72 |
73 | case .nilTerminated:
74 | guard let data = value.data(using: stringEncoding, allowLossyConversion: allowLossyStringConversion) else {
75 | throw GeneralError.valueConversionFailure
76 | }
77 | try write(bytes: data)
78 | try write(bytes: [UInt8(0)])
79 |
80 | case .lengthPrefixed:
81 | guard let data = value.data(using: stringEncoding, allowLossyConversion: allowLossyStringConversion) else {
82 | throw GeneralError.valueConversionFailure
83 | }
84 | guard data.count <= 255 else {
85 | throw GeneralError.valueConversionFailure
86 | }
87 | try write(bytes: [UInt8(data.count)])
88 | try write(bytes: data)
89 |
90 | case .custom(let custom):
91 | try custom(self, value)
92 | }
93 | }
94 |
95 | public func write(_ value: some Any) throws {
96 | try withUnsafeBytes(of: value) { bytes in
97 | try write(bytes: bytes)
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/Sources/Everything/Color/CGColor+More.swift:
--------------------------------------------------------------------------------
1 | import CoreGraphics
2 |
3 | #if os(macOS)
4 | import AppKit
5 | #elseif os(iOS) || os(tvOS)
6 | import UIKit
7 | #endif
8 |
9 | public extension CGColor {
10 | #if os(macOS)
11 | static func HSV(hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat = 1.0) -> CGColor {
12 | NSColor(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha).cgColor
13 | }
14 |
15 | #elseif os(iOS) || os(tvOS)
16 | static func HSV(hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat = 1.0) -> CGColor {
17 | UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha).cgColor
18 | }
19 | #endif
20 |
21 | func withAlphaComponent(_ alpha: CGFloat) -> CGColor {
22 | copy(alpha: alpha)!
23 | }
24 |
25 | func blended(withFraction fraction: CGFloat, of other: CGColor) -> CGColor {
26 | unimplemented()
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Sources/Everything/Color/ColorConvertible.swift:
--------------------------------------------------------------------------------
1 | import CoreGraphics
2 |
3 | // TODO: Move
4 | public protocol ColorConvertible {
5 | var color: CGColor { get }
6 | }
7 |
8 | extension Double: ColorConvertible {
9 | public var color: CGColor {
10 | let gray = CGFloat(self)
11 | return CGColor(red: gray, green: gray, blue: gray, alpha: 1.0)
12 | }
13 | }
14 |
15 | extension Bool: ColorConvertible {
16 | public var color: CGColor {
17 | let gray: CGFloat = self ? 1.0 : 0.0
18 | return CGColor(red: gray, green: gray, blue: gray, alpha: 1.0)
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Sources/Everything/Color/SystemColorPalette.swift:
--------------------------------------------------------------------------------
1 | import CoreGraphics
2 |
3 | #if os(macOS)
4 | import AppKit
5 | #elseif os(iOS) || os(tvOS)
6 | import UIKit
7 | #endif
8 |
9 | public protocol SystemColorPalette {
10 | associatedtype SystemColor
11 |
12 | static var clear: SystemColor { get }
13 | static var white: SystemColor { get }
14 | static var black: SystemColor { get }
15 | static var red: SystemColor { get }
16 | static var green: SystemColor { get }
17 | static var blue: SystemColor { get }
18 | static var magenta: SystemColor { get }
19 | static var yellow: SystemColor { get }
20 | static var cyan: SystemColor { get }
21 | static var orange: SystemColor { get }
22 | static var purple: SystemColor { get }
23 |
24 | static var darkGray: SystemColor { get }
25 | static var lightGray: SystemColor { get }
26 | static var gray: SystemColor { get }
27 | static var brown: SystemColor { get }
28 | }
29 |
30 | #if os(macOS)
31 | extension NSColor: SystemColorPalette {
32 | public typealias SystemColor = NSColor
33 | }
34 |
35 | extension CGColor: SystemColorPalette {
36 | public typealias SystemColor = CGColor
37 |
38 | public static var red: SystemColor { NSColor.red.cgColor }
39 | public static var green: SystemColor { NSColor.green.cgColor }
40 | public static var blue: SystemColor { NSColor.blue.cgColor }
41 | public static var magenta: SystemColor { NSColor.magenta.cgColor }
42 | public static var yellow: SystemColor { NSColor.yellow.cgColor }
43 | public static var cyan: SystemColor { NSColor.cyan.cgColor }
44 | public static var orange: SystemColor { NSColor.orange.cgColor }
45 | public static var purple: SystemColor { NSColor.purple.cgColor }
46 |
47 | public static var darkGray: SystemColor { NSColor.darkGray.cgColor }
48 | public static var lightGray: SystemColor { NSColor.lightGray.cgColor }
49 | public static var gray: SystemColor { NSColor.gray.cgColor }
50 | public static var brown: SystemColor { NSColor.brown.cgColor }
51 | }
52 |
53 | #elseif os(iOS) || os(tvOS)
54 | extension UIColor: SystemColorPalette {
55 | public typealias SystemColor = UIColor
56 | }
57 |
58 | extension CGColor: SystemColorPalette {
59 | public typealias SystemColor = CGColor
60 |
61 | public static var clear: SystemColor { UIColor.clear.cgColor }
62 | public static var white: SystemColor { UIColor.white.cgColor }
63 | public static var black: SystemColor { UIColor.black.cgColor }
64 | public static var red: SystemColor { UIColor.red.cgColor }
65 | public static var green: SystemColor { UIColor.green.cgColor }
66 | public static var blue: SystemColor { UIColor.blue.cgColor }
67 | public static var magenta: SystemColor { UIColor.magenta.cgColor }
68 | public static var yellow: SystemColor { UIColor.yellow.cgColor }
69 | public static var cyan: SystemColor { UIColor.cyan.cgColor }
70 | public static var orange: SystemColor { UIColor.orange.cgColor }
71 | public static var purple: SystemColor { UIColor.purple.cgColor }
72 |
73 | public static var darkGray: SystemColor { UIColor.darkGray.cgColor }
74 | public static var lightGray: SystemColor { UIColor.lightGray.cgColor }
75 | public static var gray: SystemColor { UIColor.gray.cgColor }
76 | public static var brown: SystemColor { UIColor.brown.cgColor }
77 | }
78 | #endif
79 |
--------------------------------------------------------------------------------
/Sources/Everything/Combine/Combine.swift:
--------------------------------------------------------------------------------
1 | import Combine
2 | import Foundation
3 |
4 | public extension Publisher where Failure == Never {
5 | // Block only gets the first output from
6 | func block() -> Output {
7 | let done = DispatchSemaphore(value: 0)
8 | var result: Output!
9 | let s = sink { output in
10 | result = output
11 | done.signal()
12 | }
13 | done.wait()
14 | s.cancel()
15 | return result
16 | }
17 | }
18 |
19 | public extension Publisher {
20 | func block() throws -> Output {
21 | let done = DispatchSemaphore(value: 0)
22 | var result: Result