├── docs
├── favicon.ico
├── developer-og.jpg
├── developer-og-twitter.jpg
├── img
│ ├── no-image@2x.df2a0a50.png
│ ├── deprecated-icon.015b4f17.svg
│ ├── added-icon.d6f7e47d.svg
│ └── modified-icon.f496e73d.svg
├── metadata.json
├── js
│ ├── highlight-js-shell.dd7f411f.js
│ ├── highlight-js-json.471128d2.js
│ ├── highlight-js-diff.62d66733.js
│ ├── highlight-js-http.163e45b6.js
│ └── highlight-js-xml.9c3688c7.js
├── favicon.svg
└── data
│ └── documentation
│ └── crush
│ ├── userinfokey.json
│ ├── entity
│ ├── init().json
│ ├── hashable-implementations.json
│ └── readaleobject-implementations.json
│ ├── entitymap
│ └── init().json
│ ├── relationship
│ └── relationshipprotocol-implementations.json
│ ├── migrationerror
│ ├── error-implementations.json
│ ├── notmigrated.json
│ ├── incompatible.json
│ └── equatable-implementations.json
│ ├── coredataerror
│ ├── customstringconvertible-implementations.json
│ └── error-implementations.json
│ ├── orderedset
│ ├── init().json
│ └── equatable-implementations.json
│ ├── objectdriver
│ ├── customdebugstringconvertible-implementations.json
│ ├── hashable-implementations.json
│ └── equatable-implementations.json
│ ├── datacontainererror
│ ├── error-implementations.json
│ └── equatable-implementations.json
│ ├── storage
│ └── equatable-implementations.json
│ ├── adhocmigrationerror
│ ├── error-implementations.json
│ └── equatable-implementations.json
│ ├── mutableset
│ ├── init().json
│ └── equatable-implementations.json
│ ├── entitytypedescriptor
│ └── init().json
│ ├── migrationmodelingerror
│ └── error-implementations.json
│ ├── configuration
│ └── init().json
│ ├── fetchsorteroption
│ ├── default.json
│ ├── localized.json
│ ├── equatable-implementations.json
│ ├── caseinsensitive.json
│ └── localizedstandard.json
│ ├── searchstring
│ └── equatable-implementations.json
│ ├── entityabstraction
│ ├── concrete.json
│ └── equatable-implementations.json
│ ├── storageoption
│ └── equatable-implementations.json
│ ├── adhocmigration
│ └── equatable-implementations.json
│ ├── requestexecutor
│ └── received.json
│ ├── entityinheritance
│ ├── multitable.json
│ ├── singletable.json
│ └── equatable-implementations.json
│ ├── propertytype
│ ├── managedvalue.json
│ ├── runtimevalue.json
│ └── predicatevalue.json
│ ├── updateattribute
│ ├── updatepropertymigration-implementations.json
│ └── propertymigration-implementations.json
│ ├── primarykey
│ └── equatable-implementations.json
│ ├── session
│ ├── undo().json
│ └── redo().json
│ ├── mutableorderedset
│ ├── init().json
│ └── equatable-implementations.json
│ ├── unsafesessionproperty
│ └── safe.json
│ ├── codableattributetype
│ └── hashable-implementations.json
│ ├── entitymigrationcallback.json
│ ├── updaterelationship
│ ├── updatepropertymigration-implementations.json
│ └── propertymigration-implementations.json
│ ├── manageddriver
│ └── customdebugstringconvertible-implementations.json
│ ├── migrator.json
│ ├── enumerableattributetype
│ └── hashable-implementations.json
│ ├── modelmigration
│ └── equatable-implementations.json
│ ├── lazyfetchresultcollection.json
│ ├── updatefetchedproperty
│ └── updatepropertymigration-implementations.json
│ └── selectpath
│ └── path.json
├── .swiftpm
└── xcode
│ └── package.xcworkspace
│ └── contents.xcworkspacedata
├── Sources
├── Utils
│ ├── FileManager+helper.swift
│ ├── NSEntityDescription+helper.swift
│ ├── DispatchQueue+helper.swift
│ ├── UserInfoKey.swift
│ ├── Lock.swift
│ ├── CollectionBuilder.swift
│ ├── NSManagedObject+fetchSource.swift
│ ├── Expressible.swift
│ ├── Optional.swift
│ ├── PersistentHash.swift
│ ├── KeyPath+helper.swift
│ ├── SelectPath.swift
│ └── Caches.swift
├── Versioning
│ ├── MigrationModelingError.swift
│ ├── Migration
│ │ └── AdHocMigration.swift
│ ├── Migrator
│ │ └── AdHocMigrator.swift
│ └── MigrationChainIterator.swift
├── DataStructure
│ ├── FastEnumerationIterator.swift
│ ├── MapEnumerationIterator.swift
│ ├── LazyMapSet.swift
│ ├── LazyMapOrderedSet.swift
│ └── LazyMapMutableSet.swift
├── DataModel
│ └── Entity
│ │ ├── Property
│ │ ├── Property.swift
│ │ ├── Property+Attribute.swift
│ │ ├── PrimitiveAttributeType+Transformable.swift
│ │ ├── CodableAttributeType.swift
│ │ └── EnumerableAttributeType.swift
│ │ └── PartialObject.swift
├── DataContainer
│ └── DataContainer+workingDirectory.swift
└── Crush.docc
│ ├── Crush.md
│ ├── UndoRedoInSession.md
│ ├── TypesOfSessions.md
│ ├── SigningSessionBlock.md
│ ├── CRUDOperations.md
│ ├── PropertyModifier.md
│ └── IntroducingSession.md
├── Package.resolved
├── .gitignore
├── Tests
├── DataStructureTests
│ ├── LazyMapMutableOrderedSetTests.swift
│ ├── LazyMapSetTests.swift
│ ├── LazyMapOrderedSetTests.swift
│ └── LazyMapMutableSetTests.swift
├── UtilsTests
│ ├── OptionalTests.swift
│ └── PersistentHashTests.swift
├── QueryBuilderTests
│ └── UpdateBuilderTests.swift
├── DataModelTests
│ └── PartialObjectTests.swift
├── VersioningTests
│ └── MigrationTests
│ │ └── FethcedPropertyMigrationTests.swift
├── Measurement.swift
└── Utils
│ └── Publishers+helper.swift
├── LICENSE
├── Package.swift
├── README.md
└── Assertions
└── Assertions.swift
/docs/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ezoushen/Crush/HEAD/docs/favicon.ico
--------------------------------------------------------------------------------
/docs/developer-og.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ezoushen/Crush/HEAD/docs/developer-og.jpg
--------------------------------------------------------------------------------
/docs/developer-og-twitter.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ezoushen/Crush/HEAD/docs/developer-og-twitter.jpg
--------------------------------------------------------------------------------
/docs/img/no-image@2x.df2a0a50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ezoushen/Crush/HEAD/docs/img/no-image@2x.df2a0a50.png
--------------------------------------------------------------------------------
/docs/metadata.json:
--------------------------------------------------------------------------------
1 | {"bundleDisplayName":"Crush","bundleIdentifier":"Crush","schemaVersion":{"major":0,"minor":1,"patch":0}}
--------------------------------------------------------------------------------
/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Sources/Utils/FileManager+helper.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FileManager+helper.swift
3 | //
4 | //
5 | // Created by ezou on 2021/10/24.
6 | //
7 |
8 | import Foundation
9 |
10 | extension FileManager {
11 | func removeItemIfExists(atPath path: String) throws {
12 | if fileExists(atPath: path) {
13 | try removeItem(atPath: path)
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Sources/Versioning/MigrationModelingError.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MigrationModelingError.swift
3 | //
4 | //
5 | // Created by ezou on 2021/10/15.
6 | //
7 |
8 | import Foundation
9 |
10 | public enum MigrationModelingError: Error {
11 | // If received this error, please file an issue
12 | case internalTypeMismatch
13 |
14 | case migrationTargetNotFound(_ message: String)
15 |
16 | case unknownMigrationType
17 |
18 | case unknownDescriptionType
19 | }
20 |
--------------------------------------------------------------------------------
/Sources/Utils/NSEntityDescription+helper.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NSEntityDescription+helper.swift
3 | //
4 | //
5 | // Created by ezou on 2021/10/24.
6 | //
7 |
8 | import CoreData
9 | import Foundation
10 |
11 | extension NSEntityDescription {
12 | var entityType: Entity.Type? {
13 | guard let entityClassName =
14 | userInfo?[UserInfoKey.entityClassName] as? String
15 | else { return nil }
16 | return NSClassFromString(entityClassName) as? Entity.Type
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Sources/Utils/DispatchQueue+helper.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DispatchQueue+helper.swift
3 | //
4 | //
5 | // Created by ezou on 2021/10/17.
6 | //
7 |
8 | import Foundation
9 |
10 | extension DispatchQueue {
11 | static func performMainThreadTask(_ block: @escaping () -> Void){
12 | if Thread.isMainThread {
13 | return block()
14 | }
15 | DispatchQueue.main.async {
16 | performMainThreadTask {
17 | block()
18 | }
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/docs/img/deprecated-icon.015b4f17.svg:
--------------------------------------------------------------------------------
1 |
10 |
11 |
--------------------------------------------------------------------------------
/Sources/DataStructure/FastEnumerationIterator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FastEnumerationIterator.swift
3 | //
4 | //
5 | // Created by ezou on 2022/2/10.
6 | //
7 |
8 | import Foundation
9 |
10 | public struct FastEnumerationIterator: IteratorProtocol {
11 | internal var iterator: NSFastEnumerationIterator
12 |
13 | internal init(_ iterator: NSFastEnumerationIterator) {
14 | self.iterator = iterator
15 | }
16 |
17 | public mutating func next() -> T? {
18 | guard let next = iterator.next() else { return nil }
19 | let result: T = next as! T
20 | return result
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Sources/DataStructure/MapEnumerationIterator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MapEnumerationIterator.swift
3 | //
4 | //
5 | // Created by EZOU on 2023/9/1.
6 | //
7 |
8 | import Foundation
9 |
10 | class MapEnumerationIterator: NSEnumerator {
11 | var iterator: NSFastEnumerationIterator
12 | let from: (T) -> U
13 |
14 | init(iterator: NSFastEnumerationIterator, from: @escaping (T) -> U) {
15 | self.iterator = iterator
16 | self.from = from
17 | }
18 |
19 | override func nextObject() -> Any? {
20 | guard let value = iterator.next() as? T else { return nil }
21 | return from(value)
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Sources/Utils/UserInfoKey.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UserInfoKey.swift
3 | //
4 | //
5 | // Created by ezou on 2021/10/24.
6 | //
7 |
8 | import Foundation
9 |
10 | public enum UserInfoKey {
11 | // NSManagedObjectModel
12 | static let indexes = "Index"
13 | static let uniquenessConstraintName = "UniquenessConstraintName"
14 |
15 | // NSMappingModel
16 | static let attributeMappingFunc = "AttributeMappingFunc"
17 | static let attributeMappingFromObjectFunc = "AttributeMappingFromObjectFunc"
18 | static let defaultValueFunc = "DefaultValueFunc"
19 |
20 | // NSEntityDescription
21 | static let entityClassName = "EntityClassName"
22 | }
23 |
--------------------------------------------------------------------------------
/Sources/Utils/Lock.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UnfairLock.swift
3 | //
4 | //
5 | // Created by EZOU on 2023/1/13.
6 | //
7 |
8 | import Foundation
9 |
10 | class UnfairLock {
11 | private var _lock = os_unfair_lock()
12 |
13 | func lock() {
14 | os_unfair_lock_lock(&_lock)
15 | }
16 |
17 | func unlock() {
18 | os_unfair_lock_unlock(&_lock)
19 | }
20 |
21 | func tryLock() -> Bool {
22 | os_unfair_lock_trylock(&_lock)
23 | }
24 |
25 | func assertOwner() {
26 | os_unfair_lock_assert_owner(&_lock)
27 | }
28 |
29 | func assertNotOwner() {
30 | os_unfair_lock_assert_not_owner(&_lock)
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/docs/img/added-icon.d6f7e47d.svg:
--------------------------------------------------------------------------------
1 |
10 |
11 |
--------------------------------------------------------------------------------
/docs/js/highlight-js-shell.dd7f411f.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * This source file is part of the Swift.org open source project
3 | *
4 | * Copyright (c) 2021 Apple Inc. and the Swift project authors
5 | * Licensed under Apache License v2.0 with Runtime Library Exception
6 | *
7 | * See https://swift.org/LICENSE.txt for license information
8 | * See https://swift.org/CONTRIBUTORS.txt for Swift project authors
9 | */
10 | (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["highlight-js-shell"],{b65b:function(s,n){function e(s){return{name:"Shell Session",aliases:["console","shellsession"],contains:[{className:"meta",begin:/^\s{0,3}[/~\w\d[\]()@-]*[>%$#][ ]?/,starts:{end:/[^\\](?=\s*$)/,subLanguage:"bash"}}]}}s.exports=e}}]);
--------------------------------------------------------------------------------
/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "object": {
3 | "pins": [
4 | {
5 | "package": "SwiftDocCPlugin",
6 | "repositoryURL": "https://github.com/apple/swift-docc-plugin",
7 | "state": {
8 | "branch": null,
9 | "revision": "9b1258905c21fc1b97bf03d1b4ca12c4ec4e5fda",
10 | "version": "1.2.0"
11 | }
12 | },
13 | {
14 | "package": "SymbolKit",
15 | "repositoryURL": "https://github.com/apple/swift-docc-symbolkit",
16 | "state": {
17 | "branch": null,
18 | "revision": "b45d1f2ed151d057b54504d653e0da5552844e34",
19 | "version": "1.0.0"
20 | }
21 | }
22 | ]
23 | },
24 | "version": 1
25 | }
26 |
--------------------------------------------------------------------------------
/Sources/Utils/CollectionBuilder.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CollectionBuilder.swift
3 | //
4 | //
5 | // Created by ezou on 2021/10/16.
6 | //
7 |
8 | import Foundation
9 |
10 | @resultBuilder
11 | public struct CollectionBuilder {
12 | public static func buildBlock(_ components: T...) -> [T] {
13 | return components
14 | }
15 | }
16 |
17 |
18 | @resultBuilder
19 | public struct SetBuilder {
20 | public static func buildBlock(_ components: T...) -> Set {
21 | return Set(components)
22 | }
23 | }
24 |
25 | @resultBuilder
26 | public struct OrderedSetBuilder {
27 | public static func buildBlock(_ components: T...) -> OrderedSet {
28 | return OrderedSet(components)
29 | }
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/Sources/Utils/NSManagedObject+fetchSource.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NSManagedObject+FetchSource.swift
3 | //
4 | //
5 | // Created by EZOU on 2023/4/28.
6 | //
7 |
8 | import CoreData
9 | import Foundation
10 |
11 | extension NSManagedObjectID {
12 | open override func value(forUndefinedKey key: String) -> Any? {
13 | guard let fetchSource = NSManagedObject.currentFetchSource else { return nil }
14 | let value = fetchSource.value(forKey: key)
15 | return value
16 | }
17 | }
18 |
19 | extension NSManagedObject {
20 | /// This is a thread local variable. It represents the current fetch source as
21 | /// the target of `$FETCH_SOURCE` in the fetch property of a fetched property.
22 | @ThreadLocal static var currentFetchSource: NSManagedObject? = nil
23 | }
24 |
--------------------------------------------------------------------------------
/Sources/DataModel/Entity/Property/Property.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Property.swift
3 | // Crush
4 | //
5 | // Created by EZOU on 2019/9/21.
6 | // Copyright © 2019 ezou. All rights reserved.
7 | //
8 |
9 | import CoreData
10 |
11 | // MARK: - Entity Property
12 |
13 | public protocol Property: AnyObject {
14 | typealias RuntimeValue = PropertyType.RuntimeValue
15 | typealias ManagedValue = PropertyType.ManagedValue
16 | typealias PredicateValue = PropertyType.PredicateValue
17 |
18 | associatedtype Description: NSPropertyDescription
19 | associatedtype PropertyType: Crush.PropertyType
20 |
21 | var name: String { get }
22 | var isAttribute: Bool { get }
23 |
24 | func createPropertyDescription() -> Description
25 | }
26 |
27 | public protocol WritableProperty: Property { }
28 |
--------------------------------------------------------------------------------
/Sources/Utils/Expressible.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Expressible.swift
3 | //
4 | //
5 | // Created by EZOU on 2022/6/12.
6 | //
7 |
8 | import Foundation
9 |
10 | public protocol Expressible {
11 | func asExpression() -> Any
12 | func getHashValue() -> Int
13 | }
14 |
15 | extension Expressible {
16 | func equal(to: Expressible) -> Bool {
17 | getHashValue() == to.getHashValue()
18 | }
19 | }
20 |
21 | public struct StringExpressible: Expressible, ExpressibleByStringLiteral {
22 | let path: String
23 |
24 | public init(stringLiteral value: StringLiteralType) {
25 | path = String(value)
26 | }
27 |
28 | public func getHashValue() -> Int {
29 | path.hashValue
30 | }
31 |
32 | public func asExpression() -> Any {
33 | path
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/docs/js/highlight-js-json.471128d2.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * This source file is part of the Swift.org open source project
3 | *
4 | * Copyright (c) 2021 Apple Inc. and the Swift project authors
5 | * Licensed under Apache License v2.0 with Runtime Library Exception
6 | *
7 | * See https://swift.org/LICENSE.txt for license information
8 | * See https://swift.org/CONTRIBUTORS.txt for Swift project authors
9 | */
10 | (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["highlight-js-json"],{"5ad2":function(n,e){function a(n){const e={className:"attr",begin:/"(\\.|[^\\"\r\n])*"(?=\s*:)/,relevance:1.01},a={match:/[{}[\],:]/,className:"punctuation",relevance:0},s={beginKeywords:["true","false","null"].join(" ")};return{name:"JSON",contains:[e,a,n.QUOTE_STRING_MODE,s,n.C_NUMBER_MODE,n.C_LINE_COMMENT_MODE,n.C_BLOCK_COMMENT_MODE],illegal:"\\S"}}n.exports=a}}]);
--------------------------------------------------------------------------------
/Sources/Utils/Optional.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Optional.swift
3 | // Crush
4 | //
5 | // Created by ezou on 2020/4/18.
6 | //
7 |
8 | import Foundation
9 |
10 | public protocol OptionalProtocol {
11 | var isNil: Bool { get }
12 | static var null: Self { get }
13 | }
14 |
15 | extension Swift.Optional: OptionalProtocol {
16 | @inlinable
17 | public var isNil: Bool {
18 | switch self {
19 | case .some(let value):
20 | return (value as? OptionalProtocol)?.isNil == true
21 | default: return true
22 | }
23 | }
24 |
25 | @inlinable
26 | public static var null: Self {
27 | return .none
28 | }
29 | }
30 |
31 | extension Swift.Optional {
32 | @inlinable var contentDescription: String {
33 | switch self {
34 | case .none: return "null"
35 | case .some(let value): return "\(value)"
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OS X
2 | .DS_Store
3 | /Example-Test*
4 | # Xcode
5 | build/
6 | *.pbxuser
7 | !default.pbxuser
8 | *.mode1v3
9 | !default.mode1v3
10 | *.mode2v3
11 | !default.mode2v3
12 | *.perspectivev3
13 | !default.perspectivev3
14 | xcuserdata/
15 | *.xccheckout
16 | profile
17 | *.moved-aside
18 | DerivedData
19 | *.hmap
20 | *.ipa
21 |
22 | # Bundler
23 | .bundle
24 |
25 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
26 | # Carthage/Checkouts
27 |
28 | Carthage/Build
29 |
30 | # We recommend against adding the Pods directory to your .gitignore. However
31 | # you should judge for yourself, the pros and cons are mentioned at:
32 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
33 | #
34 | # Note: if you ignore the Pods directory, make sure to uncomment
35 | # `pod install` in .travis.yml
36 | #
37 | Pods/
38 |
39 | # SPM
40 | .build/
41 |
--------------------------------------------------------------------------------
/Sources/Versioning/Migration/AdHocMigration.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AdHocMigration.swift
3 | //
4 | //
5 | // Created by ezou on 2021/10/16.
6 | //
7 |
8 | import CoreData
9 | import Foundation
10 |
11 | public enum AdHocMigrationError: Error {
12 | case sourceModelNotFound
13 | }
14 |
15 | public struct AdHocMigration: Hashable {
16 | public let sourceName: String
17 | public let migration: ModelMigration
18 |
19 | public init(_ name: String, migration: ModelMigration) {
20 | self.sourceName = name
21 | self.migration = migration
22 | }
23 |
24 | public func createMappingModel() throws -> NSMappingModel {
25 | guard let sourceModel = NSManagedObjectModel.load(name: sourceName)
26 | else { throw AdHocMigrationError.sourceModelNotFound }
27 | let destinationModel = try migration.migrateModel(sourceModel)
28 | return try migration.createMappingModel(
29 | from: sourceModel, to: destinationModel)
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Sources/Utils/PersistentHash.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Hash.swift
3 | //
4 | //
5 | // Created by ezou on 2021/10/24.
6 | //
7 |
8 | import Foundation
9 |
10 | enum PersistentHash {
11 | static func ordered(_ lhs: UInt64, _ rhs: UInt64) -> UInt64 {
12 | lhs ^ (rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2))
13 | }
14 |
15 | static func unordered(_ lhs: UInt64, _ rhs: UInt64) -> UInt64 {
16 | lhs ^ rhs
17 | }
18 |
19 | static func fromString(_ string: String) -> UInt64 {
20 | let charArray = string.utf8CString.dropLast()
21 | var hash: UInt64 = 0
22 | for i in stride(from: 0, to: charArray.count, by: 4) {
23 | var value: Int32 = 0
24 | for char in charArray[i...from(orderedSet) {
16 | "\($0)"
17 | } to: {
18 | Int($0)!
19 | }
20 | XCTAssertEqual(sut.object(at: 1) as! String, "2")
21 | }
22 |
23 | func test_isEqual_shouldCompareUnderlyingSet() {
24 | let orderedSet = NSOrderedSet(array: [1, 2, 3])
25 | let sut = LazyMapOrderedSet.from(orderedSet) {
26 | "\($0)"
27 | } to: {
28 | Int($0)!
29 | }
30 | XCTAssertTrue(sut.isEqual(NSOrderedSet(array: ["1", "2", "3"])))
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/docs/js/highlight-js-diff.62d66733.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * This source file is part of the Swift.org open source project
3 | *
4 | * Copyright (c) 2021 Apple Inc. and the Swift project authors
5 | * Licensed under Apache License v2.0 with Runtime Library Exception
6 | *
7 | * See https://swift.org/LICENSE.txt for license information
8 | * See https://swift.org/CONTRIBUTORS.txt for Swift project authors
9 | */
10 | (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["highlight-js-diff"],{"48b8":function(e,n){function a(e){const n=e.regex;return{name:"Diff",aliases:["patch"],contains:[{className:"meta",relevance:10,match:n.either(/^@@ +-\d+,\d+ +\+\d+,\d+ +@@/,/^\*\*\* +\d+,\d+ +\*\*\*\*$/,/^--- +\d+,\d+ +----$/)},{className:"comment",variants:[{begin:n.either(/Index: /,/^index/,/={3,}/,/^-{3}/,/^\*{3} /,/^\+{3}/,/^diff --git/),end:/$/},{match:/^\*{15}$/}]},{className:"addition",begin:/^\+/,end:/$/},{className:"deletion",begin:/^-/,end:/$/},{className:"addition",begin:/^!/,end:/$/}]}}e.exports=a}}]);
--------------------------------------------------------------------------------
/Tests/UtilsTests/OptionalTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // OptionalTests.swift
3 | //
4 | //
5 | // Created by ezou on 2022/2/5.
6 | //
7 |
8 | import XCTest
9 |
10 | @testable import Crush
11 |
12 | class OptionalTests: XCTestCase {
13 | func test_isNil_shouldBeTrue() {
14 | let sut = Swift.Optional.none
15 | XCTAssertTrue(sut.isNil)
16 | }
17 |
18 | func test_isNil_shouldBeFalse() {
19 | let sut = Swift.Optional.some(10)
20 | XCTAssertFalse(sut.isNil)
21 | }
22 |
23 | func test_null_shouldBeNil() {
24 | XCTAssertNil(Swift.Optional.null)
25 | }
26 |
27 | func test_contentDescription_shouldBeNull() {
28 | let sut = Swift.Optional.none
29 | XCTAssertEqual(sut.contentDescription, "null")
30 | }
31 |
32 | func test_contentDescription_shouldDescribeContent() {
33 | let sut = Swift.Optional.some(10)
34 | let result = sut.contentDescription
35 | XCTAssertEqual("\(10)", result)
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2020 ezoushen
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/docs/img/modified-icon.f496e73d.svg:
--------------------------------------------------------------------------------
1 |
10 |
11 |
--------------------------------------------------------------------------------
/Sources/DataContainer/DataContainer+workingDirectory.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DataContainer+workingDirectory.swift
3 | //
4 | //
5 | // Created by ezou on 2021/10/17.
6 | //
7 |
8 | import Foundation
9 |
10 | private var workingDirectoryLocked: Bool = false
11 | private var workingDirectory: URL = {
12 | workingDirectoryLocked = true
13 | #if os(macOS)
14 | return try! FileManager.default.url(
15 | for: .applicationSupportDirectory,
16 | in: .userDomainMask,
17 | appropriateFor: nil, create: true)
18 | #else
19 | return try! FileManager.default.url(
20 | for: .documentDirectory,
21 | in: .userDomainMask,
22 | appropriateFor: nil, create: true)
23 | #endif
24 | }()
25 |
26 | func CurrentWorkingDirectory() -> URL {
27 | workingDirectory
28 | }
29 |
30 | public enum DataContainerError: Error {
31 | case workingDirectoryInconsistency
32 | }
33 |
34 | extension DataContainer {
35 | public static func setWorkingDirectory(_ url: URL) throws {
36 | guard !workingDirectoryLocked else {
37 | throw DataContainerError.workingDirectoryInconsistency
38 | }
39 | workingDirectory = url
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Sources/Crush.docc/Crush.md:
--------------------------------------------------------------------------------
1 | # ``Crush``
2 |
3 | Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality
4 |
5 | ## Overview
6 |
7 | ### Installation
8 |
9 | Make sure you've declared `Crush` as your dependency before getting started
10 |
11 | ```swift
12 | let package = Package(
13 | dependencies: [
14 | .package(
15 | url: "https://github.com/ezoushen/Crush",
16 | from: "TARGET_VERSION"
17 | ),
18 | ],
19 | targets: [
20 | .target(
21 | name: "",
22 | dependencies: [
23 | "Crush"
24 | ]
25 | )
26 | ]
27 | )
28 | ```
29 |
30 | ## Topics
31 |
32 | ### Getting started
33 |
34 | -
35 | -
36 | -
37 |
38 | ### Managing data schema
39 |
40 | -
41 | -
42 | -
43 |
44 | ### Working with Session
45 |
46 | -
47 | -
48 | -
49 | -
50 |
51 | ### Query builders
52 |
53 | // Fetch Builder
54 | // Aggreation Builder
55 | // Update Builder
56 | // Delete Builder
57 |
--------------------------------------------------------------------------------
/Tests/DataStructureTests/LazyMapSetTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LazyMapSetTests.swift
3 | //
4 | //
5 | // Created by EZOU on 2023/9/1.
6 | //
7 |
8 | import XCTest
9 |
10 | @testable import Crush
11 |
12 | class LazyMapSetTests: XCTestCase {
13 | func test_count_shouldEqualToUnderlyingSet() {
14 | let nsset = NSSet(array: [0])
15 | let sut = LazyMapSet.from(nsset) {
16 | "\($0)"
17 | } to: {
18 | Int($0)!
19 | }
20 | XCTAssertEqual(nsset.count, sut.count)
21 | }
22 |
23 | func test_objectEnumerator_shouldIterateAllMappedObjects() {
24 | let nsset = NSSet(array: [0])
25 | let sut = LazyMapSet.from(nsset) {
26 | "\($0)"
27 | } to: {
28 | Int($0)!
29 | }
30 | let array = sut.objectEnumerator().allObjects as? [String]
31 | XCTAssertEqual(["0"], array)
32 | }
33 |
34 | func test_member_shouldReturnTheObject() {
35 | let nsset = NSSet(array: [0])
36 | let sut = LazyMapSet.from(nsset) {
37 | "\($0)"
38 | } to: {
39 | Int($0)!
40 | }
41 | XCTAssertEqual(sut.member("0") as? String, "0")
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/docs/js/highlight-js-http.163e45b6.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * This source file is part of the Swift.org open source project
3 | *
4 | * Copyright (c) 2021 Apple Inc. and the Swift project authors
5 | * Licensed under Apache License v2.0 with Runtime Library Exception
6 | *
7 | * See https://swift.org/LICENSE.txt for license information
8 | * See https://swift.org/CONTRIBUTORS.txt for Swift project authors
9 | */
10 | (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["highlight-js-http"],{c01d:function(e,n){function a(e){const n=e.regex,a="HTTP/(2|1\\.[01])",s=/[A-Za-z][A-Za-z0-9-]*/,t={className:"attribute",begin:n.concat("^",s,"(?=\\:\\s)"),starts:{contains:[{className:"punctuation",begin:/: /,relevance:0,starts:{end:"$",relevance:0}}]}},i=[t,{begin:"\\n\\n",starts:{subLanguage:[],endsWithParent:!0}}];return{name:"HTTP",aliases:["https"],illegal:/\S/,contains:[{begin:"^(?="+a+" \\d{3})",end:/$/,contains:[{className:"meta",begin:a},{className:"number",begin:"\\b\\d{3}\\b"}],starts:{end:/\b\B/,illegal:/\S/,contains:i}},{begin:"(?=^[A-Z]+ (.*?) "+a+"$)",end:/$/,contains:[{className:"string",begin:" ",end:" ",excludeBegin:!0,excludeEnd:!0},{className:"meta",begin:a},{className:"keyword",begin:"[A-Z]+"}],starts:{end:/\b\B/,illegal:/\S/,contains:i}},e.inherit(t,{relevance:0})]}}e.exports=a}}]);
--------------------------------------------------------------------------------
/Tests/QueryBuilderTests/UpdateBuilderTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UpdateBuilderTests.swift
3 | //
4 | //
5 | // Created by EZOU on 2022/7/22.
6 | //
7 |
8 | import Foundation
9 | import XCTest
10 |
11 | @testable import Crush
12 |
13 | class UpdateBuilderTests: XCTestCase {
14 |
15 | class TestEntity: Entity {
16 | var intValue = Value.Int64("intValue")
17 | var entity = Relation.ToOne("entity")
18 | }
19 |
20 | var sut: DataContainer!
21 |
22 | override func setUpWithError() throws {
23 | sut = try?.load(storages: .sqliteInMemory(), dataModel: .init(name: "DataModel", [TestEntity()]))
24 | }
25 |
26 | func test_updateIntValue_shouldUpdateAttribute() throws {
27 | let entity: TestEntity.ReadOnly = try sut.startSession().sync { context in
28 | let entity = context.create(entity: TestEntity.self)
29 | entity.intValue = 0
30 | try context.commit()
31 | return entity
32 | }
33 |
34 | let ids = try sut
35 | .update(for: TestEntity.self)
36 | .update(\.intValue, value: 10)
37 | .exec()
38 |
39 | XCTAssertEqual(ids, [entity.objectID])
40 | XCTAssertEqual(entity.intValue, 10)
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Sources/Crush.docc/UndoRedoInSession.md:
--------------------------------------------------------------------------------
1 | # Undo/Redo In Session
2 |
3 | Core Data supports undo/redo by default. In Crush, the redo/undo stack is managed through ``Session``
4 |
5 | ## How to enable undo/redo
6 |
7 | To enable undo/redo, you need to call ``Session/enableUndoManager()``. And the session would start tracking the change stack block by block. Also, you can disable undo/redo by calling ``Session/disableUndoManager()``.
8 |
9 | ## Example of usage
10 |
11 | ```swift
12 | let session = dataContainer.startInteractiveSession()
13 |
14 | session.enableUndoManager()
15 |
16 | let todo: Todo.ReadOnly = session.sync { context in
17 | // make changes
18 | let todo = context.create(entity: Todo.self)
19 | todo.title = "ORIGINAL TITLE"
20 | return todo
21 | }
22 |
23 | session.sync { context in
24 | let todo = context.edit(object: todo)
25 | todo.title = "NEW TITLE"
26 | }
27 |
28 | print(todo.title) // NEW TITLE
29 |
30 | session.undo()
31 |
32 | print(todo.title) // ORIGINAL TITLE
33 |
34 | session.redo()
35 |
36 | print(todo.title) // NEW TITLE
37 |
38 | ```
39 |
40 | Please be aware of that the undo/redo stack is not enabled by default. You need to call ``Session/enableUndoManager()`` to enable it. And the undo/redo stack is flushed once the session committed.
41 |
42 |
--------------------------------------------------------------------------------
/Tests/DataModelTests/PartialObjectTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PartialObjectTests.swift
3 | //
4 | //
5 | // Created by ezou on 2021/10/22.
6 | //
7 |
8 | import CoreData
9 | import Foundation
10 | import XCTest
11 |
12 | @testable import Crush
13 |
14 | class PartialObjectTests: XCTestCase {
15 | class TestEntity: Entity {
16 | var integerValue = Value.Int64("integerValue")
17 | var stringValue = Value.String("stringValue")
18 | }
19 |
20 | func test_initWithPairs_shouldMergeIntoDictionary() {
21 | let sut = PartialObject(
22 | EntityKeyValuePair(\.integerValue, 10)
23 | )
24 | let target = [
25 | "integerValue": Int64(10)
26 | ]
27 | XCTAssertEqual(sut.store as! [String: Int64], target)
28 | }
29 |
30 | func test_dynamicKeyPathUpdateValue_shouldWriteIntoStore() {
31 | let sut = PartialObject()
32 | sut.integerValue = 10
33 | XCTAssertEqual(sut.store["integerValue"] as? Int64, 10)
34 | }
35 |
36 | func test_dynamicKeyPathUpdateValue_shouldReadFromStore() {
37 | let sut = PartialObject(
38 | EntityKeyValuePair(\.integerValue, 10)
39 | )
40 | let target = sut.integerValue
41 | XCTAssertEqual(target, 10)
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Sources/DataStructure/LazyMapSet.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LazyMapSet.swift
3 | //
4 | //
5 | // Created by EZOU on 2023/9/1.
6 | //
7 |
8 | import Foundation
9 |
10 | final class LazyMapSet: NSSet {
11 |
12 | static func from(_ nsset: NSSet, from: @escaping (T) -> U, to: @escaping (U) -> T) -> LazyMapSet {
13 | let this = LazyMapSet()
14 | this.nsset = nsset
15 | this.from = from
16 | this.to = to
17 | return this
18 | }
19 |
20 | var from: ((T) -> U)!
21 | var to: ((U) -> T)!
22 |
23 | var nsset: NSSet!
24 |
25 | override var count: Int {
26 | nsset.count
27 | }
28 |
29 | override func member(_ object: Any) -> Any? {
30 | guard let object = object as? U,
31 | let result = nsset.member(to(object)) as? T else { return nil }
32 | return from(result)
33 | }
34 |
35 | override func objectEnumerator() -> NSEnumerator {
36 | MapEnumerationIterator(iterator: nsset.makeIterator(), from: from)
37 | }
38 |
39 | override func copy() -> Any {
40 | LazyMapSet.from(nsset.copy() as! NSSet, from: from, to: to)
41 | }
42 |
43 | override func mutableCopy() -> Any {
44 | LazyMapMutableSet.from(nsset.mutableCopy() as! NSMutableSet, from: from, to: to)
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Sources/Crush.docc/TypesOfSessions.md:
--------------------------------------------------------------------------------
1 | # Types of Sessions
2 |
3 | Introduce provided session types
4 |
5 | ## General Session
6 |
7 | This is the default session type. It is suitable for most use cases. The execution context, which is derived from the writer context, is created in a background thread. And the read only objects are presented in the UI context which working on main thread.
8 |
9 | Typically, this type of session mutates data in the background and presents data in the main thread. And the data mutation is unavailable until changes are saved.
10 |
11 | ## Interactive Session
12 |
13 | This session type is suitable for interactive use cases. The execution context, which is derived from the writer context, is created in the main thread and the read only objects are presented in the UI context which working on main thread.
14 |
15 | The use case of this session type is to perform data mutation in the main thread, and present data in the main thread. It is suitable for interactive use cases, such as editing data in a form. All changes are available during the session regardless .
16 |
17 | ## Table of comparison between different session types
18 |
19 | | Session Type | Execution Thread | UI Context | Use Case |
20 | | --- | --- | --- | --- |
21 | | General Session | Background thread | Main UI context | Apply data changes into the database
22 | | Interactive Session | Main thread | The writer context | Interactive data editing
23 |
--------------------------------------------------------------------------------
/Tests/DataStructureTests/LazyMapOrderedSetTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LazyMapOrderedSetTests.swift
3 | //
4 | //
5 | // Created by EZOU on 2023/9/1.
6 | //
7 |
8 | import XCTest
9 |
10 | @testable import Crush
11 |
12 | class LazyMapMutableOrderedSetTests: XCTestCase {
13 | func test_insert_shouldInsertMappedObject() {
14 | let orderedSet = NSMutableOrderedSet(array: [1, 2, 3])
15 | let sut = LazyMapMutableOrderedSet.from(orderedSet) {
16 | "\($0)"
17 | } to: {
18 | Int($0)!
19 | }
20 | sut.insert("0", at: 0)
21 | XCTAssertEqual(["0", "1", "2", "3"], sut.array as! [String])
22 | }
23 |
24 | func test_remove_shouldRemoveMappedObjectAtIndexSet() {
25 | let orderedSet = NSMutableOrderedSet(array: [1, 2, 3])
26 | let sut = LazyMapMutableOrderedSet.from(orderedSet) {
27 | "\($0)"
28 | } to: {
29 | Int($0)!
30 | }
31 | sut.removeObjects(at: [0, 1])
32 | XCTAssertEqual(["3"], sut.array as! [String])
33 | }
34 |
35 | func test_isEqual_shouldCompareUnderlyingSet() {
36 | let orderedSet = NSMutableOrderedSet(array: [1, 2, 3])
37 | let sut = LazyMapMutableOrderedSet.from(orderedSet) {
38 | "\($0)"
39 | } to: {
40 | Int($0)!
41 | }
42 | XCTAssertTrue(sut.isEqual(NSOrderedSet(array: ["1", "2", "3"])))
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Sources/Crush.docc/SigningSessionBlock.md:
--------------------------------------------------------------------------------
1 | # Signing Execution Block in Session
2 |
3 | Enable signing `transactionAuthor` for the code block
4 |
5 | ## What is transactionAuthor
6 |
7 | `transactionAuthor` is a property of `NSManagedObjectContext` that identifies the author of the transaction. It is used to track the changes made by each user in persistent history tracking.
8 |
9 | ## When to sign the transactionAuthor
10 |
11 | You should sign the `transactionAuthor` when you are performing a data mutation operation in a session.
12 |
13 | ## How to sign the transactionAuthor
14 |
15 | You can sign the `transactionAuthor` by providing `name` parameter of the execution method, both of sync and async methods, in `Session`:
16 |
17 | ```swift
18 |
19 | try session.sync(name: "John") { context in
20 | let entity = try context.create(MyEntity.self)
21 | entity.stringValue = "Hello world!"
22 | try context.commit()
23 | }
24 |
25 | ```
26 | ## Where would the transactionAuthor be used
27 |
28 | The `transactionAuthor` will be used in the `NSPersistentHistoryChange` object, which is used to track the changes made by each user. You can load the `NSPersistentHistoryChange` object by calling ``DataContainer/loadTransactionHistory(since:)``.
29 |
30 | ```swift
31 | let transactions = try dataContainer.loadTransactionHistory(since: targetDate)
32 |
33 | for transaction in transactions {
34 | let author = transction.author // signed author name
35 | }
36 | ```
37 |
--------------------------------------------------------------------------------
/Sources/DataModel/Entity/Property/Property+Attribute.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Property+Attribute.swift
3 | // Crush
4 | //
5 | // Created by ezou on 2019/9/26.
6 | // Copyright © 2019 ezou. All rights reserved.
7 | //
8 |
9 | import CoreData
10 |
11 | // MARK: - EntityAttribute
12 |
13 | public protocol AttributeProtocol: WritableProperty
14 | where
15 | PropertyType: AttributeType,
16 | Description: NSAttributeDescription
17 | { }
18 |
19 | extension AttributeProtocol {
20 | public var isAttribute: Bool { true }
21 |
22 | public var attributeType: NSAttributeType {
23 | PropertyType.nativeType
24 | }
25 | }
26 |
27 | public protocol ConcreteAttriuteProcotol: AttributeProtocol { }
28 |
29 |
30 | // MARK: - EntityAttributeType
31 | public class Attribute:
32 | ConcreteAttriuteProcotol,
33 | TransformableAttributeInitProtocol,
34 | TransientProperty
35 | {
36 | public typealias PredicateValue = PropertyType.PredicateValue
37 | public typealias PropertyValue = PropertyType.RuntimeValue
38 |
39 | public let name: String
40 |
41 | public required init(_ name: String) {
42 | self.name = name
43 | }
44 |
45 | public func createPropertyDescription() -> NSAttributeDescription {
46 | let description = NSAttributeDescription()
47 | description.name = name
48 | description.attributeType = attributeType
49 | return description
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/docs/favicon.svg:
--------------------------------------------------------------------------------
1 |
10 |
11 |
--------------------------------------------------------------------------------
/Tests/VersioningTests/MigrationTests/FethcedPropertyMigrationTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FethcedPropertyMigrationTests.swift
3 | //
4 | //
5 | // Created by EZOU on 2023/4/26.
6 | //
7 |
8 | import CoreData
9 | import Foundation
10 | import XCTest
11 |
12 | @testable import Crush
13 |
14 | class AddFetchedPropertyTests: XCTestCase {
15 | func test_createProperty_shouldSetupNameAndFetchRequest() {
16 | let fetchRequest = NSFetchRequest()
17 | let sut = AddFetchedProperty("NAME", fetchRequest: fetchRequest)
18 | var callback: [EntityMigrationCallback] = []
19 | let description = sut.createProperty(callbackStore: &callback)
20 | XCTAssertTrue(description is NSFetchedPropertyDescription)
21 | XCTAssertEqual(description.name, "NAME")
22 | XCTAssertIdentical((description as! NSFetchedPropertyDescription).fetchRequest, fetchRequest)
23 | }
24 | }
25 |
26 | class UpdateFetchedPropertyTests: XCTestCase {
27 | func test_migrateProperty_shouldUpdateNameAndFetchRequest() throws {
28 | let fetchRequest = NSFetchRequest()
29 | let sut = UpdateFetchedProperty("origin", name: "NAME", fetchRequest: fetchRequest)
30 | let description = NSFetchedPropertyDescription()
31 | var callback: [EntityMigrationCallback] = []
32 | _ = try sut.migrateProperty(description, callbackStore: &callback)
33 | XCTAssertEqual(description.name, "NAME")
34 | XCTAssertIdentical(description.fetchRequest, fetchRequest)
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.5
2 | // The swift-tools-version declares the minimum version of Swift required to build this package.
3 |
4 | import PackageDescription
5 |
6 | let package = Package(
7 | name: "Crush",
8 | platforms: [
9 | .macOS(.v10_13),
10 | .iOS(.v11),
11 | .watchOS(.v4),
12 | .tvOS(.v11),
13 | ],
14 | products: [
15 | // Products define the executables and libraries produced by a package, and make them visible to other packages.
16 | .library(
17 | name: "Crush",
18 | type: .`static`,
19 | targets: ["Crush"]),
20 | .library(
21 | name: "Crush-dynamic",
22 | type: .dynamic,
23 | targets: ["Crush"]),
24 | ],
25 | dependencies: [
26 | // Dependencies declare other packages that this package depends on.
27 | // .package(url: /* package url */, from: "1.0.0"),
28 | .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"),
29 | ],
30 | targets: [
31 | // Targets are the basic building blocks of a package. A target can define a module or a test suite.
32 | // Targets can depend on other targets in this package, and on products in packages which this package depends on.
33 | .target(
34 | name: "Crush",
35 | dependencies: [],
36 | path: "./Sources"),
37 | .testTarget(
38 | name: "CrushTests",
39 | dependencies: ["Crush"],
40 | path: "./Tests"),
41 | ])
42 |
--------------------------------------------------------------------------------
/Sources/Versioning/Migrator/AdHocMigrator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AdHocMigrator.swift
3 | //
4 | //
5 | // Created by ezou on 2021/10/15.
6 | //
7 |
8 | import CoreData
9 | import Foundation
10 |
11 | internal final class AdHocMigrator: Migrator {
12 | internal let lastActiveModel: NSManagedObjectModel?
13 | internal let migration: ModelMigration
14 |
15 | internal init(
16 | storage: ConcreteStorage,
17 | sourceModelName: String,
18 | migration: ModelMigration,
19 | dataModel: DataModel)
20 | {
21 | self.migration = migration
22 | self.lastActiveModel = .load(name: sourceModelName)
23 | super.init(storage: storage, dataModel: dataModel)
24 | }
25 |
26 | @discardableResult
27 | internal override func migrate() throws -> Bool {
28 | guard let sourceModel = lastActiveModel else { return false }
29 |
30 | let currentModel = dataModel.managedObjectModel
31 | let destinationModel = try migration.migrateModel(sourceModel)
32 | let isCompatible = currentModel.isCompactible(with: destinationModel)
33 |
34 | guard isCompatible else {
35 | throw MigrationError.incompatible
36 | }
37 |
38 | let mappingModel = try migration
39 | .createMappingModel(from: sourceModel, to: destinationModel)
40 |
41 | try migrateStore(
42 | name: dataModel.name,
43 | from: sourceModel,
44 | to: destinationModel,
45 | mappingModel: mappingModel)
46 |
47 | return true
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Sources/DataStructure/LazyMapOrderedSet.swift:
--------------------------------------------------------------------------------
1 | //
2 | // File.swift
3 | //
4 | //
5 | // Created by EZOU on 2023/9/1.
6 | //
7 |
8 | import Foundation
9 |
10 | final class LazyMapOrderedSet: NSOrderedSet {
11 |
12 | static func from(_ orderedSet: NSOrderedSet, from: @escaping (T) -> U, to: @escaping (U) -> T) -> LazyMapOrderedSet {
13 | let this = LazyMapOrderedSet()
14 | this.orderedSet = orderedSet
15 | this.from = from
16 | this.to = to
17 | return this
18 | }
19 |
20 | var from: ((T) -> U)!
21 | var to: ((U) -> T)!
22 |
23 | var orderedSet: NSOrderedSet!
24 |
25 | override var count: Int {
26 | orderedSet.count
27 | }
28 |
29 | override func contains(_ object: Any) -> Bool {
30 | guard let object = object as? U else { return false }
31 | return orderedSet.contains(object)
32 | }
33 |
34 | override func objectEnumerator() -> NSEnumerator {
35 | MapEnumerationIterator(iterator: orderedSet.makeIterator(), from: from)
36 | }
37 |
38 | override func object(at idx: Int) -> Any {
39 | let object = orderedSet.object(at: idx) as! T
40 | return from(object)
41 | }
42 |
43 | override func copy() -> Any {
44 | LazyMapOrderedSet.from(orderedSet.copy() as! NSOrderedSet, from: from, to: to)
45 | }
46 |
47 | override func mutableCopy() -> Any {
48 | LazyMapMutableOrderedSet
49 | .from(orderedSet.mutableCopy() as! NSMutableOrderedSet, from: from, to: to)
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Sources/Versioning/MigrationChainIterator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MigrationChainIterator.swift
3 | //
4 | //
5 | // Created by ezou on 2021/10/15.
6 | //
7 |
8 | import CoreData
9 | import Foundation
10 |
11 | internal class MigrationChainIterator: IteratorProtocol {
12 | internal struct Node {
13 | internal let name: String
14 | internal let mappingModel: NSMappingModel
15 | internal let destinationManagedObjectModel: NSManagedObjectModel
16 | }
17 |
18 | private var index: Int = 0
19 |
20 | internal let chain: MigrationChain
21 |
22 | internal init(_ chain: MigrationChain) {
23 | self.chain = chain
24 | }
25 |
26 | internal func next() -> Node? {
27 | guard let mappingModels = try? chain.mappingModels(),
28 | let managedObjectModels = try? chain.managedObjectModels(),
29 | mappingModels.count > index else { return nil }
30 | defer { index += 1 }
31 | return Node(
32 | name: chain.migrations[index+1].name,
33 | mappingModel: mappingModels[index],
34 | destinationManagedObjectModel: managedObjectModels[index+1])
35 | }
36 |
37 | internal func setActiveVersion(managedObjectModel: NSManagedObjectModel?) {
38 | guard let managedObjectModels = try? chain.managedObjectModels(),
39 | let managedObjectModel = managedObjectModel else {
40 | return index = 0
41 | }
42 | index = managedObjectModels.firstIndex(of: managedObjectModel) ?? 0
43 | }
44 |
45 | internal func reset() {
46 | index = 0
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Tests/UtilsTests/PersistentHashTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PersistentHashTests.swift
3 | //
4 | //
5 | // Created by ezou on 2022/2/5.
6 | //
7 |
8 | import Foundation
9 | import XCTest
10 |
11 | @testable import Crush
12 |
13 | public class PersistentHashTests: XCTestCase {
14 | func test_hashOrderedNumbers_shouldBeEqual() {
15 | let value = PersistentHash.ordered(10, 11)
16 | let sut = PersistentHash.ordered(10, 11)
17 | XCTAssertEqual(value, sut)
18 | }
19 |
20 | func test_hashReverseOrderedNumbers_shouldNotBeEqual() {
21 | let value = PersistentHash.ordered(10, 11)
22 | let sut = PersistentHash.ordered(11, 10)
23 | XCTAssertNotEqual(value, sut)
24 | }
25 |
26 | func test_hashUnorderedNumbers_shouldBeEqual() {
27 | let value = PersistentHash.unordered(10, 11)
28 | let sut = PersistentHash.unordered(10, 11)
29 | XCTAssertEqual(value, sut)
30 | }
31 |
32 | func test_hashReversedUnorderedNumbers_shouldBeEqual() {
33 | let value = PersistentHash.unordered(10, 11)
34 | let sut = PersistentHash.unordered(11, 10)
35 | XCTAssertEqual(value, sut)
36 | }
37 |
38 | func test_hashFromString_shouldBeEqual() {
39 | let value = PersistentHash.fromString("STRING")
40 | let sut = PersistentHash.fromString("STRING")
41 | XCTAssertEqual(value, sut)
42 | }
43 |
44 | func test_hashFromString_shouldNotBeEqual() {
45 | let value = PersistentHash.fromString("STRING")
46 | let sut = PersistentHash.fromString("ANOTHER STRING")
47 | XCTAssertNotEqual(value, sut)
48 | }
49 | }
50 |
51 |
--------------------------------------------------------------------------------
/docs/data/documentation/crush/userinfokey.json:
--------------------------------------------------------------------------------
1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"UserInfoKey"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/userinfokey"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/UserInfoKey","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"UserInfoKey"}],"title":"UserInfoKey","roleHeading":"Enumeration","role":"symbol","symbolKind":"enum","externalID":"s:5Crush11UserInfoKeyO","modules":[{"name":"Crush"}],"navigatorTitle":[{"kind":"identifier","text":"UserInfoKey"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush"]]},"references":{"doc://Crush/documentation/Crush/UserInfoKey":{"role":"symbol","title":"UserInfoKey","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"UserInfoKey"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/UserInfoKey","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"UserInfoKey"}],"url":"\/documentation\/crush\/userinfokey"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}}
--------------------------------------------------------------------------------
/Sources/DataModel/Entity/PartialObject.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PartialObject.swift
3 | //
4 | //
5 | // Created by ezou on 2021/10/16.
6 | //
7 |
8 | import Foundation
9 |
10 | @dynamicMemberLookup
11 | public final class PartialObject {
12 | internal var store: [String: Any] = [:]
13 |
14 | internal init(store: [String: Any]) {
15 | self.store = store
16 | }
17 | }
18 |
19 | extension PartialObject where T: Entity {
20 | public convenience init(_ pairs: EntityKeyValuePair...) {
21 | let store = pairs.reduce(into: [String: Any]()) {
22 | $0[$1.key] = $1.value
23 | }
24 | self.init(store: store)
25 | }
26 |
27 | public subscript(
28 | dynamicMember keyPath: KeyPath) -> S.RuntimeValue
29 | {
30 | get {
31 | let value = store[keyPath.propertyName]
32 | guard let result = value as? S.PropertyType.ManagedValue
33 | else { return .null }
34 | return S.PropertyType.convert(managedValue: result)
35 | }
36 | set {
37 | let value: S.PropertyType.ManagedValue =
38 | S.PropertyType.convert(runtimeValue: newValue)
39 | store[keyPath.propertyName] = value
40 | }
41 | }
42 | }
43 |
44 | public struct EntityKeyValuePair {
45 | public let key: String
46 | public let value: Any
47 |
48 | public init(
49 | _ keyPath: KeyPath,
50 | _ value: S.PropertyType.RuntimeValue)
51 | {
52 | self.key = keyPath.propertyName
53 | self.value = S.PropertyType.convert(runtimeValue: value)
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/Sources/DataModel/Entity/Property/PrimitiveAttributeType+Transformable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PrimitiveAttributeType+Transformable.swift
3 | //
4 | //
5 | // Created by ezou on 2021/10/18.
6 | //
7 |
8 | import CoreData
9 | import Foundation
10 |
11 | public protocol TransformableAttributeType: NSObject, NSCoding, PrimitiveAttributeType
12 | where
13 | RuntimeValue == PrimitiveType?,
14 | ManagedValue == PrimitiveType?,
15 | PredicateValue == PrimitiveType
16 | {
17 | associatedtype PrimitiveType = Self
18 |
19 | associatedtype RuntimeValue = PrimitiveType?
20 | associatedtype ManagedValue = PrimitiveType?
21 | associatedtype PredicateValue = PrimitiveType
22 |
23 | static var attributeValueClassName: String? { get }
24 | static var valueTransformerName: String? { get }
25 | }
26 |
27 | extension TransformableAttributeType {
28 | @inlinable public static var valueTransformerName: String? { nil }
29 | }
30 |
31 | extension TransformableAttributeType {
32 | @inlinable public static var nativeType: NSAttributeType { .transformableAttributeType }
33 | @inlinable public static var attributeValueClassName: String? { String(describing: Self.self) }
34 | }
35 |
36 | #if os(iOS) || os(watchOS)
37 | import UIKit.UIImage
38 | extension UIImage: PrimitiveAttributeType {
39 | public typealias PrimitiveType = UIImage
40 | }
41 |
42 | extension UIColor: PrimitiveAttributeType {
43 | public typealias PrimitiveType = UIColor
44 | }
45 | #endif
46 |
47 | extension NSCoding where Self: PrimitiveAttributeType & NSObject {
48 | @inlinable public static var nativeType: NSAttributeType { .transformableAttributeType }
49 | @inlinable public var predicateValue: NSObject { self }
50 | }
51 |
--------------------------------------------------------------------------------
/Sources/DataStructure/LazyMapMutableSet.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LazyMapMutableSet.swift
3 | //
4 | //
5 | // Created by EZOU on 2023/9/1.
6 | //
7 |
8 | import Foundation
9 |
10 | final class LazyMapMutableSet: NSMutableSet {
11 |
12 | static func from(_ mutableSet: NSMutableSet, from: @escaping (T) -> U, to: @escaping (U) -> T) -> LazyMapMutableSet {
13 | let this = LazyMapMutableSet()
14 | this.mutableSet = mutableSet
15 | this.from = from
16 | this.to = to
17 | return this
18 | }
19 |
20 | var from: ((T) -> U)!
21 | var to: ((U) -> T)!
22 |
23 | var mutableSet: NSMutableSet!
24 |
25 | override var count: Int {
26 | mutableSet.count
27 | }
28 |
29 | override func member(_ object: Any) -> Any? {
30 | guard let object = object as? U,
31 | let result = mutableSet.member(to(object)) as? T else { return nil }
32 | return from(result)
33 | }
34 |
35 | override func objectEnumerator() -> NSEnumerator {
36 | MapEnumerationIterator(iterator: mutableSet.makeIterator(), from: from)
37 | }
38 |
39 | override func add(_ object: Any) {
40 | guard let object = object as? U else { return }
41 | mutableSet.add(to(object))
42 | }
43 |
44 | override func remove(_ object: Any) {
45 | guard let object = object as? U else { return }
46 | mutableSet.remove(to(object))
47 | }
48 |
49 | override func copy() -> Any {
50 | LazyMapSet.from(mutableSet.copy() as! NSSet, from: from, to: to)
51 | }
52 |
53 | override func mutableCopy() -> Any {
54 | LazyMapMutableSet
55 | .from(mutableSet.mutableCopy() as! NSMutableSet, from: from, to: to)
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Sources/DataModel/Entity/Property/CodableAttributeType.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CodableAttributeType.swift
3 | //
4 | //
5 | // Created by ezou on 2021/10/18.
6 | //
7 |
8 | import CoreData
9 | import Foundation
10 |
11 | public protocol CodableAttributeType: AttributeType, PredicateEquatable, Codable, Hashable
12 | where
13 | RuntimeValue == Self?,
14 | ManagedValue == Data?,
15 | PredicateValue == Data
16 | {
17 | var data: Data { get set }
18 |
19 | static var encoder: JSONEncoder { get }
20 | static var decoder: JSONDecoder { get }
21 | }
22 |
23 | extension CodableAttributeType {
24 | @inlinable public static var defaultRuntimeValue: RuntimeValue { nil }
25 | @inlinable public static var defaultManagedValue: ManagedValue { nil }
26 |
27 | @inlinable
28 | public static func convert(managedValue: Data?) -> Self? {
29 | guard let value = managedValue else { return nil }
30 | return try! Self.decoder.decode(Self.self, from: value)
31 | }
32 |
33 | @inlinable
34 | public static func convert(runtimeValue: Self?) -> Data? {
35 | guard let value = runtimeValue else { return nil }
36 | return try! Self.encoder.encode(value)
37 | }
38 |
39 | public func hash(into hasher: inout Hasher) {
40 | hasher.combine(data)
41 | }
42 |
43 | @inlinable public static var encoder: JSONEncoder { JSONEncoder() }
44 | @inlinable public static var decoder: JSONDecoder { JSONDecoder() }
45 | @inlinable public static var nativeType: NSAttributeType { .binaryDataAttributeType }
46 |
47 | @inlinable public var predicateValue: NSObject { data as NSData }
48 | @inlinable public var data: Data {
49 | get { try! Self.encoder.encode(self) }
50 | mutating set { self = try! Self.decoder.decode(Self.self, from: newValue) }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Tests/Measurement.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Measurement.swift
3 | //
4 | //
5 | // Created by ezou on 2021/10/14.
6 | //
7 |
8 | import Foundation
9 |
10 | struct Measurement {
11 | let name: String
12 | let duration: Double
13 | let memoryConsumptionInBytes: UInt64
14 | }
15 |
16 | internal func measurement(name: String? = nil, block: () -> Void) -> Measurement {
17 | let startMemory = memory_usage()
18 | let startTime = mach_absolute_time()
19 | block()
20 | let endTime = mach_absolute_time()
21 | let endMemory = memory_usage()
22 | return Measurement(
23 | name: name ?? "untitled",
24 | duration: mach_to_milliseconds(endTime - startTime),
25 | memoryConsumptionInBytes: endMemory - startMemory)
26 | }
27 |
28 | private var timebase_info: mach_timebase_info = {
29 | var info = mach_timebase_info_data_t()
30 | mach_timebase_info(&info)
31 | return info
32 | }()
33 |
34 | private func mach_to_milliseconds(_ time: UInt64) -> Double {
35 | return Double(time * UInt64(timebase_info.numer)) / Double(timebase_info.denom) / 1_000_000
36 | }
37 |
38 | private func memory_usage() -> UInt64 {
39 | var taskInfo = mach_task_basic_info()
40 | var count = mach_msg_type_number_t(MemoryLayout.size)/4
41 | let kerr: kern_return_t = withUnsafeMutablePointer(to: &taskInfo) {
42 | $0.withMemoryRebound(to: integer_t.self, capacity: 1) {
43 | task_info(mach_task_self_, task_flavor_t(MACH_TASK_BASIC_INFO), $0, &count)
44 | }
45 | }
46 |
47 | if kerr == KERN_SUCCESS {
48 | return taskInfo.resident_size
49 | }
50 | else {
51 | fatalError("Error with task_info(): " +
52 | (String(cString: mach_error_string(kerr), encoding: String.Encoding.ascii) ?? "unknown error"))
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/Sources/DataModel/Entity/Property/EnumerableAttributeType.swift:
--------------------------------------------------------------------------------
1 | //
2 | // EnumerableAttributeType.swift
3 | //
4 | //
5 | // Created by ezou on 2021/10/18.
6 | //
7 |
8 | import CoreData
9 | import Foundation
10 |
11 | public protocol EnumerableAttributeType:
12 | RawRepresentable,
13 | AttributeType,
14 | PredicateEquatable,
15 | Hashable
16 | where
17 | RawValue: PredicateEquatable & Hashable,
18 | ManagedValue == RawAttributeType.ManagedValue,
19 | RuntimeValue == Self?,
20 | PredicateValue == RawAttributeType.PredicateValue,
21 | PredicateType == RawValue.PredicateType
22 | {
23 | associatedtype RawAttributeType: PrimitiveAttributeType
24 | associatedtype PredicateValue = RawValue
25 | associatedtype ManagedValue = RawValue?
26 | associatedtype RuntimeValue = Self?
27 | }
28 |
29 | extension EnumerableAttributeType {
30 | @inlinable public static var defaultRuntimeValue: RuntimeValue { nil }
31 | @inlinable public static var defaultManagedValue: ManagedValue { nil }
32 |
33 | public static func convert(managedValue: RawValue?) -> Self? {
34 | guard let value = managedValue else { return nil }
35 | return Self.init(rawValue: value)
36 | }
37 |
38 | @inlinable public static func convert(runtimeValue: Self?) -> RawValue? {
39 | runtimeValue?.rawValue
40 | }
41 |
42 | @inlinable public static var nativeType: NSAttributeType { RawAttributeType.nativeType }
43 | @inlinable public var predicateValue: PredicateType { self.rawValue.predicateValue }
44 |
45 | public func hash(into hasher: inout Hasher) {
46 | hasher.combine(rawValue)
47 | }
48 | }
49 |
50 | public protocol ComparableEnumerableAttributeType:
51 | EnumerableAttributeType, PredicateComparable
52 | where
53 | RawValue: PredicateComparable { }
54 |
--------------------------------------------------------------------------------
/docs/data/documentation/crush/entity/init().json:
--------------------------------------------------------------------------------
1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"required"},{"kind":"text","text":" "},{"kind":"keyword","text":"init"},{"kind":"text","text":"()"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/entity\/init()"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/Entity\/init()","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"title":"init()","roleHeading":"Initializer","role":"symbol","symbolKind":"init","externalID":"s:5Crush6EntityCACycfc","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/Entity"]]},"references":{"doc://Crush/documentation/Crush/Entity/init()":{"role":"symbol","title":"init()","fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Entity\/init()","kind":"symbol","type":"topic","url":"\/documentation\/crush\/entity\/init()"},"doc://Crush/documentation/Crush/Entity":{"role":"symbol","title":"Entity","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"Entity"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Entity","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Entity"}],"url":"\/documentation\/crush\/entity"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/entitymap/init().json:
--------------------------------------------------------------------------------
1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"init"},{"kind":"text","text":"()"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/entitymap\/init()"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/EntityMap\/init()","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"title":"init()","roleHeading":"Initializer","role":"symbol","symbolKind":"init","externalID":"s:5Crush9EntityMapCACycfc","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/EntityMap"]]},"references":{"doc://Crush/documentation/Crush/EntityMap/init()":{"role":"symbol","title":"init()","fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityMap\/init()","kind":"symbol","type":"topic","url":"\/documentation\/crush\/entitymap\/init()"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/EntityMap":{"role":"symbol","title":"EntityMap","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"EntityMap"}],"abstract":[{"type":"text","text":"Declare a map that describes relationships between entities."}],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityMap","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"EntityMap"}],"url":"\/documentation\/crush\/entitymap"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/relationship/relationshipprotocol-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/relationship\/relationshipprotocol-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/Relationship\/RelationshipProtocol-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Properties","identifiers":["doc:\/\/Crush\/documentation\/Crush\/Relationship\/isAttribute"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"RelationshipProtocol Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/Relationship"]]},"references":{"doc://Crush/documentation/Crush/Relationship":{"role":"symbol","title":"Relationship","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"Relationship"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Relationship","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Relationship"}],"url":"\/documentation\/crush\/relationship"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/Relationship/isAttribute":{"role":"symbol","title":"isAttribute","fragments":[{"kind":"keyword","text":"var"},{"kind":"text","text":" "},{"kind":"identifier","text":"isAttribute"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Relationship\/isAttribute","kind":"symbol","type":"topic","url":"\/documentation\/crush\/relationship\/isattribute"}}}
--------------------------------------------------------------------------------
/Sources/Crush.docc/CRUDOperations.md:
--------------------------------------------------------------------------------
1 | # CRUD Operations
2 |
3 | Simple example of CRUD Operations in Crush
4 |
5 | ## Start with Session
6 |
7 | All data mutation in Crush must be completed through a ``Session``. You can create a session by calling ``DataContainer/startSession(name:)``. All data mutation would not be persisted until you call ``Session/commit()``.
8 |
9 |
10 | ```swift
11 | let session = dataContainer.startSession()
12 |
13 | try session.sync { context in
14 | /*
15 | Do something
16 | */
17 | try context.commit() // Persist the changes
18 | }
19 | ```
20 |
21 | ## Create Operation
22 |
23 | You can create an entity by calling ``SessionContext/create(entity:)``
24 |
25 | ```swift
26 | try session.sync { context in
27 | let todo = context.create(entity: Todo.self)
28 | todo.title = "todo title"
29 | // setup the entity here
30 | try context.commit()
31 | }
32 | ```
33 |
34 | ## Read Operation
35 |
36 | ### Load by NSManagedObjectID
37 |
38 | You can load an entity by calling ``SessionContext/load(objectID:isFault:)``
39 |
40 | ```swift
41 | session.sync { context in
42 | let todo = context.load(objectID: injectedObjectID)
43 | }
44 | ```
45 |
46 | ### Fetch objects
47 |
48 | You can fetch objects by building a fetch request through ``SessionContext/fetch(for:)``
49 |
50 | ```swift
51 | session.sync { context in
52 | let todo = context.fetch(for: Todo.self)
53 | .where(\.title == "target title")
54 | .findOne()
55 | }
56 | ```
57 |
58 | ## Update Operation
59 |
60 | You can edit a readonly object by ``SessionContext/edit(object:)``
61 |
62 | ```swift
63 | try session.sync { context in
64 | let editableTodo = context.edit(object: todo)
65 | editableTodo.title = "new title"
66 | try context.commit()
67 | }
68 | ```
69 |
70 | ## Delete Operation
71 |
72 | You can delete an object by ``SessionContext/delete(_:)``
73 |
74 | ```swift
75 | try session.sync { context in
76 | context.delete(todo)
77 | try context.commit()
78 | }
79 | ```
80 |
--------------------------------------------------------------------------------
/docs/data/documentation/crush/entity/hashable-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/entity\/hashable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/Entity\/Hashable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Methods","identifiers":["doc:\/\/Crush\/documentation\/Crush\/Entity\/hash(into:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Hashable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/Entity"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/Entity":{"role":"symbol","title":"Entity","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"Entity"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Entity","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Entity"}],"url":"\/documentation\/crush\/entity"},"doc://Crush/documentation/Crush/Entity/hash(into:)":{"role":"symbol","title":"hash(into:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"hash"},{"kind":"text","text":"("},{"kind":"externalParam","text":"into"},{"kind":"text","text":": "},{"kind":"keyword","text":"inout"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"Hasher","preciseIdentifier":"s:s6HasherV"},{"kind":"text","text":")"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Entity\/hash(into:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/entity\/hash(into:)"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/migrationerror/error-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/migrationerror\/error-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/MigrationError\/Error-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Properties","identifiers":["doc:\/\/Crush\/documentation\/Crush\/MigrationError\/localizedDescription"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Error Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/MigrationError"]]},"references":{"doc://Crush/documentation/Crush/MigrationError/localizedDescription":{"role":"symbol","title":"localizedDescription","fragments":[{"kind":"keyword","text":"var"},{"kind":"text","text":" "},{"kind":"identifier","text":"localizedDescription"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MigrationError\/localizedDescription","kind":"symbol","type":"topic","url":"\/documentation\/crush\/migrationerror\/localizeddescription"},"doc://Crush/documentation/Crush/MigrationError":{"role":"symbol","title":"MigrationError","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"MigrationError"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MigrationError","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"MigrationError"}],"url":"\/documentation\/crush\/migrationerror"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/coredataerror/customstringconvertible-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/coredataerror\/customstringconvertible-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/CoreDataError\/CustomStringConvertible-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Properties","identifiers":["doc:\/\/Crush\/documentation\/Crush\/CoreDataError\/description"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"CustomStringConvertible Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/CoreDataError"]]},"references":{"doc://Crush/documentation/Crush/CoreDataError":{"role":"symbol","title":"CoreDataError","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"CoreDataError"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/CoreDataError","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"CoreDataError"}],"url":"\/documentation\/crush\/coredataerror"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/CoreDataError/description":{"role":"symbol","title":"description","fragments":[{"kind":"keyword","text":"var"},{"kind":"text","text":" "},{"kind":"identifier","text":"description"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/CoreDataError\/description","kind":"symbol","type":"topic","url":"\/documentation\/crush\/coredataerror\/description"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/coredataerror/error-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/coredataerror\/error-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/CoreDataError\/Error-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Properties","identifiers":["doc:\/\/Crush\/documentation\/Crush\/CoreDataError\/localizedDescription-15imi"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Error Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/CoreDataError"]]},"references":{"doc://Crush/documentation/Crush/CoreDataError/localizedDescription-15imi":{"role":"symbol","title":"localizedDescription","fragments":[{"kind":"keyword","text":"var"},{"kind":"text","text":" "},{"kind":"identifier","text":"localizedDescription"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/CoreDataError\/localizedDescription-15imi","kind":"symbol","type":"topic","url":"\/documentation\/crush\/coredataerror\/localizeddescription-15imi"},"doc://Crush/documentation/Crush/CoreDataError":{"role":"symbol","title":"CoreDataError","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"CoreDataError"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/CoreDataError","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"CoreDataError"}],"url":"\/documentation\/crush\/coredataerror"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/orderedset/init().json:
--------------------------------------------------------------------------------
1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"init"},{"kind":"text","text":"()"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/orderedset\/init()"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/OrderedSet\/init()","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"Inherited from "},{"type":"codeVoice","code":"SetAlgebra.init()"},{"type":"text","text":"."}],"kind":"symbol","metadata":{"fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"title":"init()","roleHeading":"Initializer","role":"symbol","symbolKind":"init","externalID":"s:5Crush10OrderedSetVACyxGycfc","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/OrderedSet"]]},"references":{"doc://Crush/documentation/Crush/OrderedSet/init()":{"role":"symbol","title":"init()","fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/OrderedSet\/init()","kind":"symbol","type":"topic","url":"\/documentation\/crush\/orderedset\/init()"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/OrderedSet":{"role":"symbol","title":"OrderedSet","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"OrderedSet"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/OrderedSet","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"OrderedSet"}],"url":"\/documentation\/crush\/orderedset"}}}
--------------------------------------------------------------------------------
/Sources/Utils/KeyPath+helper.swift:
--------------------------------------------------------------------------------
1 | //
2 | // KeyPath+helper.swift
3 | // Crush
4 | //
5 | // Created by ezou on 2019/9/20.
6 | // Copyright © 2019 ezou. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import CoreData
11 |
12 | extension AnyKeyPath {
13 | fileprivate static var lock = UnfairLock()
14 | fileprivate static var propertyNameCache: [AnyHashable: String] = [:]
15 |
16 | fileprivate var propertyNameCache: [AnyHashable: String] {
17 | get { Self.propertyNameCache }
18 | set { Self.propertyNameCache = newValue }
19 | }
20 | }
21 |
22 | extension PartialKeyPath where Root: Entity {
23 | var optionalPropertyName: String? {
24 | Self.lock.lock()
25 | defer { Self.lock.unlock() }
26 | return propertyNameCache[ObjectIdentifier(self)] ?? {
27 | let name = (Root()[keyPath: self] as? (any Property))?.name
28 | defer { if let name = name { propertyNameCache[ObjectIdentifier(self)] = name } }
29 | return name
30 | }()
31 | }
32 | }
33 |
34 | extension KeyPath where Root: Entity, Value: Property {
35 | var propertyName: String {
36 | Self.lock.lock()
37 | defer { Self.lock.unlock() }
38 | let key = AnyHashable(self)
39 | return propertyNameCache[key] ?? {
40 | let name = Root()[keyPath: self].name
41 | defer { propertyNameCache[key] = name }
42 | return name
43 | }()
44 | }
45 | }
46 |
47 | extension KeyPath: Expressible where Root: Entity, Value: Property {
48 | public func getHashValue() -> Int {
49 | propertyName.hashValue
50 | }
51 |
52 | public func asExpression() -> Any {
53 | propertyName
54 | }
55 | }
56 |
57 | extension KeyPath where Root: Entity, Value: RelationshipProtocol {
58 | public func extend(
59 | _ keyPath: KeyPath) -> String
60 | where
61 | Property: Crush.Property,
62 | Value.Destination == Target
63 | {
64 | "\(propertyName).\(keyPath.propertyName)"
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/docs/data/documentation/crush/objectdriver/customdebugstringconvertible-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/objectdriver\/customdebugstringconvertible-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/ObjectDriver\/CustomDebugStringConvertible-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Properties","identifiers":["doc:\/\/Crush\/documentation\/Crush\/ObjectDriver\/debugDescription"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"CustomDebugStringConvertible Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/ObjectDriver"]]},"references":{"doc://Crush/documentation/Crush/ObjectDriver":{"role":"symbol","title":"ObjectDriver","fragments":[{"kind":"keyword","text":"protocol"},{"kind":"text","text":" "},{"kind":"identifier","text":"ObjectDriver"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/ObjectDriver","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"ObjectDriver"}],"url":"\/documentation\/crush\/objectdriver"},"doc://Crush/documentation/Crush/ObjectDriver/debugDescription":{"role":"symbol","title":"debugDescription","fragments":[{"kind":"keyword","text":"var"},{"kind":"text","text":" "},{"kind":"identifier","text":"debugDescription"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/ObjectDriver\/debugDescription","kind":"symbol","type":"topic","url":"\/documentation\/crush\/objectdriver\/debugdescription"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/datacontainererror/error-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/datacontainererror\/error-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/DataContainerError\/Error-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Properties","identifiers":["doc:\/\/Crush\/documentation\/Crush\/DataContainerError\/localizedDescription"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Error Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/DataContainerError"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/DataContainerError/localizedDescription":{"role":"symbol","title":"localizedDescription","fragments":[{"kind":"keyword","text":"var"},{"kind":"text","text":" "},{"kind":"identifier","text":"localizedDescription"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/DataContainerError\/localizedDescription","kind":"symbol","type":"topic","url":"\/documentation\/crush\/datacontainererror\/localizeddescription"},"doc://Crush/documentation/Crush/DataContainerError":{"role":"symbol","title":"DataContainerError","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"DataContainerError"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/DataContainerError","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"DataContainerError"}],"url":"\/documentation\/crush\/datacontainererror"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/storage/equatable-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/storage\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/Storage\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/Storage\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/Storage"]]},"references":{"doc://Crush/documentation/Crush/Storage":{"role":"symbol","title":"Storage","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"Storage"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Storage","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Storage"}],"url":"\/documentation\/crush\/storage"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/Storage/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Storage\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/storage\/!=(_:_:)"}}}
--------------------------------------------------------------------------------
/Sources/Utils/SelectPath.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CoreData.swift
3 | //
4 | //
5 | // Created by EZOU on 2022/6/11.
6 | //
7 |
8 | import CoreData
9 |
10 | public final class SelectPath: Expressible, ExpressibleByStringLiteral {
11 |
12 | private(set)
13 | public var name: String
14 | public let path: String
15 |
16 | lazy var expression: NSExpressionDescription = {
17 | let desc = NSExpressionDescription()
18 | desc.name = name
19 | desc.expressionResultType = resolveResultType(from: path)
20 | desc.expression = NSExpression(forKeyPath: path)
21 | return desc
22 | }()
23 |
24 | public init(stringLiteral value: StringLiteralType) {
25 | name = value
26 | path = value
27 | }
28 |
29 | public init(_ keyPath: PartialKeyPath & Expressible, as asName: String? = nil) {
30 | path = keyPath.optionalPropertyName!
31 | name = asName ?? path
32 | }
33 |
34 | public init(_ keyPath: String, as asName: String? = nil) {
35 | name = asName ?? keyPath
36 | path = keyPath
37 | }
38 |
39 | public func getHashValue() -> Int {
40 | expression.hashValue
41 | }
42 |
43 | public func asExpression() -> Any {
44 | expression
45 | }
46 |
47 | public func `as`(name: String) -> Self {
48 | self.name = name
49 | return self
50 | }
51 |
52 | private func resolveResultType(from path: String) -> NSAttributeType {
53 | var desc = Entity.entity()
54 |
55 | for component in path.split(separator: ".") {
56 | let property = desc.propertiesByName[String(component)]
57 |
58 | switch property {
59 | case let attribute as NSAttributeDescription:
60 | return attribute.attributeType
61 | case let relation as NSRelationshipDescription:
62 | desc = relation.destinationEntity!
63 | continue
64 | default:
65 | break
66 | }
67 | }
68 |
69 | return .undefinedAttributeType
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/docs/data/documentation/crush/adhocmigrationerror/error-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/adhocmigrationerror\/error-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/AdHocMigrationError\/Error-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Properties","identifiers":["doc:\/\/Crush\/documentation\/Crush\/AdHocMigrationError\/localizedDescription"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Error Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/AdHocMigrationError"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/AdHocMigrationError":{"role":"symbol","title":"AdHocMigrationError","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"AdHocMigrationError"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/AdHocMigrationError","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"AdHocMigrationError"}],"url":"\/documentation\/crush\/adhocmigrationerror"},"doc://Crush/documentation/Crush/AdHocMigrationError/localizedDescription":{"role":"symbol","title":"localizedDescription","fragments":[{"kind":"keyword","text":"var"},{"kind":"text","text":" "},{"kind":"identifier","text":"localizedDescription"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/AdHocMigrationError\/localizedDescription","kind":"symbol","type":"topic","url":"\/documentation\/crush\/adhocmigrationerror\/localizeddescription"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/mutableset/init().json:
--------------------------------------------------------------------------------
1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"required"},{"kind":"text","text":" "},{"kind":"keyword","text":"init"},{"kind":"text","text":"()"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/mutableset\/init()"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/MutableSet\/init()","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"Inherited from "},{"type":"codeVoice","code":"SetAlgebra.init()"},{"type":"text","text":"."}],"kind":"symbol","metadata":{"fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"title":"init()","roleHeading":"Initializer","role":"symbol","symbolKind":"init","externalID":"s:5Crush10MutableSetCACyxGycfc","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/MutableSet"]]},"references":{"doc://Crush/documentation/Crush/MutableSet/init()":{"role":"symbol","title":"init()","fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MutableSet\/init()","kind":"symbol","type":"topic","url":"\/documentation\/crush\/mutableset\/init()"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/MutableSet":{"role":"symbol","title":"MutableSet","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"MutableSet"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MutableSet","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"MutableSet"}],"url":"\/documentation\/crush\/mutableset"}}}
--------------------------------------------------------------------------------
/Sources/Crush.docc/PropertyModifier.md:
--------------------------------------------------------------------------------
1 | # Property Modifier
2 |
3 | Crush provides multiple ways to modify the properties of an entity. This helps you separate concerns and configure a property by composition.
4 |
5 | ## Overview
6 |
7 | In Crush, declaring properties is straightforward. You can define a property using the following syntax:
8 |
9 | ``` swift
10 | let property = Value.Int16("property")
11 | ```
12 |
13 | By default, properties are declared without requiring extensive configuration. However, if you need to fine-tune the behavior of a property, you can achieve this through the use of property modifiers.
14 |
15 | ### Using Property Modifiers
16 |
17 | Property modifiers allow you to apply specific configurations to your properties. For instance, consider a scenario where you want to adjust the behavior of a property to make it optional and also mark it for indexing. You can achieve this using property modifiers.
18 |
19 | Here's an example of declaring a property with property modifiers:
20 |
21 | ``` swift
22 | @Indexed
23 | @Optional
24 | var property = Value.Int16("property")
25 | ```
26 |
27 | In this example, the `@Indexed` modifier indicates that the property should be indexed, which can improve query performance. The `@Optional` modifier specifies that the property is optional, meaning it does not need to have a value.
28 |
29 | By utilizing property modifiers, you can easily tailor the behavior of your properties to suit your specific needs, ensuring flexibility and efficiency in your codebase.
30 |
31 | ### General Modifers
32 |
33 | - ``Optional``
34 | - ``Required``
35 | - ``Transient``
36 | - ``Indexed``
37 | - ``IndexedBySpotlight``
38 | - ``Unique``
39 |
40 | ### Attribute Modifiers
41 |
42 | - ``Default``
43 | - ``ExternalBinaryDataStorage``
44 | - ``Validation``
45 | - ``PreservesValueInHistoryOnDeletion``
46 |
47 | ### Relationship Modifiers
48 |
49 | - ``Inverse``
50 | - ``MaxCount``
51 | - ``MinCount``
52 | - ``DeleteRule``
53 | - ``UnidirectionalInverse``
54 |
55 | > Tips: You can access all modifiers using ``PropertyModifiers``, ``AttributeModifiers``, and ``RelationshipModifiers``
56 |
--------------------------------------------------------------------------------
/docs/data/documentation/crush/entitytypedescriptor/init().json:
--------------------------------------------------------------------------------
1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"required"},{"kind":"text","text":" "},{"kind":"keyword","text":"init"},{"kind":"text","text":"()"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/entitytypedescriptor\/init()"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/EntityTypeDescriptor\/init()","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"title":"init()","roleHeading":"Initializer","role":"symbol","symbolKind":"init","externalID":"s:5Crush20EntityTypeDescriptorCACyxGycfc","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/EntityTypeDescriptor"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/EntityTypeDescriptor/init()":{"role":"symbol","title":"init()","fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityTypeDescriptor\/init()","kind":"symbol","type":"topic","url":"\/documentation\/crush\/entitytypedescriptor\/init()"},"doc://Crush/documentation/Crush/EntityTypeDescriptor":{"role":"symbol","title":"EntityTypeDescriptor","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"EntityTypeDescriptor"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityTypeDescriptor","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"EntityTypeDescriptor"}],"url":"\/documentation\/crush\/entitytypedescriptor"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/objectdriver/hashable-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/objectdriver\/hashable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/ObjectDriver\/Hashable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Methods","identifiers":["doc:\/\/Crush\/documentation\/Crush\/ObjectDriver\/hash(into:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Hashable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/ObjectDriver"]]},"references":{"doc://Crush/documentation/Crush/ObjectDriver/hash(into:)":{"role":"symbol","title":"hash(into:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"hash"},{"kind":"text","text":"("},{"kind":"externalParam","text":"into"},{"kind":"text","text":": "},{"kind":"keyword","text":"inout"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"Hasher","preciseIdentifier":"s:s6HasherV"},{"kind":"text","text":")"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/ObjectDriver\/hash(into:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/objectdriver\/hash(into:)"},"doc://Crush/documentation/Crush/ObjectDriver":{"role":"symbol","title":"ObjectDriver","fragments":[{"kind":"keyword","text":"protocol"},{"kind":"text","text":" "},{"kind":"identifier","text":"ObjectDriver"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/ObjectDriver","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"ObjectDriver"}],"url":"\/documentation\/crush\/objectdriver"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}}
--------------------------------------------------------------------------------
/Tests/DataStructureTests/LazyMapMutableSetTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LazyMapMutableSetTests.swift
3 | //
4 | //
5 | // Created by EZOU on 2023/9/1.
6 | //
7 |
8 | import XCTest
9 |
10 | @testable import Crush
11 |
12 | class LazyMapMutableSetTests: XCTestCase {
13 |
14 | func test_add_shouldMapAddedObject() {
15 | let mutableSet = NSMutableSet()
16 | let sut = LazyMapMutableSet.from(mutableSet) {
17 | "\($0)"
18 | } to: {
19 | Int($0)!
20 | }
21 | sut.add("0")
22 | XCTAssertTrue(mutableSet.contains(0))
23 | }
24 |
25 | func test_remove_shouldMapRemovedObject() {
26 | let mutableSet = NSMutableSet(array: [0])
27 | let sut = LazyMapMutableSet.from(mutableSet) {
28 | "\($0)"
29 | } to: {
30 | Int($0)!
31 | }
32 | sut.remove("0")
33 | XCTAssertEqual(mutableSet.count, 0)
34 | }
35 |
36 | func test_count_shouldEqualToUnderlyingSet() {
37 | let mutableSet = NSMutableSet(array: [0])
38 | let sut = LazyMapMutableSet.from(mutableSet) {
39 | "\($0)"
40 | } to: {
41 | Int($0)!
42 | }
43 | XCTAssertEqual(mutableSet.count, sut.count)
44 | }
45 |
46 | func test_objectEnumerator_shouldIterateAllMappedObjects() {
47 | let mutableSet = NSMutableSet(array: [0])
48 | let sut = LazyMapMutableSet.from(mutableSet) {
49 | "\($0)"
50 | } to: {
51 | Int($0)!
52 | }
53 | let array = sut.objectEnumerator().allObjects as? [String]
54 | XCTAssertEqual(["0"], array)
55 | }
56 |
57 | func test_mutableCopy_oldInstanceShouldRemainUnchanged() {
58 | let mutableSet = NSMutableSet(array: [0])
59 | let sut = LazyMapMutableSet.from(mutableSet) {
60 | "\($0)"
61 | } to: {
62 | Int($0)!
63 | }
64 | let result = sut.mutableCopy() as! NSMutableSet
65 | result.add("1")
66 | XCTAssertFalse(sut.contains("1"))
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/docs/data/documentation/crush/mutableset/equatable-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/mutableset\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/MutableSet\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/MutableSet\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/MutableSet"]]},"references":{"doc://Crush/documentation/Crush/MutableSet":{"role":"symbol","title":"MutableSet","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"MutableSet"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MutableSet","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"MutableSet"}],"url":"\/documentation\/crush\/mutableset"},"doc://Crush/documentation/Crush/MutableSet/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MutableSet\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/mutableset\/!=(_:_:)"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/orderedset/equatable-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/orderedset\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/OrderedSet\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/OrderedSet\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/OrderedSet"]]},"references":{"doc://Crush/documentation/Crush/OrderedSet/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/OrderedSet\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/orderedset\/!=(_:_:)"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/OrderedSet":{"role":"symbol","title":"OrderedSet","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"OrderedSet"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/OrderedSet","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"OrderedSet"}],"url":"\/documentation\/crush\/orderedset"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/entity/readaleobject-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/entity\/readaleobject-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/Entity\/ReadaleObject-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Type Aliases","identifiers":["doc:\/\/Crush\/documentation\/Crush\/Entity\/ReadOnly"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"ReadaleObject Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/Entity"]]},"references":{"doc://Crush/documentation/Crush/Entity/ReadOnly":{"conformance":{"constraints":[{"type":"codeVoice","code":"Self"},{"type":"text","text":" inherits "},{"type":"codeVoice","code":"Entity"},{"type":"text","text":"."}],"availabilityPrefix":[{"type":"text","text":"Available when"}],"conformancePrefix":[{"type":"text","text":"Conforms when"}]},"role":"symbol","title":"Entity.ReadOnly","fragments":[{"kind":"keyword","text":"typealias"},{"kind":"text","text":" "},{"kind":"identifier","text":"ReadOnly"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Entity\/ReadOnly","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"ReadOnly"}],"url":"\/documentation\/crush\/entity\/readonly"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/Entity":{"role":"symbol","title":"Entity","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"Entity"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Entity","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Entity"}],"url":"\/documentation\/crush\/entity"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/migrationmodelingerror/error-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/migrationmodelingerror\/error-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/MigrationModelingError\/Error-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Properties","identifiers":["doc:\/\/Crush\/documentation\/Crush\/MigrationModelingError\/localizedDescription"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Error Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/MigrationModelingError"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/MigrationModelingError":{"role":"symbol","title":"MigrationModelingError","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"MigrationModelingError"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MigrationModelingError","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"MigrationModelingError"}],"url":"\/documentation\/crush\/migrationmodelingerror"},"doc://Crush/documentation/Crush/MigrationModelingError/localizedDescription":{"role":"symbol","title":"localizedDescription","fragments":[{"kind":"keyword","text":"var"},{"kind":"text","text":" "},{"kind":"identifier","text":"localizedDescription"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MigrationModelingError\/localizedDescription","kind":"symbol","type":"topic","url":"\/documentation\/crush\/migrationmodelingerror\/localizeddescription"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/configuration/init().json:
--------------------------------------------------------------------------------
1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"required"},{"kind":"text","text":" "},{"kind":"keyword","text":"init"},{"kind":"text","text":"()"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/configuration\/init()"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/Configuration\/init()","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"title":"init()","roleHeading":"Initializer","role":"symbol","symbolKind":"init","externalID":"s:5Crush13ConfigurationCACyxGycfc","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/Configuration"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/Configuration":{"role":"symbol","title":"Configuration","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"Configuration"}],"abstract":[{"type":"text","text":"Assign "},{"type":"codeVoice","code":"T"},{"type":"text","text":" entity to specified configuration group"}],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Configuration","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Configuration"}],"url":"\/documentation\/crush\/configuration"},"doc://Crush/documentation/Crush/Configuration/init()":{"role":"symbol","title":"init()","fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Configuration\/init()","kind":"symbol","type":"topic","url":"\/documentation\/crush\/configuration\/init()"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/migrationerror/notmigrated.json:
--------------------------------------------------------------------------------
1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"notMigrated"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/migrationerror\/notmigrated"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/MigrationError\/notMigrated","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"notMigrated"}],"title":"MigrationError.notMigrated","roleHeading":"Case","role":"symbol","symbolKind":"case","externalID":"s:5Crush14MigrationErrorO11notMigratedyA2CmF","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/MigrationError"]]},"references":{"doc://Crush/documentation/Crush/MigrationError/notMigrated":{"role":"symbol","title":"MigrationError.notMigrated","fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"notMigrated"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MigrationError\/notMigrated","kind":"symbol","type":"topic","url":"\/documentation\/crush\/migrationerror\/notmigrated"},"doc://Crush/documentation/Crush/MigrationError":{"role":"symbol","title":"MigrationError","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"MigrationError"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MigrationError","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"MigrationError"}],"url":"\/documentation\/crush\/migrationerror"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/fetchsorteroption/default.json:
--------------------------------------------------------------------------------
1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"`default`"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/fetchsorteroption\/default"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption\/default","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"`default`"}],"title":"FetchSorterOption.default","roleHeading":"Case","role":"symbol","symbolKind":"case","externalID":"s:5Crush17FetchSorterOptionO7defaultyA2CmF","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption"]]},"references":{"doc://Crush/documentation/Crush/FetchSorterOption":{"role":"symbol","title":"FetchSorterOption","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"FetchSorterOption"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"FetchSorterOption"}],"url":"\/documentation\/crush\/fetchsorteroption"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/FetchSorterOption/default":{"role":"symbol","title":"FetchSorterOption.default","fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"`default`"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption\/default","kind":"symbol","type":"topic","url":"\/documentation\/crush\/fetchsorteroption\/default"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/objectdriver/equatable-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/objectdriver\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/ObjectDriver\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/ObjectDriver\/==(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/ObjectDriver"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/ObjectDriver":{"role":"symbol","title":"ObjectDriver","fragments":[{"kind":"keyword","text":"protocol"},{"kind":"text","text":" "},{"kind":"identifier","text":"ObjectDriver"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/ObjectDriver","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"ObjectDriver"}],"url":"\/documentation\/crush\/objectdriver"},"doc://Crush/documentation/Crush/ObjectDriver/==(_:_:)":{"role":"symbol","title":"==(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"=="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/ObjectDriver\/==(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/objectdriver\/==(_:_:)"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/searchstring/equatable-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/searchstring\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/SearchString\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/SearchString\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/SearchString"]]},"references":{"doc://Crush/documentation/Crush/SearchString":{"role":"symbol","title":"SearchString","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"SearchString"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/SearchString","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"SearchString"}],"url":"\/documentation\/crush\/searchstring"},"doc://Crush/documentation/Crush/SearchString/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/SearchString\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/searchstring\/!=(_:_:)"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/entityabstraction/concrete.json:
--------------------------------------------------------------------------------
1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"concrete"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/entityabstraction\/concrete"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/EntityAbstraction\/concrete","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"concrete"}],"title":"EntityAbstraction.concrete","roleHeading":"Case","role":"symbol","symbolKind":"case","externalID":"s:5Crush17EntityAbstractionO8concreteyA2CmF","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/EntityAbstraction"]]},"references":{"doc://Crush/documentation/Crush/EntityAbstraction/concrete":{"role":"symbol","title":"EntityAbstraction.concrete","fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"concrete"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityAbstraction\/concrete","kind":"symbol","type":"topic","url":"\/documentation\/crush\/entityabstraction\/concrete"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/EntityAbstraction":{"role":"symbol","title":"EntityAbstraction","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"EntityAbstraction"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityAbstraction","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"EntityAbstraction"}],"url":"\/documentation\/crush\/entityabstraction"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/migrationerror/incompatible.json:
--------------------------------------------------------------------------------
1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"incompatible"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/migrationerror\/incompatible"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/MigrationError\/incompatible","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"incompatible"}],"title":"MigrationError.incompatible","roleHeading":"Case","role":"symbol","symbolKind":"case","externalID":"s:5Crush14MigrationErrorO12incompatibleyA2CmF","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/MigrationError"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/MigrationError":{"role":"symbol","title":"MigrationError","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"MigrationError"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MigrationError","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"MigrationError"}],"url":"\/documentation\/crush\/migrationerror"},"doc://Crush/documentation/Crush/MigrationError/incompatible":{"role":"symbol","title":"MigrationError.incompatible","fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"incompatible"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MigrationError\/incompatible","kind":"symbol","type":"topic","url":"\/documentation\/crush\/migrationerror\/incompatible"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/storageoption/equatable-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/storageoption\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/StorageOption\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/StorageOption\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/StorageOption"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/StorageOption":{"role":"symbol","title":"StorageOption","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"StorageOption"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/StorageOption","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"StorageOption"}],"url":"\/documentation\/crush\/storageoption"},"doc://Crush/documentation/Crush/StorageOption/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/StorageOption\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/storageoption\/!=(_:_:)"}}}
--------------------------------------------------------------------------------
/Sources/Crush.docc/IntroducingSession.md:
--------------------------------------------------------------------------------
1 | # Introducing Session
2 |
3 | This article explains what a `Crush/Session` is and how to use it.
4 |
5 | ## What is Session?
6 |
7 | A ``Session`` is a lightweight object that represents a single unit of work with the database. It provides a collection of methods that allow you to create, fetch, and delete objects in the database. More importantly, it manages the lifecycle of the `NSManagedObjectContext` and ensures that all data mutations are thread-safe.
8 |
9 | ### Structure of a Session
10 |
11 | A session is composed of three `NSManagedObjectContext`s, each with a different purpose:
12 |
13 | - **Execution context**: This context is responsible for performing data mutations.
14 | - **UI context**: This context is responsible for presenting data on the main thread.
15 |
16 | By separating the execution context and the UI context, we can ensure that the main thread is free from direct communication with the database. This separation of concerns allows for a smoother user experience and helps prevent issues such as UI lag or freezes.
17 |
18 | You don't need to worry about the lifecycle of these contexts. The ``Session`` will automatically create and dispose of them for you, and also, data mutation methods are exposed through ``SessionContext`` APIs. The only decision to make is whether to execute these commands synchronously or asynchronously.
19 |
20 | ### Data isolation
21 |
22 | Each ``Session`` is isolated from other ``Session``s. This means that changes made in one session will not be visible to other sessions until they are committed. This allows you to perform multiple operations in parallel without worrying about data conflicts. However, you still need to be aware of data conflicts between different ``Session``s and make sure they are handled properly by the merge policy or error handler.
23 |
24 | ## How to use Session
25 |
26 | Using ``Session``, you can easily perform CRUD operations on the database:
27 |
28 | ```swift
29 | let session = try dataContainer.startSession()
30 | try session.sync { context in
31 | let todo = try context.create(Todo.self)
32 | todo.title = "Hello world!"
33 | try context.commit()
34 | }
35 | ```
36 |
37 |
--------------------------------------------------------------------------------
/docs/data/documentation/crush/fetchsorteroption/localized.json:
--------------------------------------------------------------------------------
1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"localized"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/fetchsorteroption\/localized"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption\/localized","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"localized"}],"title":"FetchSorterOption.localized","roleHeading":"Case","role":"symbol","symbolKind":"case","externalID":"s:5Crush17FetchSorterOptionO9localizedyA2CmF","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/FetchSorterOption":{"role":"symbol","title":"FetchSorterOption","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"FetchSorterOption"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"FetchSorterOption"}],"url":"\/documentation\/crush\/fetchsorteroption"},"doc://Crush/documentation/Crush/FetchSorterOption/localized":{"role":"symbol","title":"FetchSorterOption.localized","fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"localized"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption\/localized","kind":"symbol","type":"topic","url":"\/documentation\/crush\/fetchsorteroption\/localized"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/adhocmigration/equatable-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/adhocmigration\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/AdHocMigration\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/AdHocMigration\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/AdHocMigration"]]},"references":{"doc://Crush/documentation/Crush/AdHocMigration/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/AdHocMigration\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/adhocmigration\/!=(_:_:)"},"doc://Crush/documentation/Crush/AdHocMigration":{"role":"symbol","title":"AdHocMigration","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"AdHocMigration"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/AdHocMigration","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"AdHocMigration"}],"url":"\/documentation\/crush\/adhocmigration"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/migrationerror/equatable-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/migrationerror\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/MigrationError\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/MigrationError\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/MigrationError"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/MigrationError/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MigrationError\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/migrationerror\/!=(_:_:)"},"doc://Crush/documentation/Crush/MigrationError":{"role":"symbol","title":"MigrationError","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"MigrationError"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MigrationError","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"MigrationError"}],"url":"\/documentation\/crush\/migrationerror"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/requestexecutor/received.json:
--------------------------------------------------------------------------------
1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"Received"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/requestexecutor\/received"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/RequestExecutor\/Received","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"role":"symbol","title":"Received","roleHeading":"Associated Type","fragments":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"Received"}],"symbolKind":"associatedtype","externalID":"s:5Crush15RequestExecutorP8ReceivedQa","required":true,"modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/RequestExecutor"]]},"references":{"doc://Crush/documentation/Crush/RequestExecutor":{"role":"symbol","title":"RequestExecutor","fragments":[{"kind":"keyword","text":"protocol"},{"kind":"text","text":" "},{"kind":"identifier","text":"RequestExecutor"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/RequestExecutor","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"RequestExecutor"}],"url":"\/documentation\/crush\/requestexecutor"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/RequestExecutor/Received":{"role":"symbol","title":"Received","fragments":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"Received"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/RequestExecutor\/Received","kind":"symbol","required":true,"type":"topic","url":"\/documentation\/crush\/requestexecutor\/received"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/entityinheritance/multitable.json:
--------------------------------------------------------------------------------
1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"multiTable"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/entityinheritance\/multitable"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/EntityInheritance\/multiTable","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"multiTable"}],"title":"EntityInheritance.multiTable","roleHeading":"Case","role":"symbol","symbolKind":"case","externalID":"s:5Crush17EntityInheritanceO10multiTableyA2CmF","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/EntityInheritance"]]},"references":{"doc://Crush/documentation/Crush/EntityInheritance":{"role":"symbol","title":"EntityInheritance","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"EntityInheritance"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityInheritance","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"EntityInheritance"}],"url":"\/documentation\/crush\/entityinheritance"},"doc://Crush/documentation/Crush/EntityInheritance/multiTable":{"role":"symbol","title":"EntityInheritance.multiTable","fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"multiTable"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityInheritance\/multiTable","kind":"symbol","type":"topic","url":"\/documentation\/crush\/entityinheritance\/multitable"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/propertytype/managedvalue.json:
--------------------------------------------------------------------------------
1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"ManagedValue"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/propertytype\/managedvalue"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/PropertyType\/ManagedValue","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"role":"symbol","title":"ManagedValue","roleHeading":"Associated Type","fragments":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"ManagedValue"}],"symbolKind":"associatedtype","externalID":"s:5Crush12PropertyTypeP12ManagedValueQa","required":true,"modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/PropertyType"]]},"references":{"doc://Crush/documentation/Crush/PropertyType/ManagedValue":{"role":"symbol","title":"ManagedValue","fragments":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"ManagedValue"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/PropertyType\/ManagedValue","kind":"symbol","required":true,"type":"topic","url":"\/documentation\/crush\/propertytype\/managedvalue"},"doc://Crush/documentation/Crush/PropertyType":{"role":"symbol","title":"PropertyType","fragments":[{"kind":"keyword","text":"protocol"},{"kind":"text","text":" "},{"kind":"identifier","text":"PropertyType"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/PropertyType","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"PropertyType"}],"url":"\/documentation\/crush\/propertytype"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/propertytype/runtimevalue.json:
--------------------------------------------------------------------------------
1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"RuntimeValue"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/propertytype\/runtimevalue"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/PropertyType\/RuntimeValue","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"role":"symbol","title":"RuntimeValue","roleHeading":"Associated Type","fragments":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"RuntimeValue"}],"symbolKind":"associatedtype","externalID":"s:5Crush12PropertyTypeP12RuntimeValueQa","required":true,"modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/PropertyType"]]},"references":{"doc://Crush/documentation/Crush/PropertyType/RuntimeValue":{"role":"symbol","title":"RuntimeValue","fragments":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"RuntimeValue"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/PropertyType\/RuntimeValue","kind":"symbol","required":true,"type":"topic","url":"\/documentation\/crush\/propertytype\/runtimevalue"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/PropertyType":{"role":"symbol","title":"PropertyType","fragments":[{"kind":"keyword","text":"protocol"},{"kind":"text","text":" "},{"kind":"identifier","text":"PropertyType"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/PropertyType","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"PropertyType"}],"url":"\/documentation\/crush\/propertytype"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/updateattribute/updatepropertymigration-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/updateattribute\/updatepropertymigration-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/UpdateAttribute\/UpdatePropertyMigration-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Methods","identifiers":["doc:\/\/Crush\/documentation\/Crush\/UpdateAttribute\/versionHashModifier(_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"UpdatePropertyMigration Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/UpdateAttribute"]]},"references":{"doc://Crush/documentation/Crush/UpdateAttribute/versionHashModifier(_:)":{"role":"symbol","title":"versionHashModifier(_:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"versionHashModifier"},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"},{"kind":"text","text":"?) -> "},{"kind":"typeIdentifier","text":"Self"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/UpdateAttribute\/versionHashModifier(_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/updateattribute\/versionhashmodifier(_:)"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/UpdateAttribute":{"role":"symbol","title":"UpdateAttribute","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"UpdateAttribute"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/UpdateAttribute","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"UpdateAttribute"}],"url":"\/documentation\/crush\/updateattribute"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/entityinheritance/singletable.json:
--------------------------------------------------------------------------------
1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"singleTable"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/entityinheritance\/singletable"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/EntityInheritance\/singleTable","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"singleTable"}],"title":"EntityInheritance.singleTable","roleHeading":"Case","role":"symbol","symbolKind":"case","externalID":"s:5Crush17EntityInheritanceO11singleTableyA2CmF","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/EntityInheritance"]]},"references":{"doc://Crush/documentation/Crush/EntityInheritance/singleTable":{"role":"symbol","title":"EntityInheritance.singleTable","fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"singleTable"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityInheritance\/singleTable","kind":"symbol","type":"topic","url":"\/documentation\/crush\/entityinheritance\/singletable"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/EntityInheritance":{"role":"symbol","title":"EntityInheritance","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"EntityInheritance"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityInheritance","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"EntityInheritance"}],"url":"\/documentation\/crush\/entityinheritance"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/primarykey/equatable-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/primarykey\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/PrimaryKey\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/PrimaryKey\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/PrimaryKey"]]},"references":{"doc://Crush/documentation/Crush/PrimaryKey":{"role":"symbol","title":"PrimaryKey","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"PrimaryKey"}],"abstract":[{"type":"text","text":"Represents a primary key for an entity in Core Data."}],"identifier":"doc:\/\/Crush\/documentation\/Crush\/PrimaryKey","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"PrimaryKey"}],"url":"\/documentation\/crush\/primarykey"},"doc://Crush/documentation/Crush/PrimaryKey/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/PrimaryKey\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/primarykey\/!=(_:_:)"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/session/undo().json:
--------------------------------------------------------------------------------
1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"undo"},{"kind":"text","text":"()"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/session\/undo()"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/Session\/undo()","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"Undoes the last change made to the session."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"undo"},{"kind":"text","text":"()"}],"title":"undo()","roleHeading":"Instance Method","role":"symbol","symbolKind":"method","externalID":"s:5Crush7SessionC4undoyyF","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/Session"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/Session/undo()":{"role":"symbol","title":"undo()","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"undo"},{"kind":"text","text":"()"}],"abstract":[{"type":"text","text":"Undoes the last change made to the session."}],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Session\/undo()","kind":"symbol","type":"topic","url":"\/documentation\/crush\/session\/undo()"},"doc://Crush/documentation/Crush/Session":{"role":"symbol","title":"Session","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"Session"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Session","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Session"}],"url":"\/documentation\/crush\/session"}}}
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Crush
2 |
3 | Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality
4 |
5 | ## Overview
6 |
7 | 🕹️ Take full control of your CoreData management.
8 | 🧑💻 100% managed code, no code generation required.
9 | 📖 Free from Xcode GUI, and human-friendly diff records on git.
10 |
11 | ### Installation
12 |
13 | Make sure you've declared `Crush` as your dependency before getting started
14 |
15 | ```swift
16 | let package = Package(
17 | dependencies: [
18 | .package(
19 | url: "https://github.com/ezoushen/Crush",
20 | from: "TARGET_VERSION"
21 | ),
22 | ],
23 | targets: [
24 | .target(
25 | name: "",
26 | dependencies: [
27 | "Crush"
28 | ]
29 | )
30 | ]
31 | )
32 | ```
33 |
34 | ## Usage
35 |
36 | Only three steps to start using Crush
37 |
38 | **1. Define your schema**
39 |
40 | ```swift
41 | class Todo: Entity {
42 | @Required
43 | var title = Value.String("title") // A required string property named "title"
44 |
45 | @Optional
46 | var memo = Value.String("memo") // An optional string property named "memo"
47 |
48 | @Required
49 | @Default(false)
50 | var finished = Value.Bool("finished")
51 |
52 | @Optional
53 | var parent = Relation.ToOne("parent") // An optional relationship to another Todo
54 |
55 | @Optional
56 | @Inverse(\.parent)
57 | var children = Relation.ToMany("children")
58 | }
59 | ```
60 |
61 | **2. Create your DataContainer**
62 |
63 | ```swift
64 | let container = try DataContainer.load(
65 | storages: .sqlite(url: targetURL),
66 | dataModel: DataModel(name: "V1", [ Todo() ]))
67 | ```
68 |
69 | **3. Start coding 🔥🔥🔥**
70 |
71 | ```swift
72 | try container.startSession().sync { context in
73 | let todo = context.create(Todo.self)
74 | todo.title = "Hello Crush"
75 | try context.commit()
76 | }
77 | ```
78 |
79 | ## Documentation
80 |
81 | Swift DocC style documentation is available [here](https://ezoushen.github.io/Crush/documentation/crush)
82 |
83 | ## Coorporation
84 |
85 | If you want to contribute to the project, please feel free to open a pull request/issue.
86 |
--------------------------------------------------------------------------------
/docs/data/documentation/crush/mutableorderedset/init().json:
--------------------------------------------------------------------------------
1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"required"},{"kind":"text","text":" "},{"kind":"keyword","text":"init"},{"kind":"text","text":"()"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/mutableorderedset\/init()"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/MutableOrderedSet\/init()","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"Inherited from "},{"type":"codeVoice","code":"RangeReplaceableCollection.init()"},{"type":"text","text":"."}],"kind":"symbol","metadata":{"fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"title":"init()","roleHeading":"Initializer","role":"symbol","symbolKind":"init","externalID":"s:5Crush17MutableOrderedSetCACyxGycfc","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/MutableOrderedSet"]]},"references":{"doc://Crush/documentation/Crush/MutableOrderedSet/init()":{"role":"symbol","title":"init()","fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MutableOrderedSet\/init()","kind":"symbol","type":"topic","url":"\/documentation\/crush\/mutableorderedset\/init()"},"doc://Crush/documentation/Crush/MutableOrderedSet":{"role":"symbol","title":"MutableOrderedSet","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"MutableOrderedSet"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MutableOrderedSet","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"MutableOrderedSet"}],"url":"\/documentation\/crush\/mutableorderedset"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/propertytype/predicatevalue.json:
--------------------------------------------------------------------------------
1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"PredicateValue"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/propertytype\/predicatevalue"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/PropertyType\/PredicateValue","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"role":"symbol","title":"PredicateValue","roleHeading":"Associated Type","fragments":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"PredicateValue"}],"symbolKind":"associatedtype","externalID":"s:5Crush12PropertyTypeP14PredicateValueQa","required":true,"modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/PropertyType"]]},"references":{"doc://Crush/documentation/Crush/PropertyType":{"role":"symbol","title":"PropertyType","fragments":[{"kind":"keyword","text":"protocol"},{"kind":"text","text":" "},{"kind":"identifier","text":"PropertyType"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/PropertyType","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"PropertyType"}],"url":"\/documentation\/crush\/propertytype"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/PropertyType/PredicateValue":{"role":"symbol","title":"PredicateValue","fragments":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"PredicateValue"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/PropertyType\/PredicateValue","kind":"symbol","required":true,"type":"topic","url":"\/documentation\/crush\/propertytype\/predicatevalue"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/unsafesessionproperty/safe.json:
--------------------------------------------------------------------------------
1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"Safe"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/unsafesessionproperty\/safe"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/UnsafeSessionProperty\/Safe","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"role":"symbol","title":"Safe","roleHeading":"Associated Type","fragments":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"Safe"}],"symbolKind":"associatedtype","externalID":"s:5Crush21UnsafeSessionPropertyP4SafeQa","required":true,"modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/UnsafeSessionProperty"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/UnsafeSessionProperty":{"role":"symbol","title":"UnsafeSessionProperty","fragments":[{"kind":"keyword","text":"protocol"},{"kind":"text","text":" "},{"kind":"identifier","text":"UnsafeSessionProperty"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/UnsafeSessionProperty","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"UnsafeSessionProperty"}],"url":"\/documentation\/crush\/unsafesessionproperty"},"doc://Crush/documentation/Crush/UnsafeSessionProperty/Safe":{"role":"symbol","title":"Safe","fragments":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"Safe"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/UnsafeSessionProperty\/Safe","kind":"symbol","required":true,"type":"topic","url":"\/documentation\/crush\/unsafesessionproperty\/safe"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/entityabstraction/equatable-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/entityabstraction\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/EntityAbstraction\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/EntityAbstraction\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/EntityAbstraction"]]},"references":{"doc://Crush/documentation/Crush/EntityAbstraction/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityAbstraction\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/entityabstraction\/!=(_:_:)"},"doc://Crush/documentation/Crush/EntityAbstraction":{"role":"symbol","title":"EntityAbstraction","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"EntityAbstraction"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityAbstraction","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"EntityAbstraction"}],"url":"\/documentation\/crush\/entityabstraction"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/entityinheritance/equatable-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/entityinheritance\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/EntityInheritance\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/EntityInheritance\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/EntityInheritance"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/EntityInheritance/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityInheritance\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/entityinheritance\/!=(_:_:)"},"doc://Crush/documentation/Crush/EntityInheritance":{"role":"symbol","title":"EntityInheritance","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"EntityInheritance"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityInheritance","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"EntityInheritance"}],"url":"\/documentation\/crush\/entityinheritance"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/fetchsorteroption/equatable-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/fetchsorteroption\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption"]]},"references":{"doc://Crush/documentation/Crush/FetchSorterOption":{"role":"symbol","title":"FetchSorterOption","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"FetchSorterOption"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"FetchSorterOption"}],"url":"\/documentation\/crush\/fetchsorteroption"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/FetchSorterOption/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/fetchsorteroption\/!=(_:_:)"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/mutableorderedset/equatable-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/mutableorderedset\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/MutableOrderedSet\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/MutableOrderedSet\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/MutableOrderedSet"]]},"references":{"doc://Crush/documentation/Crush/MutableOrderedSet/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MutableOrderedSet\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/mutableorderedset\/!=(_:_:)"},"doc://Crush/documentation/Crush/MutableOrderedSet":{"role":"symbol","title":"MutableOrderedSet","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"MutableOrderedSet"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MutableOrderedSet","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"MutableOrderedSet"}],"url":"\/documentation\/crush\/mutableorderedset"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/session/redo().json:
--------------------------------------------------------------------------------
1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"redo"},{"kind":"text","text":"()"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/session\/redo()"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/Session\/redo()","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"Redoes the last change that was undone in the session."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"redo"},{"kind":"text","text":"()"}],"title":"redo()","roleHeading":"Instance Method","role":"symbol","symbolKind":"method","externalID":"s:5Crush7SessionC4redoyyF","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/Session"]]},"references":{"doc://Crush/documentation/Crush/Session":{"role":"symbol","title":"Session","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"Session"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Session","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Session"}],"url":"\/documentation\/crush\/session"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/Session/redo()":{"role":"symbol","title":"redo()","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"redo"},{"kind":"text","text":"()"}],"abstract":[{"type":"text","text":"Redoes the last change that was undone in the session."}],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Session\/redo()","kind":"symbol","type":"topic","url":"\/documentation\/crush\/session\/redo()"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/codableattributetype/hashable-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/codableattributetype\/hashable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/CodableAttributeType\/Hashable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Methods","identifiers":["doc:\/\/Crush\/documentation\/Crush\/CodableAttributeType\/hash(into:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Hashable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/CodableAttributeType"]]},"references":{"doc://Crush/documentation/Crush/CodableAttributeType/hash(into:)":{"role":"symbol","title":"hash(into:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"hash"},{"kind":"text","text":"("},{"kind":"externalParam","text":"into"},{"kind":"text","text":": "},{"kind":"keyword","text":"inout"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"Hasher","preciseIdentifier":"s:s6HasherV"},{"kind":"text","text":")"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/CodableAttributeType\/hash(into:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/codableattributetype\/hash(into:)"},"doc://Crush/documentation/Crush/CodableAttributeType":{"role":"symbol","title":"CodableAttributeType","fragments":[{"kind":"keyword","text":"protocol"},{"kind":"text","text":" "},{"kind":"identifier","text":"CodableAttributeType"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/CodableAttributeType","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"CodableAttributeType"}],"url":"\/documentation\/crush\/codableattributetype"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/datacontainererror/equatable-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/datacontainererror\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/DataContainerError\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/DataContainerError\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/DataContainerError"]]},"references":{"doc://Crush/documentation/Crush/DataContainerError":{"role":"symbol","title":"DataContainerError","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"DataContainerError"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/DataContainerError","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"DataContainerError"}],"url":"\/documentation\/crush\/datacontainererror"},"doc://Crush/documentation/Crush/DataContainerError/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/DataContainerError\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/datacontainererror\/!=(_:_:)"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/entitymigrationcallback.json:
--------------------------------------------------------------------------------
1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"typealias"},{"kind":"text","text":" "},{"kind":"identifier","text":"EntityMigrationCallback"},{"kind":"text","text":" = (["},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"},{"kind":"text","text":" : "},{"kind":"typeIdentifier","text":"NSEntityDescription","preciseIdentifier":"c:objc(cs)NSEntityDescription"},{"kind":"text","text":"]) "},{"kind":"keyword","text":"throws"},{"kind":"text","text":" -> "},{"kind":"typeIdentifier","text":"Void","preciseIdentifier":"s:s4Voida"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/entitymigrationcallback"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/EntityMigrationCallback","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"typealias"},{"kind":"text","text":" "},{"kind":"identifier","text":"EntityMigrationCallback"}],"title":"EntityMigrationCallback","roleHeading":"Type Alias","role":"symbol","symbolKind":"typealias","externalID":"s:5Crush23EntityMigrationCallbacka","modules":[{"name":"Crush"}],"navigatorTitle":[{"kind":"identifier","text":"EntityMigrationCallback"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/EntityMigrationCallback":{"role":"symbol","title":"EntityMigrationCallback","fragments":[{"kind":"keyword","text":"typealias"},{"kind":"text","text":" "},{"kind":"identifier","text":"EntityMigrationCallback"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityMigrationCallback","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"EntityMigrationCallback"}],"url":"\/documentation\/crush\/entitymigrationcallback"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/updaterelationship/updatepropertymigration-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/updaterelationship\/updatepropertymigration-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/UpdateRelationship\/UpdatePropertyMigration-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Methods","identifiers":["doc:\/\/Crush\/documentation\/Crush\/UpdateRelationship\/versionHashModifier(_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"UpdatePropertyMigration Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/UpdateRelationship"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/UpdateRelationship/versionHashModifier(_:)":{"role":"symbol","title":"versionHashModifier(_:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"versionHashModifier"},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"},{"kind":"text","text":"?) -> "},{"kind":"typeIdentifier","text":"Self"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/UpdateRelationship\/versionHashModifier(_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/updaterelationship\/versionhashmodifier(_:)"},"doc://Crush/documentation/Crush/UpdateRelationship":{"role":"symbol","title":"UpdateRelationship","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"UpdateRelationship"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/UpdateRelationship","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"UpdateRelationship"}],"url":"\/documentation\/crush\/updaterelationship"}}}
--------------------------------------------------------------------------------
/Assertions/Assertions.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | /// drop-in replacements
4 | #if DEBUG
5 | func assert(_ condition: @autoclosure () -> Bool,_ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) {
6 | Assertions.assertClosure(condition(), message(), file, line)
7 | }
8 |
9 | func assertionFailure(_ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) {
10 | Assertions.assertionFailureClosure(message(), file, line)
11 | }
12 |
13 | func precondition(_ condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) {
14 | Assertions.preconditionClosure(condition(), message(), file, line)
15 | }
16 |
17 | func preconditionFailure(_ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) -> Never {
18 | Assertions.preconditionFailureClosure(message(), file, line)
19 | }
20 |
21 | func fatalError(_ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) -> Never {
22 | Assertions.fatalErrorClosure(message(), file, line)
23 | }
24 |
25 | /// Stores custom assertions closures, by default it points to Swift functions. But test target can override them.
26 | public class Assertions {
27 |
28 | public static var assertClosure = swiftAssertClosure
29 | public static var assertionFailureClosure = swiftAssertionFailureClosure
30 | public static var preconditionClosure = swiftPreconditionClosure
31 | public static var preconditionFailureClosure = swiftPreconditionFailureClosure
32 | public static var fatalErrorClosure = swiftFatalErrorClosure
33 |
34 | public static let swiftAssertClosure = { Swift.assert($0, $1, file: $2, line: $3) }
35 | public static let swiftAssertionFailureClosure = { Swift.assertionFailure($0, file: $1, line: $2) }
36 | public static let swiftPreconditionClosure = { Swift.precondition($0, $1, file: $2, line: $3) }
37 | public static let swiftPreconditionFailureClosure = { Swift.preconditionFailure($0, file: $1, line: $2) }
38 | public static let swiftFatalErrorClosure = { Swift.fatalError($0, file: $1, line: $2) }
39 | }
40 | #endif
41 |
--------------------------------------------------------------------------------
/Tests/Utils/Publishers+helper.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Publisher+helper.swift
3 | //
4 | //
5 | // Created by ezou on 2022/1/29.
6 | //
7 |
8 | #if canImport(Combine)
9 | import Combine
10 | import XCTest
11 |
12 | // Reference: https://www.swiftbysundell.com/articles/unit-testing-combine-based-swift-code/
13 | @available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
14 | extension XCTestCase {
15 | func awaitPublisher(
16 | _ publisher: T,
17 | timeout: TimeInterval = 1,
18 | file: StaticString = #file,
19 | line: UInt = #line,
20 | completion: () throws -> Void = { }
21 | ) throws -> T.Output {
22 | // This time, we use Swift's Result type to keep track
23 | // of the result of our Combine pipeline:
24 | var result: Result?
25 | let expectation = self.expectation(description: "Awaiting publisher")
26 |
27 | let cancellable = publisher.sink(
28 | receiveCompletion: { completion in
29 | switch completion {
30 | case .failure(let error):
31 | result = .failure(error)
32 | case .finished:
33 | break
34 | }
35 |
36 | expectation.fulfill()
37 | },
38 | receiveValue: { value in
39 | result = .success(value)
40 | }
41 | )
42 |
43 | try completion()
44 |
45 | // Just like before, we await the expectation that we
46 | // created at the top of our test, and once done, we
47 | // also cancel our cancellable to avoid getting any
48 | // unused variable warnings:
49 | waitForExpectations(timeout: timeout)
50 | cancellable.cancel()
51 |
52 | // Here we pass the original file and line number that
53 | // our utility was called at, to tell XCTest to report
54 | // any encountered errors at that original call site:
55 | let unwrappedResult = try XCTUnwrap(
56 | result,
57 | "Awaited publisher did not produce any output",
58 | file: file,
59 | line: line
60 | )
61 |
62 | return try unwrappedResult.get()
63 | }
64 | }
65 | #endif
66 |
--------------------------------------------------------------------------------
/docs/data/documentation/crush/fetchsorteroption/caseinsensitive.json:
--------------------------------------------------------------------------------
1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"caseInsensitive"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/fetchsorteroption\/caseinsensitive"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption\/caseInsensitive","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"caseInsensitive"}],"title":"FetchSorterOption.caseInsensitive","roleHeading":"Case","role":"symbol","symbolKind":"case","externalID":"s:5Crush17FetchSorterOptionO15caseInsensitiveyA2CmF","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption"]]},"references":{"doc://Crush/documentation/Crush/FetchSorterOption/caseInsensitive":{"role":"symbol","title":"FetchSorterOption.caseInsensitive","fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"caseInsensitive"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption\/caseInsensitive","kind":"symbol","type":"topic","url":"\/documentation\/crush\/fetchsorteroption\/caseinsensitive"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/FetchSorterOption":{"role":"symbol","title":"FetchSorterOption","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"FetchSorterOption"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"FetchSorterOption"}],"url":"\/documentation\/crush\/fetchsorteroption"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/updateattribute/propertymigration-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/updateattribute\/propertymigration-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/UpdateAttribute\/PropertyMigration-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Methods","identifiers":["doc:\/\/Crush\/documentation\/Crush\/UpdateAttribute\/customize(_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"PropertyMigration Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/UpdateAttribute"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/UpdateAttribute":{"role":"symbol","title":"UpdateAttribute","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"UpdateAttribute"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/UpdateAttribute","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"UpdateAttribute"}],"url":"\/documentation\/crush\/updateattribute"},"doc://Crush/documentation/Crush/UpdateAttribute/customize(_:)":{"role":"symbol","title":"customize(_:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"customize"},{"kind":"text","text":"(("},{"kind":"keyword","text":"inout"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Void","preciseIdentifier":"s:s4Voida"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Self"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/UpdateAttribute\/customize(_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/updateattribute\/customize(_:)"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/adhocmigrationerror/equatable-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/adhocmigrationerror\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/AdHocMigrationError\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/AdHocMigrationError\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/AdHocMigrationError"]]},"references":{"doc://Crush/documentation/Crush/AdHocMigrationError/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/AdHocMigrationError\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/adhocmigrationerror\/!=(_:_:)"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/AdHocMigrationError":{"role":"symbol","title":"AdHocMigrationError","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"AdHocMigrationError"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/AdHocMigrationError","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"AdHocMigrationError"}],"url":"\/documentation\/crush\/adhocmigrationerror"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/manageddriver/customdebugstringconvertible-implementations.json:
--------------------------------------------------------------------------------
1 | {"variants":[{"paths":["\/documentation\/crush\/manageddriver\/customdebugstringconvertible-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/ManagedDriver\/CustomDebugStringConvertible-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Properties","identifiers":["doc:\/\/Crush\/documentation\/Crush\/ManagedDriver\/debugDescription"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"CustomDebugStringConvertible Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/ManagedDriver"]]},"references":{"doc://Crush/documentation/Crush/ManagedDriver":{"role":"symbol","title":"ManagedDriver","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"ManagedDriver"}],"abstract":[{"type":"text","text":"Access "},{"type":"codeVoice","code":"NSManagedObject"},{"type":"text","text":" data flexibly, especially when dealing with inheritance relationships."}],"identifier":"doc:\/\/Crush\/documentation\/Crush\/ManagedDriver","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"ManagedDriver"}],"url":"\/documentation\/crush\/manageddriver"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/ManagedDriver/debugDescription":{"role":"symbol","title":"debugDescription","fragments":[{"kind":"keyword","text":"var"},{"kind":"text","text":" "},{"kind":"identifier","text":"debugDescription"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/ManagedDriver\/debugDescription","kind":"symbol","type":"topic","url":"\/documentation\/crush\/manageddriver\/debugdescription"}}}
--------------------------------------------------------------------------------
/docs/data/documentation/crush/migrator.json:
--------------------------------------------------------------------------------
1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"Migrator"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/migrator"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/Migrator","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Methods","identifiers":["doc:\/\/Crush\/documentation\/Crush\/Migrator\/migrate()"]}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"Migrator"}],"title":"Migrator","roleHeading":"Class","role":"symbol","symbolKind":"class","externalID":"s:5Crush8MigratorC","modules":[{"name":"Crush"}],"navigatorTitle":[{"kind":"identifier","text":"Migrator"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush"]]},"references":{"doc://Crush/documentation/Crush/Migrator":{"role":"symbol","title":"Migrator","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"Migrator"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Migrator","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Migrator"}],"url":"\/documentation\/crush\/migrator"},"doc://Crush/documentation/Crush/Migrator/migrate()":{"role":"symbol","title":"migrate()","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"migrate"},{"kind":"text","text":"() "},{"kind":"keyword","text":"throws"},{"kind":"text","text":" -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Migrator\/migrate()","kind":"symbol","type":"topic","url":"\/documentation\/crush\/migrator\/migrate()"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}}
--------------------------------------------------------------------------------
/docs/js/highlight-js-xml.9c3688c7.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * This source file is part of the Swift.org open source project
3 | *
4 | * Copyright (c) 2021 Apple Inc. and the Swift project authors
5 | * Licensed under Apache License v2.0 with Runtime Library Exception
6 | *
7 | * See https://swift.org/LICENSE.txt for license information
8 | * See https://swift.org/CONTRIBUTORS.txt for Swift project authors
9 | */
10 | (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["highlight-js-xml"],{"8dcb":function(e,n){function a(e){const n=e.regex,a=n.concat(/[A-Z_]/,n.optional(/[A-Z0-9_.-]*:/),/[A-Z0-9_.-]*/),s=/[A-Za-z0-9._:-]+/,t={className:"symbol",begin:/&[a-z]+;|[0-9]+;|[a-f0-9]+;/},i={begin:/\s/,contains:[{className:"keyword",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}]},c=e.inherit(i,{begin:/\(/,end:/\)/}),l=e.inherit(e.APOS_STRING_MODE,{className:"string"}),r=e.inherit(e.QUOTE_STRING_MODE,{className:"string"}),g={endsWithParent:!0,illegal:/,relevance:0,contains:[{className:"attr",begin:s,relevance:0},{begin:/=\s*/,relevance:0,contains:[{className:"string",endsParent:!0,variants:[{begin:/"/,end:/"/,contains:[t]},{begin:/'/,end:/'/,contains:[t]},{begin:/[^\s"'=<>`]+/}]}]}]};return{name:"HTML, XML",aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"],case_insensitive:!0,contains:[{className:"meta",begin://,relevance:10,contains:[i,r,l,c,{begin:/\[/,end:/\]/,contains:[{className:"meta",begin://,contains:[i,c,r,l]}]}]},e.COMMENT(//,{relevance:10}),{begin://,relevance:10},t,{className:"meta",begin:/<\?xml/,end:/\?>/,relevance:10},{className:"tag",begin:/