diff --git a/.swiftlint.yml b/.swiftlint.yml
index d455616..eca1903 100644
--- a/.swiftlint.yml
+++ b/.swiftlint.yml
@@ -1,12 +1,18 @@
# Basic Configuration
opt_in_rules:
+- anyobject_protocol
- array_init
- attributes
- closure_end_indentation
- closure_spacing
+- collection_alignment
- conditional_returns_on_newline
+- contains_over_filter_count
+- contains_over_filter_is_empty
- contains_over_first_not_nil
+- contains_over_range_nil_comparison
- convenience_type
+- empty_collection_literal
- empty_count
- empty_string
- empty_xctest_method
@@ -16,12 +22,19 @@ opt_in_rules:
- fatal_error_message
- file_header
- file_name
+- file_name_no_space
- file_types_order
- first_where
+- flatmap_over_map_reduce
- function_default_parameter_at_end
+- identical_operands
+- implicit_return
- implicitly_unwrapped_optional
-- is_disjoint
+- indentation_width
- joined_default_parameter
+- last_where
+- legacy_multiple
+- legacy_random
- let_var_whitespace
- literal_expression_end_indentation
- lower_acl_than_parent
@@ -29,52 +42,55 @@ opt_in_rules:
- modifier_order
- multiline_arguments
- multiline_arguments_brackets
-- multiline_function_chains
- multiline_literal_brackets
- multiline_parameters
- multiline_parameters_brackets
-- nimble_operator
+- nslocalizedstring_key
- number_separator
- object_literal
- operator_usage_whitespace
+- optional_enum_case_matching
- overridden_super_call
- override_in_extension
- pattern_matching_keywords
+- prefer_self_type_over_type_of_self
- private_action
- private_outlet
- prohibited_super_call
-- quick_discouraged_call
-- quick_discouraged_focused_test
-- quick_discouraged_pending_test
+- reduce_into
- redundant_nil_coalescing
- redundant_type_annotation
- single_test_class
- sorted_first_last
- sorted_imports
+- static_operator
+- strong_iboutlet
- switch_case_on_newline
+- toggle_bool
- trailing_closure
- type_contents_order
- unavailable_function
- unneeded_parentheses_in_closure_argument
- untyped_error_in_catch
+- unused_declaration
+- unused_import
- vertical_parameter_alignment_on_call
- vertical_whitespace_between_cases
- vertical_whitespace_closing_braces
- vertical_whitespace_opening_braces
+- xct_specific_matcher
- yoda_condition
-disabled_rules:
-- force_cast
-- todo
-- type_name
-
included:
-- Frameworks
+- Sources
- Tests
excluded:
- Tests/LinuxMain.swift
+disabled_rules:
+ - todo
+
# Rule Configurations
conditional_returns_on_newline:
if_only: true
@@ -85,41 +101,28 @@ explicit_type_interface:
- local
file_header:
- required_pattern: |
- \/\/
- \/\/ Created by [^\(\)\d\n]+ on \S{6,10}\.
- \/\/ Copyright © \d{4} Flinesoft\. All rights reserved\.
- \/\/
+ required_pattern: \/\/ Copyright © \d{4} Flinesoft\. All rights reserved\.
file_name:
- suffix_pattern: "Extensions?|\\+.*"
-
-file_types_order:
- order:
- - supporting_type
- - main_type
- - extension
+ suffix_pattern: "Ext"
identifier_name:
+ max_length: 60
excluded:
- id
+ - db
+ - to
line_length: 160
-type_contents_order:
- order:
- - case
- - [type_alias, associated_type]
- - subtype
- - type_property
- - instance_property
- - ib_outlet
- - initializer
- - type_method
- - view_life_cycle_method
- - ib_action
- - other_method
- - subscript
+nesting:
+ type_level: 3
+
+trailing_comma:
+ mandatory_comma: true
+
+trailing_whitespace:
+ ignores_comments: false
# Custom Rules
custom_rules:
@@ -141,15 +144,9 @@ custom_rules:
name: "Class Name Suffix View Controller"
message: "All `ViewController` subclasses should end on `ViewController`."
severity: warning
- closing_brace_whitespace:
- included: ".*.swift"
- regex: '(?:\n| {2,})\}\)? *\n *[^ \n\})\]s#"]'
- name: "Closing Brace Whitespace"
- message: "Empty line required after closing curly braces if code with same indentation follows."
- severity: warning
closure_params_parantheses:
included: ".*.swift"
- regex: '\{\s*\([^):]+\)\s*in'
+ regex: '\{\s*\((?!self)[^):]+\)\s*in'
name: "Unnecessary Closure Params Parantheses"
message: "Don't use parantheses around non-typed parameters in a closure."
severity: warning
@@ -173,9 +170,9 @@ custom_rules:
severity: warning
controller_class_name_suffix:
included: ".*.swift"
- regex: 'class +\w+(?\w+) *= *!\k(?=\s)'
- name: "Toggle Bool"
- message: "Use `toggle()` instead of toggling manually."
+ regex: '\/\/ TODO: [^\n]{0,14}\n|\/\/ TODO: \[\S{1,12}\]|\/\/ TODO: [^\[]|\/\/ TODO: \[.{13}[^\]]|\/\/ TODO: \[[^a-z]{2}|\/\/ TODO: \[.{2}[^_]|\/\/ TODO: \[.{7}[^-]|\/\/ TODO: \[.{10}[^-]'
+ name: "Todo Date"
+ message: "All TODOs should have a format with creator credentials & date of their creation documented like this: `// TODO: [cg_YYYY-MM-DD] `."
severity: warning
- too_much_indentation:
+ todo_uppercase:
included: ".*.swift"
- regex: '\n {0}[^\s\/][^\n]*[^,|&]\n+ {5,}\S|\n {4}[^\s\/][^\n]*[^,|&]\n+ {9,}\S|\n {8}[^\s\/][^\n]*[^,|&]\n+ {13,}\S|\n {12}[^\s\/][^\n]*[^,|&]\n+ {17,}\S|\n {16}[^\s\/][^\n]*[^,|&]\n+ {21,}\S|\n {20}[^\s\/][^\n]*[^,|&]\n+ {25,}\S'
- name: "Too Much Indentation"
- message: "Don't indent code by more than 4 whitespaces."
+ regex: '\/\/ ?tODO|\/\/ ?ToDO|\/\/ ?TOdO|\/\/ ?TODo|\/\/ ?todo|\/\/ ?Todo|\/\/ ?ToDo|\/\/ ?toDo'
+ name: "Todo Uppercase"
+ message: "All TODOs should be all-uppercased like this: `// TODO: [cg_YYYY-MM-DD] `."
severity: warning
- too_much_unindentation:
+ todo_whitespacing:
included: ".*.swift"
- regex: ' {28}[^\s\.](.|[^\n]*[^\)][^\ ][^\}])\n+ {0,23}[^\s\/]| {24}[^\s\.](.|[^\n]*[^\)][^\ ][^\}])\n+ {0,19}[^\s\/]| {20}[^\s\.](.|[^\n]*[^\)][^\ ][^\}])\n+ {0,15}[^\s\/]| {16}[^\s\.](.|[^\n]*[^\)][^\ ][^\}])\n+ {0,11}[^\s\/]| {12}[^\s\.](.|[^\n]*[^\)][^\ ][^\}])\n+ {0,7}[^\s\/]| {8}[^\s\.](.|[^\n]*[^\)][^\ ][^\}])\n+ {0,3}[^\s\/]'
- name: "Too Much Unindentation"
- message: "Don't unindent code by more than 4 whitespaces."
+ regex: '\/\/TODO|\/\/ TODO\s|\/\/ TODO:[^ ]|\/\/ TODO: |\/\/ TODO: \[[^\s]{0,10}\][^ ]'
+ name: "Todo Whitespace"
+ message: "All TODOs should exactly start like this (mind the whitespacing): `// TODO: [cg_YYYY-MM-DD] `."
severity: warning
tuple_index:
included: ".*.swift"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 308283c..5abd583 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,21 @@
# Changelog
All notable changes to this project will be documented in this file.
-The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
+The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
+
+
+Formatting Rules for Entries
+Each entry should use the following format:
+
+```markdown
+- Summary of what was changed in a single line using past tense & followed by two whitespaces.
+ Issue: [#0](https://github.com/Flinesoft/HandySwift/issues/0) | PR: [#0](https://github.com/Flinesoft/HandySwift/pull/0) | Author: [Cihat Gündüz](https://github.com/Jeehut)
+```
+
+Note that at the end of the summary line, you need to add two whitespaces (` `) for correct rendering on GitHub.
+
+If needed, pluralize to `Tasks`, `PRs` or `Authors` and list multiple entries separated by `, `. Also, remove entries not needed in the second line.
+
## [Unreleased]
### Added
@@ -17,6 +31,16 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
### Security
- None.
+## [3.2.0] - 2020-03-27
+### Added
+- New `DivisibleArithmetic` protocol which easily extends `average()` to Collections of `Double`, `Float` and `CGFloat`.
+ Issue: [#36](https://github.com/Flinesoft/HandySwift/issues/36) | PR: [#38](https://github.com/Flinesoft/HandySwift/pull/38) | Author: [David Knothe](https://github.com/knothed)
+- Make most of the API `@inlinable` for increased real-time performance.
+ Issue: [#40](https://github.com/Flinesoft/HandySwift/issues/40) | PR: [#43](https://github.com/Flinesoft/HandySwift/pull/43) | Author: [David Knothe](https://github.com/knothed)
+### Changed
+- Allow `Int.init?(randomBelow:)` to use an arbitrary RandomNumberGenerator (instead of just the system one).
+ PR: [#44](https://github.com/Flinesoft/HandySwift/pull/44) | Author: [David Knothe](https://github.com/knothed)
+
## [3.1.0] - 2019-09-01
### Added
- New `Comparable.clamped(to:)` and `Comparable.clamp(to:)` interfaces for any `Comparable`, e. g. `Int`.
@@ -26,15 +50,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
- New `Withable` protocol to init/copy objects and set properties in a convenient way on a single line.
### Changed
- Upgraded to Swift 5 & Xcode 10.2.
-### Deprecated
-- None.
### Removed
- Remove `ExpressibleByStringLiteral` conformance of `Regex` type to only allow initialization via `init(_:options:) throws` interface.
-### Fixed
-- None.
-### Security
-- None.
-
## [2.8.0] - 2019-02-11
### Added
@@ -44,14 +61,6 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
- New `fullRange` and `fullNSRange` computed properties on `String`
### Changed
- Made some APIs available in wider contexts (like `sample` in `RandomAccessCollection` instead of `Array`)
-### Deprecated
-- None.
-### Removed
-- None.
-### Fixed
-- None.
-### Security
-- None.
## [2.7.0] - 2018-09-27
### Added
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
deleted file mode 100644
index 376d626..0000000
--- a/CONTRIBUTING.md
+++ /dev/null
@@ -1,31 +0,0 @@
-# Contributing
-
-Bug reports and pull requests are welcome on GitHub at https://github.com/Flinesoft/HandySwift. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
-
-## Getting Started
-
-This section will tell you how you can get started contributing to HandySwift.
-
-### Prerequisites
-
-Before you start developing, please make sure you have the following tools installed on your machine:
-
-- Xcode 10.0+
-- [SwiftLint](https://github.com/realm/SwiftLint)
-- [ProjLint](https://github.com/JamitLabs/ProjLint)
-- [Beak](https://github.com/yonaskolb/Beak)
-- [Sourcery](https://github.com/krzysztofzablocki/Sourcery)
-
-### Useful Commands
-
-To **update the Linux tests** (required after adding/renaming/removing test methods):
-
-```
-beak run generateLinuxMain
-```
-
-This will make sure the Linux CI can also find and run all the tests.
-
-### Commit Messages
-
-Please also try to follow the same syntax and semantic in your **commit messages** (see rationale [here](http://chris.beams.io/posts/git-commit/)).
diff --git a/HandySwift.podspec b/HandySwift.podspec
index 3f67fa3..2105cee 100644
--- a/HandySwift.podspec
+++ b/HandySwift.podspec
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "HandySwift"
- s.version = "3.1.0"
+ s.version = "3.2.0"
s.summary = "Handy Swift features that didn't make it into the Swift standard library"
s.description = <<-DESC
@@ -14,7 +14,7 @@ Pod::Spec.new do |s|
s.license = { :type => "MIT", :file => "LICENSE" }
s.author = { "Cihat Gündüz" => "cocoapods@cihatguenduez.de" }
- s.social_media_url = "https://twitter.com/Dschee"
+ s.social_media_url = "https://twitter.com/Jeehut"
s.ios.deployment_target = "8.0"
s.osx.deployment_target = "10.10"
@@ -23,6 +23,6 @@ Pod::Spec.new do |s|
s.source = { :git => "https://github.com/Flinesoft/HandySwift.git", :tag => "#{s.version}" }
s.source_files = "Sources/HandySwift/**/*.swift"
s.framework = "Foundation"
- s.swift_version = "5.0"
+ s.swift_version = "5.1"
end
diff --git a/HandySwift.xcodeproj/project.pbxproj b/HandySwift.xcodeproj/project.pbxproj
index 4388538..35d8862 100644
--- a/HandySwift.xcodeproj/project.pbxproj
+++ b/HandySwift.xcodeproj/project.pbxproj
@@ -7,20 +7,29 @@
objects = {
/* Begin PBXBuildFile section */
- 3F95C8D220F22A3C0045AFD0 /* CollectionExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F95C8D120F22A3C0045AFD0 /* CollectionExtension.swift */; };
- 3F95C8D520F22DEE0045AFD0 /* CollectionExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F95C8D320F22DC60045AFD0 /* CollectionExtensionTests.swift */; };
- 3F95C8D620F22DEF0045AFD0 /* CollectionExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F95C8D320F22DC60045AFD0 /* CollectionExtensionTests.swift */; };
- 3F95C8D720F22DEF0045AFD0 /* CollectionExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F95C8D320F22DC60045AFD0 /* CollectionExtensionTests.swift */; };
- 8218E4D62211D193007AAAF3 /* NSRangeExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8218E4D52211D193007AAAF3 /* NSRangeExtension.swift */; };
- 8218E4D72211D193007AAAF3 /* NSRangeExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8218E4D52211D193007AAAF3 /* NSRangeExtension.swift */; };
- 8218E4D82211D193007AAAF3 /* NSRangeExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8218E4D52211D193007AAAF3 /* NSRangeExtension.swift */; };
- 8218E4DA2211D270007AAAF3 /* NSRangeExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8218E4D92211D270007AAAF3 /* NSRangeExtensionTests.swift */; };
- 8218E4DB2211D270007AAAF3 /* NSRangeExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8218E4D92211D270007AAAF3 /* NSRangeExtensionTests.swift */; };
- 8218E4DC2211D270007AAAF3 /* NSRangeExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8218E4D92211D270007AAAF3 /* NSRangeExtensionTests.swift */; };
+ 2E18B292242DECCA000C7776 /* NSObjectExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E18B291242DECCA000C7776 /* NSObjectExt.swift */; };
+ 2E18B293242DECCA000C7776 /* NSObjectExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E18B291242DECCA000C7776 /* NSObjectExt.swift */; };
+ 2E18B294242DECCA000C7776 /* NSObjectExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E18B291242DECCA000C7776 /* NSObjectExt.swift */; };
+ 2E18B296242DF436000C7776 /* NSObjectExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E18B295242DF436000C7776 /* NSObjectExtTests.swift */; };
+ 2E18B297242DF436000C7776 /* NSObjectExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E18B295242DF436000C7776 /* NSObjectExtTests.swift */; };
+ 2E18B298242DF436000C7776 /* NSObjectExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E18B295242DF436000C7776 /* NSObjectExtTests.swift */; };
+ 3F95C8D220F22A3C0045AFD0 /* CollectionExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F95C8D120F22A3C0045AFD0 /* CollectionExt.swift */; };
+ 3F95C8D520F22DEE0045AFD0 /* CollectionExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F95C8D320F22DC60045AFD0 /* CollectionExtTests.swift */; };
+ 3F95C8D620F22DEF0045AFD0 /* CollectionExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F95C8D320F22DC60045AFD0 /* CollectionExtTests.swift */; };
+ 3F95C8D720F22DEF0045AFD0 /* CollectionExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F95C8D320F22DC60045AFD0 /* CollectionExtTests.swift */; };
+ 63651F90231BFF2000E022DA /* DivisibleArithmetic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63651F8F231BFF2000E022DA /* DivisibleArithmetic.swift */; };
+ 63651F91231BFF2000E022DA /* DivisibleArithmetic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63651F8F231BFF2000E022DA /* DivisibleArithmetic.swift */; };
+ 63651F92231BFF2800E022DA /* DivisibleArithmetic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63651F8F231BFF2000E022DA /* DivisibleArithmetic.swift */; };
+ 8218E4D62211D193007AAAF3 /* NSRangeExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8218E4D52211D193007AAAF3 /* NSRangeExt.swift */; };
+ 8218E4D72211D193007AAAF3 /* NSRangeExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8218E4D52211D193007AAAF3 /* NSRangeExt.swift */; };
+ 8218E4D82211D193007AAAF3 /* NSRangeExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8218E4D52211D193007AAAF3 /* NSRangeExt.swift */; };
+ 8218E4DA2211D270007AAAF3 /* NSRangeExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8218E4D92211D270007AAAF3 /* NSRangeExtTests.swift */; };
+ 8218E4DB2211D270007AAAF3 /* NSRangeExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8218E4D92211D270007AAAF3 /* NSRangeExtTests.swift */; };
+ 8218E4DC2211D270007AAAF3 /* NSRangeExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8218E4D92211D270007AAAF3 /* NSRangeExtTests.swift */; };
823B2B351C24AAB7007B3CDD /* HandySwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 823B2B341C24AAB7007B3CDD /* HandySwift.h */; settings = {ATTRIBUTES = (Public, ); }; };
823B2B3C1C24AAB7007B3CDD /* HandySwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 823B2B311C24AAB6007B3CDD /* HandySwift.framework */; };
- 823B2B4D1C24ABA4007B3CDD /* IntExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 823B2B4C1C24ABA4007B3CDD /* IntExtension.swift */; };
- 823B2B501C24AC00007B3CDD /* IntExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 823B2B4F1C24AC00007B3CDD /* IntExtensionTests.swift */; };
+ 823B2B4D1C24ABA4007B3CDD /* IntExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 823B2B4C1C24ABA4007B3CDD /* IntExt.swift */; };
+ 823B2B501C24AC00007B3CDD /* IntExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 823B2B4F1C24AC00007B3CDD /* IntExtTests.swift */; };
8251AA2022786D460022B277 /* Withable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8251AA1F22786D460022B277 /* Withable.swift */; };
8251AA2122786D460022B277 /* Withable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8251AA1F22786D460022B277 /* Withable.swift */; };
8251AA2222786D460022B277 /* Withable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8251AA1F22786D460022B277 /* Withable.swift */; };
@@ -34,57 +43,57 @@
825EFE001C33357000558497 /* HandySwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 823B2B341C24AAB7007B3CDD /* HandySwift.h */; settings = {ATTRIBUTES = (Public, ); }; };
825EFE011C33357200558497 /* HandySwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 823B2B341C24AAB7007B3CDD /* HandySwift.h */; settings = {ATTRIBUTES = (Public, ); }; };
825EFE021C33358400558497 /* SortedArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8258E4551C2E0C140031CBFF /* SortedArray.swift */; };
- 825EFE031C33358400558497 /* IntExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 823B2B4C1C24ABA4007B3CDD /* IntExtension.swift */; };
- 825EFE051C33358400558497 /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAE2911C2ED1A200F934A7 /* StringExtension.swift */; };
- 825EFE061C33358400558497 /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAE2951C2EE64900F934A7 /* ArrayExtension.swift */; };
+ 825EFE031C33358400558497 /* IntExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 823B2B4C1C24ABA4007B3CDD /* IntExt.swift */; };
+ 825EFE051C33358400558497 /* StringExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAE2911C2ED1A200F934A7 /* StringExt.swift */; };
+ 825EFE061C33358400558497 /* ArrayExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAE2951C2EE64900F934A7 /* ArrayExt.swift */; };
825EFE081C33358500558497 /* SortedArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8258E4551C2E0C140031CBFF /* SortedArray.swift */; };
- 825EFE091C33358500558497 /* IntExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 823B2B4C1C24ABA4007B3CDD /* IntExtension.swift */; };
- 825EFE0B1C33358500558497 /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAE2911C2ED1A200F934A7 /* StringExtension.swift */; };
- 825EFE0C1C33358500558497 /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAE2951C2EE64900F934A7 /* ArrayExtension.swift */; };
+ 825EFE091C33358500558497 /* IntExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 823B2B4C1C24ABA4007B3CDD /* IntExt.swift */; };
+ 825EFE0B1C33358500558497 /* StringExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAE2911C2ED1A200F934A7 /* StringExt.swift */; };
+ 825EFE0C1C33358500558497 /* ArrayExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAE2951C2EE64900F934A7 /* ArrayExt.swift */; };
825EFE0E1C3335A400558497 /* SortedArrayTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8258E4581C2E1ACE0031CBFF /* SortedArrayTests.swift */; };
- 825EFE0F1C3335A400558497 /* IntExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 823B2B4F1C24AC00007B3CDD /* IntExtensionTests.swift */; };
- 825EFE111C3335A400558497 /* StringExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAE2931C2ED5E000F934A7 /* StringExtensionTests.swift */; };
- 825EFE121C3335A400558497 /* ArrayExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAE2971C2EE95200F934A7 /* ArrayExtensionTests.swift */; };
+ 825EFE0F1C3335A400558497 /* IntExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 823B2B4F1C24AC00007B3CDD /* IntExtTests.swift */; };
+ 825EFE111C3335A400558497 /* StringExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAE2931C2ED5E000F934A7 /* StringExtTests.swift */; };
+ 825EFE121C3335A400558497 /* ArrayExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAE2971C2EE95200F934A7 /* ArrayExtTests.swift */; };
825EFE141C3335A500558497 /* SortedArrayTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8258E4581C2E1ACE0031CBFF /* SortedArrayTests.swift */; };
- 825EFE151C3335A500558497 /* IntExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 823B2B4F1C24AC00007B3CDD /* IntExtensionTests.swift */; };
- 825EFE171C3335A500558497 /* StringExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAE2931C2ED5E000F934A7 /* StringExtensionTests.swift */; };
- 825EFE181C3335A500558497 /* ArrayExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAE2971C2EE95200F934A7 /* ArrayExtensionTests.swift */; };
+ 825EFE151C3335A500558497 /* IntExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 823B2B4F1C24AC00007B3CDD /* IntExtTests.swift */; };
+ 825EFE171C3335A500558497 /* StringExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAE2931C2ED5E000F934A7 /* StringExtTests.swift */; };
+ 825EFE181C3335A500558497 /* ArrayExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAE2971C2EE95200F934A7 /* ArrayExtTests.swift */; };
826F69AC1C3895A300B2CC6B /* FrequencyTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 826F69AB1C3895A300B2CC6B /* FrequencyTable.swift */; };
826F69AD1C3895A300B2CC6B /* FrequencyTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 826F69AB1C3895A300B2CC6B /* FrequencyTable.swift */; };
826F69AE1C3895A300B2CC6B /* FrequencyTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 826F69AB1C3895A300B2CC6B /* FrequencyTable.swift */; };
826F69B01C389DB800B2CC6B /* FrequencyTableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 826F69AF1C389DB800B2CC6B /* FrequencyTableTests.swift */; };
826F69B11C389DB800B2CC6B /* FrequencyTableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 826F69AF1C389DB800B2CC6B /* FrequencyTableTests.swift */; };
826F69B21C389DB800B2CC6B /* FrequencyTableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 826F69AF1C389DB800B2CC6B /* FrequencyTableTests.swift */; };
- 827599641E520FB800787F99 /* DispatchTimeIntervalExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 827599631E520FB800787F99 /* DispatchTimeIntervalExtensionTests.swift */; };
- 827599651E520FB800787F99 /* DispatchTimeIntervalExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 827599631E520FB800787F99 /* DispatchTimeIntervalExtensionTests.swift */; };
- 827599661E520FB800787F99 /* DispatchTimeIntervalExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 827599631E520FB800787F99 /* DispatchTimeIntervalExtensionTests.swift */; };
- 8280D7DC1C4A6EC9001172EF /* DictionaryExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8280D7DB1C4A6EC9001172EF /* DictionaryExtension.swift */; };
- 8280D7DD1C4A6EC9001172EF /* DictionaryExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8280D7DB1C4A6EC9001172EF /* DictionaryExtension.swift */; };
- 8280D7DE1C4A6EC9001172EF /* DictionaryExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8280D7DB1C4A6EC9001172EF /* DictionaryExtension.swift */; };
- 8280D7E01C4A6FF3001172EF /* DictionaryExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8280D7DF1C4A6FF3001172EF /* DictionaryExtensionTests.swift */; };
- 8280D7E11C4A6FF3001172EF /* DictionaryExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8280D7DF1C4A6FF3001172EF /* DictionaryExtensionTests.swift */; };
- 8280D7E21C4A6FF3001172EF /* DictionaryExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8280D7DF1C4A6FF3001172EF /* DictionaryExtensionTests.swift */; };
+ 827599641E520FB800787F99 /* DispatchTimeIntervalExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 827599631E520FB800787F99 /* DispatchTimeIntervalExtTests.swift */; };
+ 827599651E520FB800787F99 /* DispatchTimeIntervalExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 827599631E520FB800787F99 /* DispatchTimeIntervalExtTests.swift */; };
+ 827599661E520FB800787F99 /* DispatchTimeIntervalExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 827599631E520FB800787F99 /* DispatchTimeIntervalExtTests.swift */; };
+ 8280D7DC1C4A6EC9001172EF /* DictionaryExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8280D7DB1C4A6EC9001172EF /* DictionaryExt.swift */; };
+ 8280D7DD1C4A6EC9001172EF /* DictionaryExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8280D7DB1C4A6EC9001172EF /* DictionaryExt.swift */; };
+ 8280D7DE1C4A6EC9001172EF /* DictionaryExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8280D7DB1C4A6EC9001172EF /* DictionaryExt.swift */; };
+ 8280D7E01C4A6FF3001172EF /* DictionaryExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8280D7DF1C4A6FF3001172EF /* DictionaryExtTests.swift */; };
+ 8280D7E11C4A6FF3001172EF /* DictionaryExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8280D7DF1C4A6FF3001172EF /* DictionaryExtTests.swift */; };
+ 8280D7E21C4A6FF3001172EF /* DictionaryExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8280D7DF1C4A6FF3001172EF /* DictionaryExtTests.swift */; };
82812A9B1D06877B00CD5B6C /* Globals.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82812A9A1D06877B00CD5B6C /* Globals.swift */; };
82812A9C1D06877B00CD5B6C /* Globals.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82812A9A1D06877B00CD5B6C /* Globals.swift */; };
82812A9D1D06877B00CD5B6C /* Globals.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82812A9A1D06877B00CD5B6C /* Globals.swift */; };
82812A9F1D06926800CD5B6C /* GlobalsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82812A9E1D06926800CD5B6C /* GlobalsTests.swift */; };
82812AA01D06926800CD5B6C /* GlobalsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82812A9E1D06926800CD5B6C /* GlobalsTests.swift */; };
82812AA11D06926800CD5B6C /* GlobalsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82812A9E1D06926800CD5B6C /* GlobalsTests.swift */; };
- 82CAE2921C2ED1A200F934A7 /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAE2911C2ED1A200F934A7 /* StringExtension.swift */; };
- 82CAE2941C2ED5E000F934A7 /* StringExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAE2931C2ED5E000F934A7 /* StringExtensionTests.swift */; };
- 82CAE2961C2EE64900F934A7 /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAE2951C2EE64900F934A7 /* ArrayExtension.swift */; };
- 82CAE2981C2EE95200F934A7 /* ArrayExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAE2971C2EE95200F934A7 /* ArrayExtensionTests.swift */; };
- 82E21E8E211AF9960061EB1B /* CollectionExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F95C8D120F22A3C0045AFD0 /* CollectionExtension.swift */; };
- 82E21E8F211AF9970061EB1B /* CollectionExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F95C8D120F22A3C0045AFD0 /* CollectionExtension.swift */; };
- A11830D31E589F6700CBE087 /* TimeIntervalExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A11830D21E589F6700CBE087 /* TimeIntervalExtension.swift */; };
- A11830D41E589F6700CBE087 /* TimeIntervalExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A11830D21E589F6700CBE087 /* TimeIntervalExtension.swift */; };
- A11830D51E589F6700CBE087 /* TimeIntervalExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A11830D21E589F6700CBE087 /* TimeIntervalExtension.swift */; };
- A11830D71E58A11D00CBE087 /* TimeIntervalExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A11830D61E58A11D00CBE087 /* TimeIntervalExtensionTests.swift */; };
- A11830D81E58A11D00CBE087 /* TimeIntervalExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A11830D61E58A11D00CBE087 /* TimeIntervalExtensionTests.swift */; };
- A11830D91E58A11D00CBE087 /* TimeIntervalExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A11830D61E58A11D00CBE087 /* TimeIntervalExtensionTests.swift */; };
- A1F221641E3CC05100419B06 /* DispatchTimeIntervalExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1F221631E3CC05100419B06 /* DispatchTimeIntervalExtension.swift */; };
- A1F221651E3CC05100419B06 /* DispatchTimeIntervalExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1F221631E3CC05100419B06 /* DispatchTimeIntervalExtension.swift */; };
- A1F221661E3CC05100419B06 /* DispatchTimeIntervalExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1F221631E3CC05100419B06 /* DispatchTimeIntervalExtension.swift */; };
+ 82CAE2921C2ED1A200F934A7 /* StringExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAE2911C2ED1A200F934A7 /* StringExt.swift */; };
+ 82CAE2941C2ED5E000F934A7 /* StringExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAE2931C2ED5E000F934A7 /* StringExtTests.swift */; };
+ 82CAE2961C2EE64900F934A7 /* ArrayExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAE2951C2EE64900F934A7 /* ArrayExt.swift */; };
+ 82CAE2981C2EE95200F934A7 /* ArrayExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAE2971C2EE95200F934A7 /* ArrayExtTests.swift */; };
+ 82E21E8E211AF9960061EB1B /* CollectionExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F95C8D120F22A3C0045AFD0 /* CollectionExt.swift */; };
+ 82E21E8F211AF9970061EB1B /* CollectionExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F95C8D120F22A3C0045AFD0 /* CollectionExt.swift */; };
+ A11830D31E589F6700CBE087 /* TimeIntervalExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = A11830D21E589F6700CBE087 /* TimeIntervalExt.swift */; };
+ A11830D41E589F6700CBE087 /* TimeIntervalExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = A11830D21E589F6700CBE087 /* TimeIntervalExt.swift */; };
+ A11830D51E589F6700CBE087 /* TimeIntervalExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = A11830D21E589F6700CBE087 /* TimeIntervalExt.swift */; };
+ A11830D71E58A11D00CBE087 /* TimeIntervalExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A11830D61E58A11D00CBE087 /* TimeIntervalExtTests.swift */; };
+ A11830D81E58A11D00CBE087 /* TimeIntervalExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A11830D61E58A11D00CBE087 /* TimeIntervalExtTests.swift */; };
+ A11830D91E58A11D00CBE087 /* TimeIntervalExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A11830D61E58A11D00CBE087 /* TimeIntervalExtTests.swift */; };
+ A1F221641E3CC05100419B06 /* DispatchTimeIntervalExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1F221631E3CC05100419B06 /* DispatchTimeIntervalExt.swift */; };
+ A1F221651E3CC05100419B06 /* DispatchTimeIntervalExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1F221631E3CC05100419B06 /* DispatchTimeIntervalExt.swift */; };
+ A1F221661E3CC05100419B06 /* DispatchTimeIntervalExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1F221631E3CC05100419B06 /* DispatchTimeIntervalExt.swift */; };
C5C89B9420B0A0C10048B07C /* Weak.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5C89B9320B0A0C10048B07C /* Weak.swift */; };
C5CFB6AC20B0A70300830511 /* Unowned.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5CFB6AB20B0A70300830511 /* Unowned.swift */; };
C5CFB6AD20B0A70300830511 /* Unowned.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5CFB6AB20B0A70300830511 /* Unowned.swift */; };
@@ -97,12 +106,12 @@
CC4AE0CF2087D8A7009931F6 /* RegexTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC4AE0CD2087D895009931F6 /* RegexTests.swift */; };
CC4AE0D02087D8A8009931F6 /* RegexTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC4AE0CD2087D895009931F6 /* RegexTests.swift */; };
CC4AE0D12087D8A9009931F6 /* RegexTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC4AE0CD2087D895009931F6 /* RegexTests.swift */; };
- CC66E047228199A0007ABF61 /* ComparableExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC66E046228199A0007ABF61 /* ComparableExtension.swift */; };
- CC66E048228199DE007ABF61 /* ComparableExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC66E046228199A0007ABF61 /* ComparableExtension.swift */; };
- CC66E049228199DF007ABF61 /* ComparableExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC66E046228199A0007ABF61 /* ComparableExtension.swift */; };
- CC66E12522819FFF007ABF61 /* ComparableExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC66E12322819FCF007ABF61 /* ComparableExtensionTests.swift */; };
- CC66E1262281A000007ABF61 /* ComparableExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC66E12322819FCF007ABF61 /* ComparableExtensionTests.swift */; };
- CC66E1272281A000007ABF61 /* ComparableExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC66E12322819FCF007ABF61 /* ComparableExtensionTests.swift */; };
+ CC66E047228199A0007ABF61 /* ComparableExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC66E046228199A0007ABF61 /* ComparableExt.swift */; };
+ CC66E048228199DE007ABF61 /* ComparableExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC66E046228199A0007ABF61 /* ComparableExt.swift */; };
+ CC66E049228199DF007ABF61 /* ComparableExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC66E046228199A0007ABF61 /* ComparableExt.swift */; };
+ CC66E12522819FFF007ABF61 /* ComparableExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC66E12322819FCF007ABF61 /* ComparableExtTests.swift */; };
+ CC66E1262281A000007ABF61 /* ComparableExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC66E12322819FCF007ABF61 /* ComparableExtTests.swift */; };
+ CC66E1272281A000007ABF61 /* ComparableExtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC66E12322819FCF007ABF61 /* ComparableExtTests.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -130,11 +139,14 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
+ 2E18B291242DECCA000C7776 /* NSObjectExt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSObjectExt.swift; sourceTree = ""; };
+ 2E18B295242DF436000C7776 /* NSObjectExtTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSObjectExtTests.swift; sourceTree = ""; };
2E4189DB231B971E00C65B81 /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitignore; sourceTree = ""; };
- 3F95C8D120F22A3C0045AFD0 /* CollectionExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionExtension.swift; sourceTree = ""; };
- 3F95C8D320F22DC60045AFD0 /* CollectionExtensionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionExtensionTests.swift; sourceTree = ""; };
- 8218E4D52211D193007AAAF3 /* NSRangeExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSRangeExtension.swift; sourceTree = ""; };
- 8218E4D92211D270007AAAF3 /* NSRangeExtensionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSRangeExtensionTests.swift; sourceTree = ""; };
+ 3F95C8D120F22A3C0045AFD0 /* CollectionExt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionExt.swift; sourceTree = ""; };
+ 3F95C8D320F22DC60045AFD0 /* CollectionExtTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionExtTests.swift; sourceTree = ""; };
+ 63651F8F231BFF2000E022DA /* DivisibleArithmetic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DivisibleArithmetic.swift; sourceTree = ""; };
+ 8218E4D52211D193007AAAF3 /* NSRangeExt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSRangeExt.swift; sourceTree = ""; };
+ 8218E4D92211D270007AAAF3 /* NSRangeExtTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSRangeExtTests.swift; sourceTree = ""; };
8218E4DD2211D7D3007AAAF3 /* CODE_OF_CONDUCT.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CODE_OF_CONDUCT.md; sourceTree = ""; };
8218E4DE2211D7D3007AAAF3 /* CHANGELOG.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CHANGELOG.md; sourceTree = ""; };
8218E4DF2211D7D3007AAAF3 /* CONTRIBUTING.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CONTRIBUTING.md; sourceTree = ""; };
@@ -143,8 +155,8 @@
823B2B361C24AAB7007B3CDD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
823B2B3B1C24AAB7007B3CDD /* HandySwift iOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "HandySwift iOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
823B2B421C24AAB7007B3CDD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
- 823B2B4C1C24ABA4007B3CDD /* IntExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntExtension.swift; sourceTree = ""; };
- 823B2B4F1C24AC00007B3CDD /* IntExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntExtensionTests.swift; sourceTree = ""; };
+ 823B2B4C1C24ABA4007B3CDD /* IntExt.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntExt.swift; sourceTree = ""; };
+ 823B2B4F1C24AC00007B3CDD /* IntExtTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntExtTests.swift; sourceTree = ""; };
8251AA1F22786D460022B277 /* Withable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Withable.swift; sourceTree = ""; };
8251AA24227875C00022B277 /* WithableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WithableTests.swift; sourceTree = ""; };
8258E4551C2E0C140031CBFF /* SortedArray.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SortedArray.swift; sourceTree = ""; };
@@ -155,30 +167,30 @@
825EFDF21C33351300558497 /* HandySwift tvOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "HandySwift tvOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
826F69AB1C3895A300B2CC6B /* FrequencyTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FrequencyTable.swift; sourceTree = ""; };
826F69AF1C389DB800B2CC6B /* FrequencyTableTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FrequencyTableTests.swift; sourceTree = ""; };
- 827599631E520FB800787F99 /* DispatchTimeIntervalExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DispatchTimeIntervalExtensionTests.swift; sourceTree = ""; };
- 8280D7DB1C4A6EC9001172EF /* DictionaryExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DictionaryExtension.swift; sourceTree = ""; };
- 8280D7DF1C4A6FF3001172EF /* DictionaryExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DictionaryExtensionTests.swift; sourceTree = ""; };
+ 827599631E520FB800787F99 /* DispatchTimeIntervalExtTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DispatchTimeIntervalExtTests.swift; sourceTree = ""; };
+ 8280D7DB1C4A6EC9001172EF /* DictionaryExt.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DictionaryExt.swift; sourceTree = ""; };
+ 8280D7DF1C4A6FF3001172EF /* DictionaryExtTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DictionaryExtTests.swift; sourceTree = ""; };
82812A9A1D06877B00CD5B6C /* Globals.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Globals.swift; sourceTree = ""; };
82812A9E1D06926800CD5B6C /* GlobalsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GlobalsTests.swift; sourceTree = ""; };
- 82CAE2911C2ED1A200F934A7 /* StringExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExtension.swift; sourceTree = ""; };
- 82CAE2931C2ED5E000F934A7 /* StringExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExtensionTests.swift; sourceTree = ""; };
- 82CAE2951C2EE64900F934A7 /* ArrayExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayExtension.swift; sourceTree = ""; };
- 82CAE2971C2EE95200F934A7 /* ArrayExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayExtensionTests.swift; sourceTree = ""; };
+ 82CAE2911C2ED1A200F934A7 /* StringExt.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExt.swift; sourceTree = ""; };
+ 82CAE2931C2ED5E000F934A7 /* StringExtTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExtTests.swift; sourceTree = ""; };
+ 82CAE2951C2EE64900F934A7 /* ArrayExt.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayExt.swift; sourceTree = ""; };
+ 82CAE2971C2EE95200F934A7 /* ArrayExtTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayExtTests.swift; sourceTree = ""; };
82EB7875215B96E20042E0FD /* beak.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = beak.swift; sourceTree = ""; };
82EB7876215B98530042E0FD /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = ""; };
82F22E551C26434900E784A2 /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; };
- A11830D21E589F6700CBE087 /* TimeIntervalExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimeIntervalExtension.swift; sourceTree = ""; };
- A11830D61E58A11D00CBE087 /* TimeIntervalExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimeIntervalExtensionTests.swift; sourceTree = ""; };
+ A11830D21E589F6700CBE087 /* TimeIntervalExt.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimeIntervalExt.swift; sourceTree = ""; };
+ A11830D61E58A11D00CBE087 /* TimeIntervalExtTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimeIntervalExtTests.swift; sourceTree = ""; };
A15C62221EE734F100A7CA38 /* .swiftlint.yml */ = {isa = PBXFileReference; lastKnownFileType = text; path = .swiftlint.yml; sourceTree = ""; };
A16B85EB1D8EA9A200B39055 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; };
A19DD6921DE2B70F00C66584 /* HandySwift.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = HandySwift.podspec; sourceTree = ""; };
- A1F221631E3CC05100419B06 /* DispatchTimeIntervalExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DispatchTimeIntervalExtension.swift; sourceTree = ""; };
+ A1F221631E3CC05100419B06 /* DispatchTimeIntervalExt.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DispatchTimeIntervalExt.swift; sourceTree = ""; };
C5C89B9320B0A0C10048B07C /* Weak.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Weak.swift; sourceTree = ""; };
C5CFB6AB20B0A70300830511 /* Unowned.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Unowned.swift; sourceTree = ""; };
CC120CC1205FDB9300C37D7C /* Regex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Regex.swift; sourceTree = ""; };
CC4AE0CD2087D895009931F6 /* RegexTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegexTests.swift; sourceTree = ""; };
- CC66E046228199A0007ABF61 /* ComparableExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComparableExtension.swift; sourceTree = ""; };
- CC66E12322819FCF007ABF61 /* ComparableExtensionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComparableExtensionTests.swift; sourceTree = ""; };
+ CC66E046228199A0007ABF61 /* ComparableExt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComparableExt.swift; sourceTree = ""; };
+ CC66E12322819FCF007ABF61 /* ComparableExtTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComparableExtTests.swift; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -233,8 +245,8 @@
8203930320F3A4DF0074974F /* HandySwift */ = {
isa = PBXGroup;
children = (
- 82812A9A1D06877B00CD5B6C /* Globals.swift */,
823B2B4B1C24AB7F007B3CDD /* Extensions */,
+ 82812A9A1D06877B00CD5B6C /* Globals.swift */,
8251AA1E22786CF90022B277 /* Protocols */,
8258E4541C2E0BAF0031CBFF /* Structs */,
);
@@ -278,15 +290,16 @@
823B2B4B1C24AB7F007B3CDD /* Extensions */ = {
isa = PBXGroup;
children = (
- 82CAE2951C2EE64900F934A7 /* ArrayExtension.swift */,
- 3F95C8D120F22A3C0045AFD0 /* CollectionExtension.swift */,
- CC66E046228199A0007ABF61 /* ComparableExtension.swift */,
- 8280D7DB1C4A6EC9001172EF /* DictionaryExtension.swift */,
- A1F221631E3CC05100419B06 /* DispatchTimeIntervalExtension.swift */,
- 823B2B4C1C24ABA4007B3CDD /* IntExtension.swift */,
- 8218E4D52211D193007AAAF3 /* NSRangeExtension.swift */,
- 82CAE2911C2ED1A200F934A7 /* StringExtension.swift */,
- A11830D21E589F6700CBE087 /* TimeIntervalExtension.swift */,
+ 82CAE2951C2EE64900F934A7 /* ArrayExt.swift */,
+ 3F95C8D120F22A3C0045AFD0 /* CollectionExt.swift */,
+ CC66E046228199A0007ABF61 /* ComparableExt.swift */,
+ 8280D7DB1C4A6EC9001172EF /* DictionaryExt.swift */,
+ A1F221631E3CC05100419B06 /* DispatchTimeIntervalExt.swift */,
+ 823B2B4C1C24ABA4007B3CDD /* IntExt.swift */,
+ 2E18B291242DECCA000C7776 /* NSObjectExt.swift */,
+ 8218E4D52211D193007AAAF3 /* NSRangeExt.swift */,
+ 82CAE2911C2ED1A200F934A7 /* StringExt.swift */,
+ A11830D21E589F6700CBE087 /* TimeIntervalExt.swift */,
);
path = Extensions;
sourceTree = "";
@@ -294,15 +307,16 @@
823B2B4E1C24ABD8007B3CDD /* Extensions */ = {
isa = PBXGroup;
children = (
- 82CAE2971C2EE95200F934A7 /* ArrayExtensionTests.swift */,
- 3F95C8D320F22DC60045AFD0 /* CollectionExtensionTests.swift */,
- CC66E12322819FCF007ABF61 /* ComparableExtensionTests.swift */,
- 8280D7DF1C4A6FF3001172EF /* DictionaryExtensionTests.swift */,
- 827599631E520FB800787F99 /* DispatchTimeIntervalExtensionTests.swift */,
- 823B2B4F1C24AC00007B3CDD /* IntExtensionTests.swift */,
- 8218E4D92211D270007AAAF3 /* NSRangeExtensionTests.swift */,
- 82CAE2931C2ED5E000F934A7 /* StringExtensionTests.swift */,
- A11830D61E58A11D00CBE087 /* TimeIntervalExtensionTests.swift */,
+ 82CAE2971C2EE95200F934A7 /* ArrayExtTests.swift */,
+ 3F95C8D320F22DC60045AFD0 /* CollectionExtTests.swift */,
+ CC66E12322819FCF007ABF61 /* ComparableExtTests.swift */,
+ 8280D7DF1C4A6FF3001172EF /* DictionaryExtTests.swift */,
+ 827599631E520FB800787F99 /* DispatchTimeIntervalExtTests.swift */,
+ 823B2B4F1C24AC00007B3CDD /* IntExtTests.swift */,
+ 2E18B295242DF436000C7776 /* NSObjectExtTests.swift */,
+ 8218E4D92211D270007AAAF3 /* NSRangeExtTests.swift */,
+ 82CAE2931C2ED5E000F934A7 /* StringExtTests.swift */,
+ A11830D61E58A11D00CBE087 /* TimeIntervalExtTests.swift */,
);
path = Extensions;
sourceTree = "";
@@ -310,6 +324,7 @@
8251AA1E22786CF90022B277 /* Protocols */ = {
isa = PBXGroup;
children = (
+ 63651F8F231BFF2000E022DA /* DivisibleArithmetic.swift */,
8251AA1F22786D460022B277 /* Withable.swift */,
);
path = Protocols;
@@ -431,11 +446,11 @@
isa = PBXNativeTarget;
buildConfigurationList = 823B2B451C24AAB7007B3CDD /* Build configuration list for PBXNativeTarget "HandySwift iOS" */;
buildPhases = (
+ 82F967F41C67A68A0003F12A /* SwiftLint */,
823B2B2C1C24AAB6007B3CDD /* Sources */,
823B2B2D1C24AAB6007B3CDD /* Frameworks */,
823B2B2E1C24AAB6007B3CDD /* Headers */,
823B2B2F1C24AAB6007B3CDD /* Resources */,
- 82F967F41C67A68A0003F12A /* SwiftLint */,
);
buildRules = (
);
@@ -453,6 +468,7 @@
823B2B371C24AAB7007B3CDD /* Sources */,
823B2B381C24AAB7007B3CDD /* Frameworks */,
823B2B391C24AAB7007B3CDD /* Resources */,
+ 2E78897B242B4A8100143348 /* Update LinuxMain.swift */,
);
buildRules = (
);
@@ -468,11 +484,11 @@
isa = PBXNativeTarget;
buildConfigurationList = 825EFDDB1C3333B000558497 /* Build configuration list for PBXNativeTarget "HandySwift macOS" */;
buildPhases = (
+ 82F967F51C67A69A0003F12A /* SwiftLint */,
825EFDC51C3333B000558497 /* Sources */,
825EFDC61C3333B000558497 /* Frameworks */,
825EFDC71C3333B000558497 /* Headers */,
825EFDC81C3333B000558497 /* Resources */,
- 82F967F51C67A69A0003F12A /* SwiftLint */,
);
buildRules = (
);
@@ -490,6 +506,7 @@
825EFDCF1C3333B000558497 /* Sources */,
825EFDD01C3333B000558497 /* Frameworks */,
825EFDD11C3333B000558497 /* Resources */,
+ 2E78897C242B4B3D00143348 /* Update LinuxMain.swift */,
);
buildRules = (
);
@@ -505,11 +522,11 @@
isa = PBXNativeTarget;
buildConfigurationList = 825EFDFA1C33351300558497 /* Build configuration list for PBXNativeTarget "HandySwift tvOS" */;
buildPhases = (
+ 82F967F61C67A6A80003F12A /* SwiftLint */,
825EFDE41C33351200558497 /* Sources */,
825EFDE51C33351200558497 /* Frameworks */,
825EFDE61C33351200558497 /* Headers */,
825EFDE71C33351200558497 /* Resources */,
- 82F967F61C67A6A80003F12A /* SwiftLint */,
);
buildRules = (
);
@@ -527,6 +544,7 @@
825EFDEE1C33351300558497 /* Sources */,
825EFDEF1C33351300558497 /* Frameworks */,
825EFDF01C33351300558497 /* Resources */,
+ 2E78897D242B4B4100143348 /* Update LinuxMain.swift */,
);
buildRules = (
);
@@ -545,7 +563,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0720;
- LastUpgradeCheck = 1020;
+ LastUpgradeCheck = 1120;
ORGANIZATIONNAME = Flinesoft;
TargetAttributes = {
823B2B301C24AAB6007B3CDD = {
@@ -643,6 +661,60 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
+ 2E78897B242B4A8100143348 /* Update LinuxMain.swift */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ );
+ name = "Update LinuxMain.swift";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "if [ \"${CONFIGURATION}\" = \"Debug\" ]; then\n if which swiftlint > /dev/null; then\n sourcery --sources Tests --templates .sourcery/LinuxMain.stencil --output .sourcery --force-parse generated\n mv .sourcery/LinuxMain.generated.swift Tests/LinuxMain.swift\n else\n echo \"warning: Sourcery not installed, download it from https://github.com/krzysztofzablocki/Sourcery\"\n fi\nfi\n";
+ };
+ 2E78897C242B4B3D00143348 /* Update LinuxMain.swift */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ );
+ name = "Update LinuxMain.swift";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "if [ \"${CONFIGURATION}\" = \"Debug\" ]; then\n if which swiftlint > /dev/null; then\n sourcery --sources Tests --templates .sourcery/LinuxMain.stencil --output .sourcery --force-parse generated\n mv .sourcery/LinuxMain.generated.swift Tests/LinuxMain.swift\n else\n echo \"warning: Sourcery not installed, download it from https://github.com/krzysztofzablocki/Sourcery\"\n fi\nfi\n";
+ };
+ 2E78897D242B4B4100143348 /* Update LinuxMain.swift */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ );
+ name = "Update LinuxMain.swift";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "if [ \"${CONFIGURATION}\" = \"Debug\" ]; then\n if which swiftlint > /dev/null; then\n sourcery --sources Tests --templates .sourcery/LinuxMain.stencil --output .sourcery --force-parse generated\n mv .sourcery/LinuxMain.generated.swift Tests/LinuxMain.swift\n else\n echo \"warning: Sourcery not installed, download it from https://github.com/krzysztofzablocki/Sourcery\"\n fi\nfi\n";
+ };
82F967F41C67A68A0003F12A /* SwiftLint */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -695,19 +767,21 @@
8258E4561C2E0C140031CBFF /* SortedArray.swift in Sources */,
CC120CC2205FDB9300C37D7C /* Regex.swift in Sources */,
826F69AC1C3895A300B2CC6B /* FrequencyTable.swift in Sources */,
- A1F221641E3CC05100419B06 /* DispatchTimeIntervalExtension.swift in Sources */,
- 8218E4D62211D193007AAAF3 /* NSRangeExtension.swift in Sources */,
- 3F95C8D220F22A3C0045AFD0 /* CollectionExtension.swift in Sources */,
- 823B2B4D1C24ABA4007B3CDD /* IntExtension.swift in Sources */,
- CC66E047228199A0007ABF61 /* ComparableExtension.swift in Sources */,
+ 2E18B292242DECCA000C7776 /* NSObjectExt.swift in Sources */,
+ A1F221641E3CC05100419B06 /* DispatchTimeIntervalExt.swift in Sources */,
+ 8218E4D62211D193007AAAF3 /* NSRangeExt.swift in Sources */,
+ 3F95C8D220F22A3C0045AFD0 /* CollectionExt.swift in Sources */,
+ 823B2B4D1C24ABA4007B3CDD /* IntExt.swift in Sources */,
+ CC66E047228199A0007ABF61 /* ComparableExt.swift in Sources */,
C5C89B9420B0A0C10048B07C /* Weak.swift in Sources */,
8251AA2022786D460022B277 /* Withable.swift in Sources */,
- 82CAE2921C2ED1A200F934A7 /* StringExtension.swift in Sources */,
- 82CAE2961C2EE64900F934A7 /* ArrayExtension.swift in Sources */,
+ 82CAE2921C2ED1A200F934A7 /* StringExt.swift in Sources */,
+ 82CAE2961C2EE64900F934A7 /* ArrayExt.swift in Sources */,
C5CFB6AC20B0A70300830511 /* Unowned.swift in Sources */,
82812A9B1D06877B00CD5B6C /* Globals.swift in Sources */,
- 8280D7DC1C4A6EC9001172EF /* DictionaryExtension.swift in Sources */,
- A11830D31E589F6700CBE087 /* TimeIntervalExtension.swift in Sources */,
+ 63651F90231BFF2000E022DA /* DivisibleArithmetic.swift in Sources */,
+ 8280D7DC1C4A6EC9001172EF /* DictionaryExt.swift in Sources */,
+ A11830D31E589F6700CBE087 /* TimeIntervalExt.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -716,18 +790,19 @@
buildActionMask = 2147483647;
files = (
826F69B01C389DB800B2CC6B /* FrequencyTableTests.swift in Sources */,
- 827599641E520FB800787F99 /* DispatchTimeIntervalExtensionTests.swift in Sources */,
+ 827599641E520FB800787F99 /* DispatchTimeIntervalExtTests.swift in Sources */,
8258E4591C2E1ACE0031CBFF /* SortedArrayTests.swift in Sources */,
- A11830D71E58A11D00CBE087 /* TimeIntervalExtensionTests.swift in Sources */,
+ A11830D71E58A11D00CBE087 /* TimeIntervalExtTests.swift in Sources */,
8251AA25227875C00022B277 /* WithableTests.swift in Sources */,
- 823B2B501C24AC00007B3CDD /* IntExtensionTests.swift in Sources */,
- 82CAE2941C2ED5E000F934A7 /* StringExtensionTests.swift in Sources */,
- 82CAE2981C2EE95200F934A7 /* ArrayExtensionTests.swift in Sources */,
+ 823B2B501C24AC00007B3CDD /* IntExtTests.swift in Sources */,
+ 82CAE2941C2ED5E000F934A7 /* StringExtTests.swift in Sources */,
+ 82CAE2981C2EE95200F934A7 /* ArrayExtTests.swift in Sources */,
82812A9F1D06926800CD5B6C /* GlobalsTests.swift in Sources */,
- 8218E4DA2211D270007AAAF3 /* NSRangeExtensionTests.swift in Sources */,
- 8280D7E01C4A6FF3001172EF /* DictionaryExtensionTests.swift in Sources */,
- CC66E12522819FFF007ABF61 /* ComparableExtensionTests.swift in Sources */,
- 3F95C8D520F22DEE0045AFD0 /* CollectionExtensionTests.swift in Sources */,
+ 8218E4DA2211D270007AAAF3 /* NSRangeExtTests.swift in Sources */,
+ 8280D7E01C4A6FF3001172EF /* DictionaryExtTests.swift in Sources */,
+ CC66E12522819FFF007ABF61 /* ComparableExtTests.swift in Sources */,
+ 3F95C8D520F22DEE0045AFD0 /* CollectionExtTests.swift in Sources */,
+ 2E18B296242DF436000C7776 /* NSObjectExtTests.swift in Sources */,
CC4AE0CF2087D8A7009931F6 /* RegexTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -736,22 +811,24 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 825EFE061C33358400558497 /* ArrayExtension.swift in Sources */,
+ 825EFE061C33358400558497 /* ArrayExt.swift in Sources */,
CC120CC3205FDC4C00C37D7C /* Regex.swift in Sources */,
C5CFB6AD20B0A70300830511 /* Unowned.swift in Sources */,
+ 2E18B293242DECCA000C7776 /* NSObjectExt.swift in Sources */,
826F69AD1C3895A300B2CC6B /* FrequencyTable.swift in Sources */,
- 8218E4D72211D193007AAAF3 /* NSRangeExtension.swift in Sources */,
- 825EFE051C33358400558497 /* StringExtension.swift in Sources */,
- 82E21E8E211AF9960061EB1B /* CollectionExtension.swift in Sources */,
- CC66E048228199DE007ABF61 /* ComparableExtension.swift in Sources */,
+ 8218E4D72211D193007AAAF3 /* NSRangeExt.swift in Sources */,
+ 825EFE051C33358400558497 /* StringExt.swift in Sources */,
+ 82E21E8E211AF9960061EB1B /* CollectionExt.swift in Sources */,
+ CC66E048228199DE007ABF61 /* ComparableExt.swift in Sources */,
C5CFB6AF20B0A78F00830511 /* Weak.swift in Sources */,
8251AA2122786D460022B277 /* Withable.swift in Sources */,
- A1F221651E3CC05100419B06 /* DispatchTimeIntervalExtension.swift in Sources */,
+ A1F221651E3CC05100419B06 /* DispatchTimeIntervalExt.swift in Sources */,
825EFE021C33358400558497 /* SortedArray.swift in Sources */,
- 825EFE031C33358400558497 /* IntExtension.swift in Sources */,
+ 825EFE031C33358400558497 /* IntExt.swift in Sources */,
82812A9C1D06877B00CD5B6C /* Globals.swift in Sources */,
- 8280D7DD1C4A6EC9001172EF /* DictionaryExtension.swift in Sources */,
- A11830D41E589F6700CBE087 /* TimeIntervalExtension.swift in Sources */,
+ 63651F91231BFF2000E022DA /* DivisibleArithmetic.swift in Sources */,
+ 8280D7DD1C4A6EC9001172EF /* DictionaryExt.swift in Sources */,
+ A11830D41E589F6700CBE087 /* TimeIntervalExt.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -760,18 +837,19 @@
buildActionMask = 2147483647;
files = (
826F69B11C389DB800B2CC6B /* FrequencyTableTests.swift in Sources */,
- 827599651E520FB800787F99 /* DispatchTimeIntervalExtensionTests.swift in Sources */,
- 825EFE111C3335A400558497 /* StringExtensionTests.swift in Sources */,
- A11830D81E58A11D00CBE087 /* TimeIntervalExtensionTests.swift in Sources */,
+ 827599651E520FB800787F99 /* DispatchTimeIntervalExtTests.swift in Sources */,
+ 825EFE111C3335A400558497 /* StringExtTests.swift in Sources */,
+ A11830D81E58A11D00CBE087 /* TimeIntervalExtTests.swift in Sources */,
8251AA26227875C00022B277 /* WithableTests.swift in Sources */,
825EFE0E1C3335A400558497 /* SortedArrayTests.swift in Sources */,
- 825EFE121C3335A400558497 /* ArrayExtensionTests.swift in Sources */,
- 825EFE0F1C3335A400558497 /* IntExtensionTests.swift in Sources */,
+ 825EFE121C3335A400558497 /* ArrayExtTests.swift in Sources */,
+ 825EFE0F1C3335A400558497 /* IntExtTests.swift in Sources */,
82812AA01D06926800CD5B6C /* GlobalsTests.swift in Sources */,
- 8218E4DB2211D270007AAAF3 /* NSRangeExtensionTests.swift in Sources */,
- 8280D7E11C4A6FF3001172EF /* DictionaryExtensionTests.swift in Sources */,
- CC66E1262281A000007ABF61 /* ComparableExtensionTests.swift in Sources */,
- 3F95C8D620F22DEF0045AFD0 /* CollectionExtensionTests.swift in Sources */,
+ 8218E4DB2211D270007AAAF3 /* NSRangeExtTests.swift in Sources */,
+ 8280D7E11C4A6FF3001172EF /* DictionaryExtTests.swift in Sources */,
+ CC66E1262281A000007ABF61 /* ComparableExtTests.swift in Sources */,
+ 3F95C8D620F22DEF0045AFD0 /* CollectionExtTests.swift in Sources */,
+ 2E18B297242DF436000C7776 /* NSObjectExtTests.swift in Sources */,
CC4AE0D02087D8A8009931F6 /* RegexTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -780,22 +858,24 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 825EFE0C1C33358500558497 /* ArrayExtension.swift in Sources */,
+ 825EFE0C1C33358500558497 /* ArrayExt.swift in Sources */,
CC120CC4205FDC4D00C37D7C /* Regex.swift in Sources */,
C5CFB6AE20B0A70300830511 /* Unowned.swift in Sources */,
+ 2E18B294242DECCA000C7776 /* NSObjectExt.swift in Sources */,
826F69AE1C3895A300B2CC6B /* FrequencyTable.swift in Sources */,
- 8218E4D82211D193007AAAF3 /* NSRangeExtension.swift in Sources */,
- 825EFE0B1C33358500558497 /* StringExtension.swift in Sources */,
- 82E21E8F211AF9970061EB1B /* CollectionExtension.swift in Sources */,
- CC66E049228199DF007ABF61 /* ComparableExtension.swift in Sources */,
+ 8218E4D82211D193007AAAF3 /* NSRangeExt.swift in Sources */,
+ 825EFE0B1C33358500558497 /* StringExt.swift in Sources */,
+ 82E21E8F211AF9970061EB1B /* CollectionExt.swift in Sources */,
+ CC66E049228199DF007ABF61 /* ComparableExt.swift in Sources */,
C5CFB6B020B0A79000830511 /* Weak.swift in Sources */,
8251AA2222786D460022B277 /* Withable.swift in Sources */,
- A1F221661E3CC05100419B06 /* DispatchTimeIntervalExtension.swift in Sources */,
+ A1F221661E3CC05100419B06 /* DispatchTimeIntervalExt.swift in Sources */,
825EFE081C33358500558497 /* SortedArray.swift in Sources */,
- 825EFE091C33358500558497 /* IntExtension.swift in Sources */,
+ 825EFE091C33358500558497 /* IntExt.swift in Sources */,
82812A9D1D06877B00CD5B6C /* Globals.swift in Sources */,
- 8280D7DE1C4A6EC9001172EF /* DictionaryExtension.swift in Sources */,
- A11830D51E589F6700CBE087 /* TimeIntervalExtension.swift in Sources */,
+ 63651F92231BFF2800E022DA /* DivisibleArithmetic.swift in Sources */,
+ 8280D7DE1C4A6EC9001172EF /* DictionaryExt.swift in Sources */,
+ A11830D51E589F6700CBE087 /* TimeIntervalExt.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -804,18 +884,19 @@
buildActionMask = 2147483647;
files = (
826F69B21C389DB800B2CC6B /* FrequencyTableTests.swift in Sources */,
- 827599661E520FB800787F99 /* DispatchTimeIntervalExtensionTests.swift in Sources */,
- 825EFE171C3335A500558497 /* StringExtensionTests.swift in Sources */,
- A11830D91E58A11D00CBE087 /* TimeIntervalExtensionTests.swift in Sources */,
+ 827599661E520FB800787F99 /* DispatchTimeIntervalExtTests.swift in Sources */,
+ 825EFE171C3335A500558497 /* StringExtTests.swift in Sources */,
+ A11830D91E58A11D00CBE087 /* TimeIntervalExtTests.swift in Sources */,
8251AA27227875C00022B277 /* WithableTests.swift in Sources */,
825EFE141C3335A500558497 /* SortedArrayTests.swift in Sources */,
- 825EFE181C3335A500558497 /* ArrayExtensionTests.swift in Sources */,
- 825EFE151C3335A500558497 /* IntExtensionTests.swift in Sources */,
+ 825EFE181C3335A500558497 /* ArrayExtTests.swift in Sources */,
+ 825EFE151C3335A500558497 /* IntExtTests.swift in Sources */,
82812AA11D06926800CD5B6C /* GlobalsTests.swift in Sources */,
- 8218E4DC2211D270007AAAF3 /* NSRangeExtensionTests.swift in Sources */,
- 8280D7E21C4A6FF3001172EF /* DictionaryExtensionTests.swift in Sources */,
- CC66E1272281A000007ABF61 /* ComparableExtensionTests.swift in Sources */,
- 3F95C8D720F22DEF0045AFD0 /* CollectionExtensionTests.swift in Sources */,
+ 8218E4DC2211D270007AAAF3 /* NSRangeExtTests.swift in Sources */,
+ 8280D7E21C4A6FF3001172EF /* DictionaryExtTests.swift in Sources */,
+ CC66E1272281A000007ABF61 /* ComparableExtTests.swift in Sources */,
+ 3F95C8D720F22DEF0045AFD0 /* CollectionExtTests.swift in Sources */,
+ 2E18B298242DF436000C7776 /* NSObjectExtTests.swift in Sources */,
CC4AE0D12087D8A9009931F6 /* RegexTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -964,7 +1045,7 @@
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
- CODE_SIGN_IDENTITY = "iPhone Developer";
+ CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -986,7 +1067,7 @@
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
- CODE_SIGN_IDENTITY = "iPhone Developer";
+ CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -1005,6 +1086,7 @@
823B2B491C24AAB7007B3CDD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
INFOPLIST_FILE = Tests/SupportingFiles/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.flinesoft.HandySwift-iOS-Tests";
@@ -1016,6 +1098,7 @@
823B2B4A1C24AAB7007B3CDD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
INFOPLIST_FILE = Tests/SupportingFiles/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.flinesoft.HandySwift-iOS-Tests";
diff --git a/HandySwift.xcodeproj/xcshareddata/xcschemes/HandySwift iOS.xcscheme b/HandySwift.xcodeproj/xcshareddata/xcschemes/HandySwift iOS.xcscheme
index 34be75d..a69acc5 100644
--- a/HandySwift.xcodeproj/xcshareddata/xcschemes/HandySwift iOS.xcscheme
+++ b/HandySwift.xcodeproj/xcshareddata/xcschemes/HandySwift iOS.xcscheme
@@ -1,6 +1,6 @@
+
+
+
+
@@ -39,17 +48,6 @@
-
-
-
-
-
-
-
-
+
+
+
+
@@ -39,17 +48,6 @@
-
-
-
-
-
-
-
-
+
+
+
+
@@ -39,17 +48,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
Installation
• Usage
+ • Donation
• Issues
• Contributing
• License
@@ -45,7 +62,7 @@ If you like this, please also checkout [HandyUIKit](https://github.com/Flinesoft
## Installation
-Currently the recommended way of installing this library is via [Carthage](https://github.com/Carthage/Carthage) on macOS or [Swift Package Manager](https://github.com/apple/swift-package-manager) on Linux. [Cocoapods](https://github.com/CocoaPods/CocoaPods) might work, too, but is not tested.
+Currently the recommended way of installing this library is via [Swift Package Manager](https://github.com/apple/swift-package-manager). [Carthage](https://github.com/Carthage/Carthage) & [Cocoapods](https://github.com/CocoaPods/CocoaPods) are supported, too.
You can of course also just include this framework manually into your project by downloading it or by using git submodules.
@@ -552,7 +569,7 @@ NOTE: Only available for `Int` and `Double` collections.
```
### Withable
-Simple protocol to make constructing and modifying objects with multiple properties more pleasant (functional, chainable, point-free).
+Simple protocol to make constructing and modifying objects with multiple properties more pleasant (functional, chainable, point-free). Supported by all `NSObject` subclasses by default.
``` swift
struct Foo: Withable {
@@ -571,9 +588,16 @@ foo2.bar // => 7
```
+## Donation
+
+BartyCrouch was brought to you by [Cihat Gündüz](https://github.com/Jeehut) in his free time. If you want to thank me and support the development of this project, please **make a small donation on [PayPal](https://paypal.me/Dschee/5EUR)**. In case you also like my other [open source contributions](https://github.com/Flinesoft) and [articles](https://medium.com/@Jeehut), please consider motivating me by **becoming a sponsor on [GitHub](https://github.com/sponsors/Jeehut)** or a **patron on [Patreon](https://www.patreon.com/Jeehut)**.
+
+Thank you very much for any donation, it really helps out a lot! 💯
+
+
## Contributing
-See the file [CONTRIBUTING.md](https://github.com/Flinesoft/HandySwift/blob/stable/CONTRIBUTING.md).
+Contributions are welcome. Feel free to open an issue on GitHub with your ideas or implement an idea yourself and post a pull request. If you want to contribute code, please try to follow the same syntax and semantic in your **commit messages** (see rationale [here](http://chris.beams.io/posts/git-commit/)). Also, please make sure to add an entry to the `CHANGELOG.md` file which explains your change.
## License
diff --git a/Sources/HandySwift/Extensions/ArrayExtension.swift b/Sources/HandySwift/Extensions/ArrayExt.swift
similarity index 95%
rename from Sources/HandySwift/Extensions/ArrayExtension.swift
rename to Sources/HandySwift/Extensions/ArrayExt.swift
index cd71986..f915e1a 100644
--- a/Sources/HandySwift/Extensions/ArrayExtension.swift
+++ b/Sources/HandySwift/Extensions/ArrayExt.swift
@@ -13,6 +13,7 @@ extension Array {
/// - Parameters:
/// - other: Other array to combine the elements with.
/// - Returns: An array of tuples with the elements of both arrays combined.
+ @inlinable
public func combinations(with other: [T]) -> [Combination] {
var combinations = [(Element, T)]()
forEach { elem in other.forEach { otherElem in combinations.append((elem, otherElem)) } }
@@ -27,6 +28,7 @@ extension Array {
/// - Parameters:
/// - stable: Speifies if the sorting algorithm should be stable.
/// - areInIncreasingOrder: The closure to specify the order of the elements to be sorted by.
+ @inlinable
public mutating func sort(by areInIncreasingOrder: @escaping (Element, Element) -> Bool, stable: Bool) {
guard stable else { sort(by: areInIncreasingOrder); return }
stableMergeSort(by: areInIncreasingOrder)
@@ -39,6 +41,7 @@ extension Array {
/// - Parameters:
/// - stable: Speifies if the sorting algorithm should be stable.
/// - areInIncreasingOrder: The closure to specify the order of the elements to be sorted by.
+ @inlinable
public func sorted(by areInIncreasingOrder: @escaping (Element, Element) -> Bool, stable: Bool) -> [Element] {
guard stable else { return sorted(by: areInIncreasingOrder) }
@@ -49,6 +52,7 @@ extension Array {
}
/// Sorts the array in-place using a stable merge sort algorithm.
+ @inlinable
mutating func stableMergeSort(by areInIncreasingOrder: @escaping (Element, Element) -> Bool) {
var tmp = [Element]()
tmp.reserveCapacity(numericCast(count))
@@ -91,7 +95,7 @@ extension RandomAccessCollection where Index == Int {
/// Returns a random element from the `Array`.
///
/// - Returns: A random element from the array or `nil` if empty.
- public var sample: Element? {
+ @inlinable public var sample: Element? {
guard let randomIndex = Int(randomBelow: count) else { return nil }
return self[randomIndex]
}
@@ -101,6 +105,7 @@ extension RandomAccessCollection where Index == Int {
/// - Parameters:
/// - size: The number of random elements wanted.
/// - Returns: An array with the given number of random elements or `nil` if empty.
+ @inlinable
public func sample(size: Int) -> [Element]? {
guard !isEmpty else { return nil }
@@ -118,6 +123,7 @@ extension Array where Element: Comparable {
///
/// - Parameters:
/// - stable: Speifies if the sorting algorithm should be stable.
+ @inlinable
public mutating func sort(stable: Bool) {
sort(by: { lhs, rhs in lhs < rhs }, stable: stable)
}
@@ -128,7 +134,8 @@ extension Array where Element: Comparable {
///
/// - Parameters:
/// - stable: Speifies if the sorting algorithm should be stable.
+ @inlinable
public func sorted(stable: Bool) -> [Element] {
- return sorted(by: { lhs, rhs in lhs < rhs }, stable: stable)
+ sorted(by: { lhs, rhs in lhs < rhs }, stable: stable)
}
}
diff --git a/Sources/HandySwift/Extensions/CollectionExtension.swift b/Sources/HandySwift/Extensions/CollectionExt.swift
similarity index 57%
rename from Sources/HandySwift/Extensions/CollectionExtension.swift
rename to Sources/HandySwift/Extensions/CollectionExt.swift
index 4c33a27..e4eb719 100644
--- a/Sources/HandySwift/Extensions/CollectionExtension.swift
+++ b/Sources/HandySwift/Extensions/CollectionExt.swift
@@ -7,28 +7,32 @@ extension Collection {
///
/// - Parameters:
/// - try: The index of the element.
+ @inlinable
public subscript(try index: Index) -> Element? {
- return indices.contains(index) ? self[index] : nil
+ indices.contains(index) ? self[index] : nil
}
}
extension Sequence where Element: Numeric {
/// Returns the sum of all elements.
+ @inlinable
public func sum() -> Element {
- return reduce(0, +)
+ reduce(0, +)
}
}
-extension Collection where Element == Int {
- /// Returns the average of all elements as a Double value.
- public func average() -> Double {
- return reduce(0) { $0 + Double($1) } / Double(count)
+extension Collection where Element: DivisibleArithmetic {
+ /// Returns the average of all elements.
+ @inlinable
+ public func average() -> Element {
+ sum() / Element(count)
}
}
-extension Collection where Element == Double {
+extension Collection where Element == Int {
/// Returns the average of all elements as a Double value.
- public func average() -> Double {
- return reduce(0, +) / Double(count)
+ @inlinable
+ public func average() -> ReturnType {
+ ReturnType(sum()) / ReturnType(count)
}
}
diff --git a/Sources/HandySwift/Extensions/ComparableExtension.swift b/Sources/HandySwift/Extensions/ComparableExt.swift
similarity index 97%
rename from Sources/HandySwift/Extensions/ComparableExtension.swift
rename to Sources/HandySwift/Extensions/ComparableExt.swift
index 164351a..a71656f 100644
--- a/Sources/HandySwift/Extensions/ComparableExtension.swift
+++ b/Sources/HandySwift/Extensions/ComparableExt.swift
@@ -11,6 +11,7 @@ extension Comparable {
/// - `self`, if it is inside the given limits.
/// - `lowerBound` of the given limits, if `self` is smaller than it.
/// - `upperBound` of the given limits, if `self` is greater than it.
+ @inlinable
public func clamped(to limits: ClosedRange) -> Self {
if limits.lowerBound > self {
return limits.lowerBound
@@ -27,6 +28,7 @@ extension Comparable {
/// - Returns:
/// - `self`, if it is inside the given limits.
/// - `lowerBound` of the given limits, if `self` is smaller than it.
+ @inlinable
public func clamped(to limits: PartialRangeFrom) -> Self {
if limits.lowerBound > self {
return limits.lowerBound
@@ -41,6 +43,7 @@ extension Comparable {
/// - Returns:
/// - `self`, if it is inside the given limits.
/// - `upperBound` of the given limits, if `self` is greater than it.
+ @inlinable
public func clamped(to limits: PartialRangeThrough) -> Self {
if limits.upperBound < self {
return limits.upperBound
@@ -57,6 +60,7 @@ extension Comparable {
/// - `upperBound` of the given limits, if `self` is greater than it.
///
/// - Parameter limits: The closed range determining minimum & maxmimum value.
+ @inlinable
public mutating func clamp(to limits: ClosedRange) {
self = clamped(to: limits)
}
@@ -67,6 +71,7 @@ extension Comparable {
/// - `lowerBound` of the given limits, if `self` is smaller than it.
///
/// - Parameter limits: The partial range (from) determining the minimum value.
+ @inlinable
public mutating func clamp(to limits: PartialRangeFrom) {
self = clamped(to: limits)
}
@@ -77,6 +82,7 @@ extension Comparable {
/// - `upperBound` of the given limits, if `self` is greater than it.
///
/// - Parameter limits: The partial range (through) determining the maximum value.
+ @inlinable
public mutating func clamp(to limits: PartialRangeThrough) {
self = clamped(to: limits)
}
diff --git a/Sources/HandySwift/Extensions/DictionaryExtension.swift b/Sources/HandySwift/Extensions/DictionaryExt.swift
similarity index 97%
rename from Sources/HandySwift/Extensions/DictionaryExtension.swift
rename to Sources/HandySwift/Extensions/DictionaryExt.swift
index 6ac9565..0608f15 100644
--- a/Sources/HandySwift/Extensions/DictionaryExtension.swift
+++ b/Sources/HandySwift/Extensions/DictionaryExt.swift
@@ -8,6 +8,7 @@ extension Dictionary {
/// - Parameters:
/// - keys: The `Array` of keys.
/// - values: The `Array` of values.
+ @inlinable
public init?(keys: [Key], values: [Value]) {
guard keys.count == values.count else { return nil }
self.init()
@@ -18,6 +19,7 @@ extension Dictionary {
///
/// - Parameters:
/// - otherDictionary: The other `Dictionary` to merge into this `Dictionary`.
+ @inlinable
public mutating func merge(_ other: [Key: Value]) {
for (key, value) in other { self[key] = value }
}
@@ -28,6 +30,7 @@ extension Dictionary {
/// - Parameters:
/// - otherDictionary: The other `Dictionary` to merge into this `Dictionary`.
/// - Returns: The new Dictionary with merged keys and values from this and the other `Dictionary`.
+ @inlinable
public func merged(with other: [Key: Value]) -> [Key: Value] {
var newDict: [Key: Value] = [:]
[self, other].forEach { dict in for (key, value) in dict { newDict[key] = value } }
diff --git a/Sources/HandySwift/Extensions/DispatchTimeIntervalExtension.swift b/Sources/HandySwift/Extensions/DispatchTimeIntervalExt.swift
similarity index 100%
rename from Sources/HandySwift/Extensions/DispatchTimeIntervalExtension.swift
rename to Sources/HandySwift/Extensions/DispatchTimeIntervalExt.swift
diff --git a/Sources/HandySwift/Extensions/IntExtension.swift b/Sources/HandySwift/Extensions/IntExt.swift
similarity index 63%
rename from Sources/HandySwift/Extensions/IntExtension.swift
rename to Sources/HandySwift/Extensions/IntExt.swift
index 65fe6c5..7d74eb6 100644
--- a/Sources/HandySwift/Extensions/IntExtension.swift
+++ b/Sources/HandySwift/Extensions/IntExt.swift
@@ -12,10 +12,21 @@ extension Int {
self = .random(in: 0 ..< upperLimit)
}
+ /// Initializes a new `Int ` instance with a random value below a given `Int`.
+ ///
+ /// - Parameters:
+ /// - randomBelow: The upper bound value to create a random value with.
+ /// - generator: The `RandomNumberGenerator` source that should be used to generate random numbers.
+ public init?(randomBelow upperLimit: Int, using generator: inout Generator) {
+ guard upperLimit > 0 else { return nil }
+ self = .random(in: 0 ..< upperLimit, using: &generator)
+ }
+
/// Runs the code passed as a closure the specified number of times.
///
/// - Parameters:
/// - closure: The code to be run multiple times.
+ @inlinable
public func times(_ closure: () -> Void) {
guard self > 0 else { return }
for _ in 0 ..< self { closure() }
@@ -26,8 +37,9 @@ extension Int {
///
/// - Parameters:
/// - closure: The code to deliver a return value multiple times.
+ @inlinable
public func timesMake(_ closure: () -> ReturnType) -> [ReturnType] {
guard self > 0 else { return [] }
- return (0 ..< self).map { _ in return closure() }
+ return (0 ..< self).map { _ in closure() }
}
}
diff --git a/Sources/HandySwift/Extensions/NSObjectExt.swift b/Sources/HandySwift/Extensions/NSObjectExt.swift
new file mode 100644
index 0000000..f7ecf51
--- /dev/null
+++ b/Sources/HandySwift/Extensions/NSObjectExt.swift
@@ -0,0 +1,7 @@
+// Copyright © 2020 Flinesoft. All rights reserved.
+
+import Foundation
+
+#if !os(Linux)
+ extension NSObject: Withable {}
+#endif
diff --git a/Sources/HandySwift/Extensions/NSRangeExtension.swift b/Sources/HandySwift/Extensions/NSRangeExt.swift
similarity index 100%
rename from Sources/HandySwift/Extensions/NSRangeExtension.swift
rename to Sources/HandySwift/Extensions/NSRangeExt.swift
diff --git a/Sources/HandySwift/Extensions/StringExtension.swift b/Sources/HandySwift/Extensions/StringExt.swift
similarity index 88%
rename from Sources/HandySwift/Extensions/StringExtension.swift
rename to Sources/HandySwift/Extensions/StringExt.swift
index 8b81c3a..1aacb9a 100644
--- a/Sources/HandySwift/Extensions/StringExtension.swift
+++ b/Sources/HandySwift/Extensions/StringExt.swift
@@ -4,23 +4,23 @@ import Foundation
extension String {
/// - Returns: `true` if contains any cahracters other than whitespace or newline characters, else `no`.
- public var isBlank: Bool { return stripped().isEmpty }
+ public var isBlank: Bool { stripped().isEmpty }
/// Returns a random character from the String.
///
/// - Returns: A random character from the String or `nil` if empty.
public var sample: Character? {
- return isEmpty ? nil : self[index(startIndex, offsetBy: Int(randomBelow: count)!)]
+ isEmpty ? nil : self[index(startIndex, offsetBy: Int(randomBelow: count)!)]
}
/// Returns the range containing the full String.
public var fullRange: Range {
- return startIndex ..< endIndex
+ startIndex ..< endIndex
}
/// Returns the range as NSRange type for the full String.
public var fullNSRange: NSRange {
- return NSRange(fullRange, in: self)
+ NSRange(fullRange, in: self)
}
/// Create new instance with random numeric/alphabetic/alphanumeric String of given length.
@@ -49,13 +49,14 @@ extension String {
}
/// - Returns: The string stripped by whitespace and newline characters from beginning and end.
- public func stripped() -> String { return trimmingCharacters(in: .whitespacesAndNewlines) }
+ public func stripped() -> String { trimmingCharacters(in: .whitespacesAndNewlines) }
/// Returns a given number of random characters from the String.
///
/// - Parameters:
/// - size: The number of random characters wanted.
/// - Returns: A String with the given number of random characters or `nil` if empty.
+ @inlinable
public func sample(size: Int) -> String? {
guard !isEmpty else { return nil }
diff --git a/Sources/HandySwift/Extensions/TimeIntervalExtension.swift b/Sources/HandySwift/Extensions/TimeIntervalExt.swift
similarity index 55%
rename from Sources/HandySwift/Extensions/TimeIntervalExtension.swift
rename to Sources/HandySwift/Extensions/TimeIntervalExt.swift
index 229bd70..0bc14bf 100644
--- a/Sources/HandySwift/Extensions/TimeIntervalExtension.swift
+++ b/Sources/HandySwift/Extensions/TimeIntervalExt.swift
@@ -7,82 +7,89 @@ public typealias Timespan = TimeInterval
extension TimeInterval {
// MARK: - Computed Type Properties
- internal static var secondsPerDay: Double { return 24 * 60 * 60 }
- internal static var secondsPerHour: Double { return 60 * 60 }
- internal static var secondsPerMinute: Double { return 60 }
- internal static var millisecondsPerSecond: Double { return 1_000 }
- internal static var microsecondsPerSecond: Double { return 1_000 * 1_000 }
- internal static var nanosecondsPerSecond: Double { return 1_000 * 1_000 * 1_000 }
+ @usableFromInline internal static var secondsPerDay: Double { 24 * 60 * 60 }
+ @usableFromInline internal static var secondsPerHour: Double { 60 * 60 }
+ @usableFromInline internal static var secondsPerMinute: Double { 60 }
+ @usableFromInline internal static var millisecondsPerSecond: Double { 1_000 }
+ @usableFromInline internal static var microsecondsPerSecond: Double { 1_000 * 1_000 }
+ @usableFromInline internal static var nanosecondsPerSecond: Double { 1_000 * 1_000 * 1_000 }
// MARK: - Computed Instance Properties
/// - Returns: The `TimeInterval` in days.
- public var days: Double {
- return self / TimeInterval.secondsPerDay
+ @inlinable public var days: Double {
+ self / TimeInterval.secondsPerDay
}
/// - Returns: The `TimeInterval` in hours.
- public var hours: Double {
- return self / TimeInterval.secondsPerHour
+ @inlinable public var hours: Double {
+ self / TimeInterval.secondsPerHour
}
/// - Returns: The `TimeInterval` in minutes.
- public var minutes: Double {
- return self / TimeInterval.secondsPerMinute
+ @inlinable public var minutes: Double {
+ self / TimeInterval.secondsPerMinute
}
/// - Returns: The `TimeInterval` in seconds.
- public var seconds: Double {
- return self
+ @inlinable public var seconds: Double {
+ self
}
/// - Returns: The `TimeInterval` in milliseconds.
- public var milliseconds: Double {
- return self * TimeInterval.millisecondsPerSecond
+ @inlinable public var milliseconds: Double {
+ self * TimeInterval.millisecondsPerSecond
}
/// - Returns: The `TimeInterval` in microseconds.
- public var microseconds: Double {
- return self * TimeInterval.microsecondsPerSecond
+ @inlinable public var microseconds: Double {
+ self * TimeInterval.microsecondsPerSecond
}
/// - Returns: The `TimeInterval` in nanoseconds.
- public var nanoseconds: Double {
- return self * TimeInterval.nanosecondsPerSecond
+ @inlinable public var nanoseconds: Double {
+ self * TimeInterval.nanosecondsPerSecond
}
// MARK: - Type Methods
/// - Returns: The time in days using the `TimeInterval` type.
+ @inlinable
public static func days(_ value: Double) -> TimeInterval {
- return value * secondsPerDay
+ value * secondsPerDay
}
/// - Returns: The time in hours using the `TimeInterval` type.
+ @inlinable
public static func hours(_ value: Double) -> TimeInterval {
- return value * secondsPerHour
+ value * secondsPerHour
}
/// - Returns: The time in minutes using the `TimeInterval` type.
+ @inlinable
public static func minutes(_ value: Double) -> TimeInterval {
- return value * secondsPerMinute
+ value * secondsPerMinute
}
/// - Returns: The time in seconds using the `TimeInterval` type.
+ @inlinable
public static func seconds(_ value: Double) -> TimeInterval {
- return value
+ value
}
/// - Returns: The time in milliseconds using the `TimeInterval` type.
+ @inlinable
public static func milliseconds(_ value: Double) -> TimeInterval {
- return value / millisecondsPerSecond
+ value / millisecondsPerSecond
}
/// - Returns: The time in microseconds using the `TimeInterval` type.
+ @inlinable
public static func microseconds(_ value: Double) -> TimeInterval {
- return value / microsecondsPerSecond
+ value / microsecondsPerSecond
}
/// - Returns: The time in nanoseconds using the `TimeInterval` type.
+ @inlinable
public static func nanoseconds(_ value: Double) -> TimeInterval {
- return value / nanosecondsPerSecond
+ value / nanosecondsPerSecond
}
}
diff --git a/Sources/HandySwift/Protocols/DivisibleArithmetic.swift b/Sources/HandySwift/Protocols/DivisibleArithmetic.swift
new file mode 100644
index 0000000..5e54c6f
--- /dev/null
+++ b/Sources/HandySwift/Protocols/DivisibleArithmetic.swift
@@ -0,0 +1,16 @@
+// Copyright © 2019 Flinesoft. All rights reserved.
+
+/// A type which conforms to DivisibleArithmetic provides the basic arithmetic operations: additon, subtraction, multiplication and division.
+public protocol DivisibleArithmetic: Numeric {
+ init(_ value: Int)
+ static func / (lhs: Self, rhs: Self) -> Self
+}
+
+extension Double: DivisibleArithmetic {}
+extension Float: DivisibleArithmetic {}
+
+#if canImport(CoreGraphics)
+ import CoreGraphics
+
+ extension CGFloat: DivisibleArithmetic {}
+#endif
diff --git a/Sources/HandySwift/Protocols/Withable.swift b/Sources/HandySwift/Protocols/Withable.swift
index 89828ed..9530281 100644
--- a/Sources/HandySwift/Protocols/Withable.swift
+++ b/Sources/HandySwift/Protocols/Withable.swift
@@ -8,12 +8,14 @@ public protocol Withable {
extension Withable {
/// Construct a new instance, setting an arbitrary subset of properties.
+ @inlinable
public init(with config: (inout Self) -> Void) {
self.init()
config(&self)
}
/// Create a copy, overriding an arbitrary subset of properties.
+ @inlinable
public func with(_ config: (inout Self) -> Void) -> Self {
var copy = self
config(©)
diff --git a/Sources/HandySwift/Structs/FrequencyTable.swift b/Sources/HandySwift/Structs/FrequencyTable.swift
index cdee255..45cb90b 100644
--- a/Sources/HandySwift/Structs/FrequencyTable.swift
+++ b/Sources/HandySwift/Structs/FrequencyTable.swift
@@ -5,17 +5,18 @@ import Foundation
/// Data structure to retrieve random values with their frequency taken into account.
public struct FrequencyTable {
// MARK: - Sub Types
+ @usableFromInline
typealias Entry = (value: T, frequency: Int)
// MARK: - Stored Instance Properties
- private let valuesWithFrequencies: [Entry]
+ @usableFromInline internal let valuesWithFrequencies: [Entry]
/// Contains all values the amount of time of their frequencies.
- private let frequentValues: [T]
+ @usableFromInline internal let frequentValues: [T]
// MARK: - Computed Instance Properties
/// - Returns: A random value taking frequencies into account or nil if values empty.
- public var sample: T? { return frequentValues.sample }
+ @inlinable public var sample: T? { frequentValues.sample }
// MARK: - Initializers
/// Creates a new FrequencyTable instance with values and their frequencies provided.
@@ -23,10 +24,11 @@ public struct FrequencyTable {
/// - Parameters:
/// - values: An array full of values to be saved into the frequency table.
/// - frequencyClosure: The closure to specify the frequency for a specific value.
+ @inlinable
public init(values: [T], frequencyClosure: (T) -> Int) {
valuesWithFrequencies = values.map { ($0, frequencyClosure($0)) }
- frequentValues = valuesWithFrequencies.reduce([]) { memo, entry in
- return memo + Array(repeating: entry.value, count: entry.frequency)
+ frequentValues = valuesWithFrequencies.reduce(into: []) { memo, entry in
+ memo += Array(repeating: entry.value, count: entry.frequency)
}
}
@@ -37,6 +39,7 @@ public struct FrequencyTable {
/// - size: The size of the resulting array of random values.
///
/// - Returns: An array of random values or nil if values empty.
+ @inlinable
public func sample(size: Int) -> [T]? {
guard size > 0 && !frequentValues.isEmpty else { return nil }
return Array(0 ..< size).map { _ in sample! }
diff --git a/Sources/HandySwift/Structs/Regex.swift b/Sources/HandySwift/Structs/Regex.swift
index 234c5e7..c62d00a 100644
--- a/Sources/HandySwift/Structs/Regex.swift
+++ b/Sources/HandySwift/Structs/Regex.swift
@@ -6,7 +6,7 @@ import Foundation
/// `Regex` is a swifty regex engine built on top of the NSRegularExpression api.
public struct Regex {
// MARK: - Properties
- private let regularExpression: NSRegularExpression
+ @usableFromInline internal let regularExpression: NSRegularExpression
// MARK: - Initializers
/// Create a `Regex` based on a pattern string.
@@ -33,8 +33,9 @@ public struct Regex {
/// - parameter string: The string to test.
///
/// - returns: `true` if the regular expression matches, otherwise `false`.
+ @inlinable
public func matches(_ string: String) -> Bool {
- return firstMatch(in: string) != nil
+ firstMatch(in: string) != nil
}
/// If the regex matches `string`, returns a `Match` describing the
@@ -44,6 +45,7 @@ public struct Regex {
/// - parameter string: The string to match against.
///
/// - returns: An optional `Match` describing the first match, or `nil`.
+ @inlinable
public func firstMatch(in string: String) -> Match? {
let firstMatch = regularExpression
.firstMatch(in: string, options: [], range: NSRange(location: 0, length: string.utf16.count))
@@ -58,6 +60,7 @@ public struct Regex {
/// - parameter string: The string to match against.
///
/// - returns: An array of `Match` describing every match in `string`.
+ @inlinable
public func matches(in string: String) -> [Match] {
let matches = regularExpression
.matches(in: string, options: [], range: NSRange(location: 0, length: string.utf16.count))
@@ -82,6 +85,7 @@ public struct Regex {
/// - count: The maximum count of matches to replace, beginning with the first match.
///
/// - returns: A string with all matches of `regex` replaced by `template`.
+ @inlinable
public func replacingMatches(in input: String, with template: String, count: Int? = nil) -> String {
var output = input
let matches = self.matches(in: input)
@@ -99,7 +103,7 @@ public struct Regex {
extension Regex: CustomStringConvertible {
/// Returns a string describing the regex using its pattern string.
public var description: String {
- return "Regex<\"\(regularExpression.pattern)\">"
+ "Regex<\"\(regularExpression.pattern)\">"
}
}
@@ -109,7 +113,7 @@ extension Regex: Equatable {
/// Two `Regex` are considered equal, if both the pattern string and the options
/// passed on initialization are equal.
public static func == (lhs: Regex, rhs: Regex) -> Bool {
- return lhs.regularExpression.pattern == rhs.regularExpression.pattern &&
+ lhs.regularExpression.pattern == rhs.regularExpression.pattern &&
lhs.regularExpression.options == rhs.regularExpression.options
}
}
@@ -175,12 +179,12 @@ extension Regex {
// MARK: Properties
/// The entire matched string.
public lazy var string: String = {
- return String(describing: self.baseString[self.range])
+ String(describing: self.baseString[self.range])
}()
/// The range of the matched string.
public lazy var range: Range = {
- return Range(self.result.range, in: self.baseString)!
+ Range(self.result.range, in: self.baseString)!
}()
/// The matching string for each capture group in the regular expression
@@ -219,6 +223,7 @@ extension Regex {
private let baseString: String
// MARK: - Initializers
+ @usableFromInline
internal init(result: NSTextCheckingResult, in string: String) {
precondition(
result.regularExpression != nil,
@@ -257,7 +262,7 @@ extension Regex {
// MARK: - CustomStringConvertible
/// Returns a string describing the match.
public var description: String {
- return "Match<\"\(string)\">"
+ "Match<\"\(string)\">"
}
}
}
diff --git a/Sources/HandySwift/Structs/SortedArray.swift b/Sources/HandySwift/Structs/SortedArray.swift
index 07d50e1..66a41f9 100644
--- a/Sources/HandySwift/Structs/SortedArray.swift
+++ b/Sources/HandySwift/Structs/SortedArray.swift
@@ -5,10 +5,10 @@ import Foundation
/// Data structure to keep a sorted array of elements for fast access.
public struct SortedArray {
// MARK: - Stored Instance Properties
- private var internalArray: [Element]
+ @usableFromInline internal var internalArray: [Element]
/// Returns the sorted array of elements.
- public var array: [Element] { return self.internalArray }
+ public var array: [Element] { self.internalArray }
// MARK: - Initializers
/// Creates a new, empty array.
@@ -30,7 +30,8 @@ public struct SortedArray {
self.init(sequence: sequence, preSorted: false)
}
- private init(sequence: S, preSorted: Bool) where S.Iterator.Element == Element {
+ @usableFromInline
+ internal init(sequence: S, preSorted: Bool) where S.Iterator.Element == Element {
internalArray = preSorted ? Array(sequence) : Array(sequence).sorted()
}
@@ -43,6 +44,7 @@ public struct SortedArray {
/// - Parameters:
/// - predicate: The predicate to match the elements against.
/// - Returns: The index of the first matching element or `nil` if none of them matches.
+ @inlinable
public func index(where predicate: (Element) -> Bool) -> Int? {
// cover trivial cases
guard !array.isEmpty else { return nil }
@@ -75,6 +77,7 @@ public struct SortedArray {
/// - Parameters:
/// - index: The upper bound index until which to include elements.
/// - Returns: A new SortedArray instance including all elements until the specified index (exluding it).
+ @inlinable
public func prefix(upTo index: Int) -> SortedArray {
let subarray = Array(array[array.indices.prefix(upTo: index)])
return SortedArray(sequence: subarray, preSorted: true)
@@ -87,6 +90,7 @@ public struct SortedArray {
/// - Parameters:
/// - index: The upper bound index until which to include elements.
/// - Returns: A new SortedArray instance including all elements until the specified index (including it).
+ @inlinable
public func prefix(through index: Int) -> SortedArray {
let subarray = Array(array[array.indices.prefix(through: index)])
return SortedArray(sequence: subarray, preSorted: true)
@@ -99,6 +103,7 @@ public struct SortedArray {
/// - Parameters:
/// - index: The lower bound index from which to start including elements.
/// - Returns: A new SortedArray instance including all elements starting at the specified index.
+ @inlinable
public func suffix(from index: Int) -> SortedArray {
let subarray = Array(array[array.indices.suffix(from: index)])
return SortedArray(sequence: subarray, preSorted: true)
@@ -111,6 +116,7 @@ public struct SortedArray {
///
/// - Parameters:
/// - newElement: The new element to be inserted into the array.
+ @inlinable
public mutating func insert(newElement: Element) {
let insertIndex = internalArray.firstIndex { $0 >= newElement } ?? internalArray.endIndex
internalArray.insert(newElement, at: insertIndex)
@@ -122,6 +128,7 @@ public struct SortedArray {
///
/// - Parameters:
/// - sequence
+ @inlinable
public mutating func insert(contentsOf sequence: S) where S.Iterator.Element == Element {
sequence.forEach { insert(newElement: $0) }
}
@@ -132,6 +139,7 @@ public struct SortedArray {
///
/// - Parameters:
/// - index: The index of the element to remove from the sorted array.
+ @inlinable
public mutating func remove(at index: Int) {
internalArray.remove(at: index)
}
@@ -140,32 +148,36 @@ public struct SortedArray {
///
/// - Parameter
/// - bounds: A range of the SortedArray's indices. The bounds of the range must be valid indices.
+ @inlinable
public subscript(bounds: Range) -> SortedArray {
- return SortedArray(sequence: array[bounds], preSorted: true)
+ SortedArray(sequence: array[bounds], preSorted: true)
}
}
extension SortedArray: Collection {
public typealias Index = Array.Index
- public var startIndex: Int {
- return internalArray.startIndex
+ @inlinable public var startIndex: Int {
+ internalArray.startIndex
}
- public var endIndex: Int {
- return internalArray.endIndex
+ @inlinable public var endIndex: Int {
+ internalArray.endIndex
}
+ @inlinable
public func sorted() -> [Element] {
- return internalArray
+ internalArray
}
+ @inlinable
public func index(after index: Int) -> Int {
- return internalArray.index(after: index)
+ internalArray.index(after: index)
}
+ @inlinable
public subscript(position: Int) -> Element {
- return internalArray[position]
+ internalArray[position]
}
}
diff --git a/Sources/HandySwift/Structs/Unowned.swift b/Sources/HandySwift/Structs/Unowned.swift
index 17275be..3d369b6 100644
--- a/Sources/HandySwift/Structs/Unowned.swift
+++ b/Sources/HandySwift/Structs/Unowned.swift
@@ -16,7 +16,7 @@ public struct Unowned where Wrapped: AnyObject {
extension Unowned: CustomDebugStringConvertible where Wrapped: CustomDebugStringConvertible {
/// A textual representation of this instance, suitable for debugging.
public var debugDescription: String {
- return value.debugDescription
+ value.debugDescription
}
}
@@ -39,7 +39,7 @@ extension Unowned: Equatable where Wrapped: Equatable {
/// - lhs: An optional value to compare.
/// - rhs: Another optional value to compare.
public static func == (lhs: Unowned, rhs: Unowned) -> Bool {
- return lhs.value == rhs.value
+ lhs.value == rhs.value
}
}
diff --git a/Sources/HandySwift/Structs/Weak.swift b/Sources/HandySwift/Structs/Weak.swift
index a16f867..bc656e6 100644
--- a/Sources/HandySwift/Structs/Weak.swift
+++ b/Sources/HandySwift/Structs/Weak.swift
@@ -24,6 +24,7 @@ public struct Weak: ExpressibleByNilLiteral where Wrapped: AnyObject {
/// of the instance.
/// - Returns: The result of the given closure. If this instance is `nil`,
/// returns `nil`.
+ @inlinable
public func map(_ transform: (Wrapped) throws -> U) rethrows -> U? {
guard let value = value else { return nil }
@@ -37,6 +38,7 @@ public struct Weak: ExpressibleByNilLiteral where Wrapped: AnyObject {
/// of the instance.
/// - Returns: The result of the given closure. If this instance is `nil`,
/// returns `nil`.
+ @inlinable
public func flatMap(_ transform: (Wrapped) throws -> U?) rethrows -> U? {
guard let value = value else { return nil }
@@ -47,7 +49,7 @@ public struct Weak: ExpressibleByNilLiteral where Wrapped: AnyObject {
extension Weak: CustomDebugStringConvertible {
/// A textual representation of this instance, suitable for debugging.
public var debugDescription: String {
- return value.debugDescription
+ value.debugDescription
}
}
@@ -70,7 +72,7 @@ extension Weak: Equatable where Wrapped: Equatable {
/// - lhs: An optional value to compare.
/// - rhs: Another optional value to compare.
public static func == (lhs: Weak, rhs: Weak) -> Bool {
- return lhs.value == rhs.value
+ lhs.value == rhs.value
}
}
diff --git a/Sources/SupportingFiles/Info.plist b/Sources/SupportingFiles/Info.plist
index 651d2ab..fdc4357 100644
--- a/Sources/SupportingFiles/Info.plist
+++ b/Sources/SupportingFiles/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 3.1.0
+ 3.2.0
CFBundleSignature
????
diff --git a/Tests/HandySwiftTests/Extensions/ArrayExtensionTests.swift b/Tests/HandySwiftTests/Extensions/ArrayExtTests.swift
similarity index 96%
rename from Tests/HandySwiftTests/Extensions/ArrayExtensionTests.swift
rename to Tests/HandySwiftTests/Extensions/ArrayExtTests.swift
index c45db26..2d5f026 100644
--- a/Tests/HandySwiftTests/Extensions/ArrayExtensionTests.swift
+++ b/Tests/HandySwiftTests/Extensions/ArrayExtTests.swift
@@ -3,12 +3,12 @@
@testable import HandySwift
import XCTest
-class ArrayExtensionTests: XCTestCase {
+class ArrayExtTests: XCTestCase {
struct T: Equatable { // swiftlint:disable:this type_name
let a: Int, b: Int // swiftlint:disable:this identifier_name
static func == (lhs: T, rhs: T) -> Bool {
- return lhs.a == rhs.a && lhs.b == rhs.b
+ lhs.a == rhs.a && lhs.b == rhs.b
}
}
diff --git a/Tests/HandySwiftTests/Extensions/CollectionExtensionTests.swift b/Tests/HandySwiftTests/Extensions/CollectionExtTests.swift
similarity index 69%
rename from Tests/HandySwiftTests/Extensions/CollectionExtensionTests.swift
rename to Tests/HandySwiftTests/Extensions/CollectionExtTests.swift
index 91dbf7d..5455c0a 100644
--- a/Tests/HandySwiftTests/Extensions/CollectionExtensionTests.swift
+++ b/Tests/HandySwiftTests/Extensions/CollectionExtTests.swift
@@ -3,7 +3,7 @@
@testable import HandySwift
import XCTest
-class CollectionExtensionTests: XCTestCase {
+class CollectionExtTests: XCTestCase {
func testTrySubscript() {
let testArray = [0, 1, 2, 3, 20]
@@ -28,7 +28,17 @@ class CollectionExtensionTests: XCTestCase {
let intArray = [1, 2, 10]
XCTAssertEqual(intArray.average(), 4.333, accuracy: 0.001)
+ #if canImport(CoreGraphics)
+ let averageAsCGFloat: CGFloat = intArray.average()
+ XCTAssertEqual(averageAsCGFloat, 4.333, accuracy: 0.001)
+ #endif
+
let doubleArray = [1.0, 2.0, 10.0]
XCTAssertEqual(doubleArray.average(), 4.333, accuracy: 0.001)
+
+ #if canImport(CoreGraphics)
+ let cgFloatArray: [CGFloat] = [1.0, 2.0, 10.0]
+ XCTAssertEqual(cgFloatArray.average(), 4.333, accuracy: 0.001)
+ #endif
}
}
diff --git a/Tests/HandySwiftTests/Extensions/ComparableExtensionTests.swift b/Tests/HandySwiftTests/Extensions/ComparableExtTests.swift
similarity index 98%
rename from Tests/HandySwiftTests/Extensions/ComparableExtensionTests.swift
rename to Tests/HandySwiftTests/Extensions/ComparableExtTests.swift
index dd07346..53d9c05 100644
--- a/Tests/HandySwiftTests/Extensions/ComparableExtensionTests.swift
+++ b/Tests/HandySwiftTests/Extensions/ComparableExtTests.swift
@@ -5,7 +5,7 @@ import Foundation
@testable import HandySwift
import XCTest
-class ComparableExtensionTests: XCTestCase {
+class ComparableExtTests: XCTestCase {
// MARK: Returning Variants
func testClampedClosedRange() {
let myNum = 3
diff --git a/Tests/HandySwiftTests/Extensions/DictionaryExtensionTests.swift b/Tests/HandySwiftTests/Extensions/DictionaryExtTests.swift
similarity index 97%
rename from Tests/HandySwiftTests/Extensions/DictionaryExtensionTests.swift
rename to Tests/HandySwiftTests/Extensions/DictionaryExtTests.swift
index 8dbb327..d4eede4 100644
--- a/Tests/HandySwiftTests/Extensions/DictionaryExtensionTests.swift
+++ b/Tests/HandySwiftTests/Extensions/DictionaryExtTests.swift
@@ -3,7 +3,7 @@
@testable import HandySwift
import XCTest
-class DictionaryExtensionTests: XCTestCase {
+class DictionaryExtTests: XCTestCase {
func testInitWithSameCountKeysAndValues() {
let keys = Array(0 ..< 100)
let values = Array(stride(from: 0, to: 10 * 100, by: 10))
diff --git a/Tests/HandySwiftTests/Extensions/DispatchTimeIntervalExtensionTests.swift b/Tests/HandySwiftTests/Extensions/DispatchTimeIntervalExtTests.swift
similarity index 85%
rename from Tests/HandySwiftTests/Extensions/DispatchTimeIntervalExtensionTests.swift
rename to Tests/HandySwiftTests/Extensions/DispatchTimeIntervalExtTests.swift
index 9471bd6..27a4392 100644
--- a/Tests/HandySwiftTests/Extensions/DispatchTimeIntervalExtensionTests.swift
+++ b/Tests/HandySwiftTests/Extensions/DispatchTimeIntervalExtTests.swift
@@ -3,7 +3,7 @@
@testable import HandySwift
import XCTest
-class DispatchTimeIntervalExtensionTests: XCTestCase {
+class DispatchTimeIntervalExtTests: XCTestCase {
func testTimeInterval() {
let dispatchTimeInterval = DispatchTimeInterval.milliseconds(500)
let timeInterval = dispatchTimeInterval.timeInterval
diff --git a/Tests/HandySwiftTests/Extensions/IntExtensionTests.swift b/Tests/HandySwiftTests/Extensions/IntExtTests.swift
similarity index 70%
rename from Tests/HandySwiftTests/Extensions/IntExtensionTests.swift
rename to Tests/HandySwiftTests/Extensions/IntExtTests.swift
index f7b9ee1..6d69c42 100644
--- a/Tests/HandySwiftTests/Extensions/IntExtensionTests.swift
+++ b/Tests/HandySwiftTests/Extensions/IntExtTests.swift
@@ -3,7 +3,7 @@
@testable import HandySwift
import XCTest
-class IntExtensionTests: XCTestCase {
+class IntExtTests: XCTestCase {
func testInitRandomBelow() {
10.times {
XCTAssertTrue(Int(randomBelow: 15)! < 15)
@@ -11,6 +11,14 @@ class IntExtensionTests: XCTestCase {
XCTAssertNil(Int(randomBelow: 0))
XCTAssertNil(Int(randomBelow: -1))
}
+
+ var generator = SystemRandomNumberGenerator()
+ 10.times {
+ XCTAssertTrue(Int(randomBelow: 15, using: &generator)! < 15)
+ XCTAssertTrue(Int(randomBelow: 15, using: &generator)! >= 0)
+ XCTAssertNil(Int(randomBelow: 0, using: &generator))
+ XCTAssertNil(Int(randomBelow: -1, using: &generator))
+ }
}
func testTimesMethod() {
diff --git a/Tests/HandySwiftTests/Extensions/NSObjectExtTests.swift b/Tests/HandySwiftTests/Extensions/NSObjectExtTests.swift
new file mode 100644
index 0000000..391f007
--- /dev/null
+++ b/Tests/HandySwiftTests/Extensions/NSObjectExtTests.swift
@@ -0,0 +1,13 @@
+// Copyright © 2020 Flinesoft. All rights reserved.
+
+@testable import HandySwift
+import XCTest
+
+class NSObjectExtTests: XCTestCase {
+ func testWith() {
+ #if !os(Linux)
+ let helloString: NSString? = ("Hello, world".mutableCopy() as? NSMutableString)?.with { $0.append("!") }
+ XCTAssertEqual(helloString, "Hello, world!")
+ #endif
+ }
+}
diff --git a/Tests/HandySwiftTests/Extensions/NSRangeExtensionTests.swift b/Tests/HandySwiftTests/Extensions/NSRangeExtTests.swift
similarity index 94%
rename from Tests/HandySwiftTests/Extensions/NSRangeExtensionTests.swift
rename to Tests/HandySwiftTests/Extensions/NSRangeExtTests.swift
index 527d40b..d317106 100644
--- a/Tests/HandySwiftTests/Extensions/NSRangeExtensionTests.swift
+++ b/Tests/HandySwiftTests/Extensions/NSRangeExtTests.swift
@@ -3,7 +3,7 @@
@testable import HandySwift
import XCTest
-class NSRangeExtensionTests: XCTestCase {
+class NSRangeExtTests: XCTestCase {
func testInitWithSwiftRange() {
let testStrings = ["Simple String", "👪 👨👩👦 👨👩👧 👨👩👧👦 👨👩👦👦 👨👩👧👧 👨👨👦 👨👨👧 👨👨👧👦 👨👨👦👦 👨👨👧👧 👩👩👦 👩👩👧 👩👩👧👦 👩👩👦👦 👩👩👧👧"]
diff --git a/Tests/HandySwiftTests/Extensions/StringExtensionTests.swift b/Tests/HandySwiftTests/Extensions/StringExtTests.swift
similarity index 98%
rename from Tests/HandySwiftTests/Extensions/StringExtensionTests.swift
rename to Tests/HandySwiftTests/Extensions/StringExtTests.swift
index c18b3a4..4bcb9a6 100644
--- a/Tests/HandySwiftTests/Extensions/StringExtensionTests.swift
+++ b/Tests/HandySwiftTests/Extensions/StringExtTests.swift
@@ -3,7 +3,7 @@
@testable import HandySwift
import XCTest
-class StringExtensionTests: XCTestCase {
+class StringExtTests: XCTestCase {
func testStrip() {
let whitespaceString = " \n\t BB-8 likes Rey \t\n "
XCTAssertEqual(whitespaceString.stripped(), "BB-8 likes Rey")
diff --git a/Tests/HandySwiftTests/Extensions/TimeIntervalExtensionTests.swift b/Tests/HandySwiftTests/Extensions/TimeIntervalExtTests.swift
similarity index 96%
rename from Tests/HandySwiftTests/Extensions/TimeIntervalExtensionTests.swift
rename to Tests/HandySwiftTests/Extensions/TimeIntervalExtTests.swift
index 3f22dfb..279e3fc 100644
--- a/Tests/HandySwiftTests/Extensions/TimeIntervalExtensionTests.swift
+++ b/Tests/HandySwiftTests/Extensions/TimeIntervalExtTests.swift
@@ -3,7 +3,7 @@
@testable import HandySwift
import XCTest
-class TimeIntervalExtensionTests: XCTestCase {
+class TimeIntervalExtTests: XCTestCase {
func testUnitInitialization() {
XCTAssertEqual(Timespan.days(0.5), 12 * 60 * 60, accuracy: 0.001)
XCTAssertEqual(Timespan.hours(0.5), 30 * 60, accuracy: 0.001)
diff --git a/Tests/HandySwiftTests/Structs/RegexTests.swift b/Tests/HandySwiftTests/Structs/RegexTests.swift
index 68537e8..5a6954b 100644
--- a/Tests/HandySwiftTests/Structs/RegexTests.swift
+++ b/Tests/HandySwiftTests/Structs/RegexTests.swift
@@ -12,11 +12,10 @@ class RegexTests: XCTestCase {
}
func testInvalidInitialization() {
- do {
+ do {
_ = try Regex("*")
XCTFail("Regex initialization unexpectedly didn't fail")
- } catch {
- }
+ } catch {}
}
// MARK: - Options
@@ -98,7 +97,7 @@ class RegexTests: XCTestCase {
let match1 = regex?.firstMatch(in: "2Needed")
let match2 = regex?.firstMatch(in: "5NeededOptional")
- enum CapturingError: Error { // swiftlint:disable:this nesting
+ enum CapturingError: Error {
case indexTooHigh
case noMatch
}
@@ -120,7 +119,7 @@ class RegexTests: XCTestCase {
XCTAssertEqual(match1Capture0, "2")
XCTAssertEqual(match1Capture1, "Needed")
- XCTAssertEqual(match1Capture2, nil)
+ XCTAssertNil(match1Capture2)
XCTAssertEqual(match2Capture0, "5")
XCTAssertEqual(match2Capture1, "Needed")
diff --git a/Tests/HandySwiftTests/Structs/SortedArrayTests.swift b/Tests/HandySwiftTests/Structs/SortedArrayTests.swift
index 79bdc70..e46b041 100644
--- a/Tests/HandySwiftTests/Structs/SortedArrayTests.swift
+++ b/Tests/HandySwiftTests/Structs/SortedArrayTests.swift
@@ -49,13 +49,13 @@ class SortedArrayTests: XCTestCase {
func testCollectionFeatures() {
let intArray: [Int] = [5, 6, 7, 8, 9, 0, 1, 2, 3, 4]
let sortedIntArray = SortedArray(intArray)
- let expectedElementsSum = intArray.reduce(0) { result, element in return result + element }
+ let expectedElementsSum = intArray.reduce(0) { result, element in result + element }
var forEachElementsSum = 0
sortedIntArray.forEach { forEachElementsSum += $0 }
XCTAssertEqual(forEachElementsSum, expectedElementsSum)
- let reduceElementsSum = sortedIntArray.reduce(0) { result, element in return result + element }
+ let reduceElementsSum = sortedIntArray.reduce(0) { result, element in result + element }
XCTAssertEqual(reduceElementsSum, expectedElementsSum)
let increasedByOneSortedArray = sortedIntArray.map { $0 + 1 }
diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift
index 936f458..120f37d 100644
--- a/Tests/LinuxMain.swift
+++ b/Tests/LinuxMain.swift
@@ -1,4 +1,4 @@
-// Generated using Sourcery 0.15.0 — https://github.com/krzysztofzablocki/Sourcery
+// Generated using Sourcery 0.17.0 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
@testable import HandySwiftTests
@@ -6,8 +6,8 @@ import XCTest
// swiftlint:disable line_length file_length
-extension ArrayExtensionTests {
- static var allTests: [(String, (ArrayExtensionTests) -> () throws -> Void)] = [
+extension ArrayExtTests {
+ static var allTests: [(String, (ArrayExtTests) -> () throws -> Void)] = [
("testSample", testSample),
("testSampleWithSize", testSampleWithSize),
("testCombinationsWithOther", testCombinationsWithOther),
@@ -16,14 +16,27 @@ extension ArrayExtensionTests {
]
}
-extension CollectionExtensionTests {
- static var allTests: [(String, (CollectionExtensionTests) -> () throws -> Void)] = [
- ("testTrySubscript", testTrySubscript)
+extension CollectionExtTests {
+ static var allTests: [(String, (CollectionExtTests) -> () throws -> Void)] = [
+ ("testTrySubscript", testTrySubscript),
+ ("testSum", testSum),
+ ("testAverage", testAverage)
]
}
-extension DictionaryExtensionTests {
- static var allTests: [(String, (DictionaryExtensionTests) -> () throws -> Void)] = [
+extension ComparableExtTests {
+ static var allTests: [(String, (ComparableExtTests) -> () throws -> Void)] = [
+ ("testClampedClosedRange", testClampedClosedRange),
+ ("testClampedPartialRangeFrom", testClampedPartialRangeFrom),
+ ("testClampedPartialRangeThrough", testClampedPartialRangeThrough),
+ ("testClampClosedRange", testClampClosedRange),
+ ("testClampPartialRangeFrom", testClampPartialRangeFrom),
+ ("testClampPartialRangeThrough", testClampPartialRangeThrough)
+ ]
+}
+
+extension DictionaryExtTests {
+ static var allTests: [(String, (DictionaryExtTests) -> () throws -> Void)] = [
("testInitWithSameCountKeysAndValues", testInitWithSameCountKeysAndValues),
("testInitWithDifferentCountKeysAndValues", testInitWithDifferentCountKeysAndValues),
("testMergeOtherDictionary", testMergeOtherDictionary),
@@ -31,8 +44,8 @@ extension DictionaryExtensionTests {
]
}
-extension DispatchTimeIntervalExtensionTests {
- static var allTests: [(String, (DispatchTimeIntervalExtensionTests) -> () throws -> Void)] = [
+extension DispatchTimeIntervalExtTests {
+ static var allTests: [(String, (DispatchTimeIntervalExtTests) -> () throws -> Void)] = [
("testTimeInterval", testTimeInterval)
]
}
@@ -50,14 +63,26 @@ extension GlobalsTests {
]
}
-extension IntExtensionTests {
- static var allTests: [(String, (IntExtensionTests) -> () throws -> Void)] = [
+extension IntExtTests {
+ static var allTests: [(String, (IntExtTests) -> () throws -> Void)] = [
("testInitRandomBelow", testInitRandomBelow),
("testTimesMethod", testTimesMethod),
("testTimesMakeMethod", testTimesMakeMethod)
]
}
+extension NSObjectExtTests {
+ static var allTests: [(String, (NSObjectExtTests) -> () throws -> Void)] = [
+ ("testWith", testWith)
+ ]
+}
+
+extension NSRangeExtTests {
+ static var allTests: [(String, (NSRangeExtTests) -> () throws -> Void)] = [
+ ("testInitWithSwiftRange", testInitWithSwiftRange)
+ ]
+}
+
extension RegexTests {
static var allTests: [(String, (RegexTests) -> () throws -> Void)] = [
("testValidInitialization", testValidInitialization),
@@ -88,33 +113,45 @@ extension SortedArrayTests {
]
}
-extension StringExtensionTests {
- static var allTests: [(String, (StringExtensionTests) -> () throws -> Void)] = [
+extension StringExtTests {
+ static var allTests: [(String, (StringExtTests) -> () throws -> Void)] = [
("testStrip", testStrip),
("testIsBlank", testIsBlank),
("testInitRandomWithLengthAllowedCharactersType", testInitRandomWithLengthAllowedCharactersType),
("testSample", testSample),
- ("testSampleWithSize", testSampleWithSize)
+ ("testSampleWithSize", testSampleWithSize),
+ ("testFullRange", testFullRange)
]
}
-extension TimeIntervalExtensionTests {
- static var allTests: [(String, (TimeIntervalExtensionTests) -> () throws -> Void)] = [
+extension TimeIntervalExtTests {
+ static var allTests: [(String, (TimeIntervalExtTests) -> () throws -> Void)] = [
("testUnitInitialization", testUnitInitialization),
("testUnitConversion", testUnitConversion)
]
}
+extension WithableTests {
+ static var allTests: [(String, (WithableTests) -> () throws -> Void)] = [
+ ("testInitWith", testInitWith),
+ ("testWith", testWith)
+ ]
+}
+
XCTMain([
- testCase(ArrayExtensionTests.allTests),
- testCase(CollectionExtensionTests.allTests),
- testCase(DictionaryExtensionTests.allTests),
- testCase(DispatchTimeIntervalExtensionTests.allTests),
+ testCase(ArrayExtTests.allTests),
+ testCase(CollectionExtTests.allTests),
+ testCase(ComparableExtTests.allTests),
+ testCase(DictionaryExtTests.allTests),
+ testCase(DispatchTimeIntervalExtTests.allTests),
testCase(FrequencyTableTests.allTests),
testCase(GlobalsTests.allTests),
- testCase(IntExtensionTests.allTests),
+ testCase(IntExtTests.allTests),
+ testCase(NSObjectExtTests.allTests),
+ testCase(NSRangeExtTests.allTests),
testCase(RegexTests.allTests),
testCase(SortedArrayTests.allTests),
- testCase(StringExtensionTests.allTests),
- testCase(TimeIntervalExtensionTests.allTests)
+ testCase(StringExtTests.allTests),
+ testCase(TimeIntervalExtTests.allTests),
+ testCase(WithableTests.allTests)
])
diff --git a/UsageExamples.playground/Contents.swift b/UsageExamples.playground/Contents.swift
index 9fb7fcf..575eac7 100644
--- a/UsageExamples.playground/Contents.swift
+++ b/UsageExamples.playground/Contents.swift
@@ -128,10 +128,12 @@ arrayForTry[try: 20]
[0.5, 1.5, 2.5].sum()
//: ### .average()
-//: Returns the average of all elements as a Double value.
-//: NOTE: Only available for `Int` and `Double` collections.
+//: Returns the average of all elements.
+//: NOTE: For `Int` collections, the average is returned alternatively as a `Double`, `Float` or `CGFloat` value.
[10, 20, 30, 40].average()
[10.75, 20.75, 30.25, 40.25].average()
+let averageAsFloat: Float = [10, 20, 30, 40].average()
+averageAsFloat
//: ## DictionaryExtension
//: ### init?(keys:values:)
diff --git a/beak.swift b/beak.swift
deleted file mode 100644
index e26bf24..0000000
--- a/beak.swift
+++ /dev/null
@@ -1,280 +0,0 @@
-// beak: kareman/SwiftShell @ .upToNextMajor(from: "4.0.1")
-// beak: kylef/PathKit @ .upToNextMajor(from: "0.9.1")
-// beak: onevcat/Rainbow @ .upToNextMajor(from: "3.1.2")
-// beak: Flinesoft/HandySwift @ .upToNextMajor(from: "2.6.0")
-
-import HandySwift
-import Foundation
-import SwiftShell
-import PathKit
-import Rainbow
-
-let supportedPlatforms = ["iOS", "tvOS", "macOS", "watchOS"]
-
-// MARK: - Helpers
-private func deleteFile(_ fileName: String) throws {
- let command = "[ ! -e \(fileName) ] || rm \(fileName)"
- print("Deleting file '\(fileName)': '\(command)'", level: .info)
- try runAndPrint(bash: command)
-}
-
-private func renameProject(from oldName: String, to newName: String) throws {
- var filesToReplaceContent: [Path] = [
- Path(oldName + ".xcodeproj/project.pbxproj"),
- Path(oldName + ".xcodeproj/project.xcworkspace/contents.xcworkspacedata")
- ]
-
- filesToReplaceContent += supportedPlatforms.map { Path(oldName + ".xcodeproj/xcshareddata/xcschemes/\(oldName) \($0).xcscheme") }
- filesToReplaceContent += Path.glob("Sources/**/*.swift")
- filesToReplaceContent += Path.glob("Tests/**/*.swift")
- filesToReplaceContent += [
- "README.md", "Package.swift", "Sources/Supporting Files/\(oldName).h", "UsageExamples.playground/Contents.swift",
- "\(oldName).xcworkspace/contents.xcworkspacedata", "\(oldName).podspec"
- ].map { Path($0) }
-
- try filesToReplaceContent.forEach { swiftFilePath in
- try replaceInFile(fileUrl: swiftFilePath.url, regex: try Regex(oldName), replacement: newName)
- }
-
- try supportedPlatforms.forEach { platform in
- let oldSchemePath = "\(oldName).xcodeproj/xcshareddata/xcschemes/\(oldName)\\ \(platform).xcscheme"
- let newSchemePath = "\(oldName).xcodeproj/xcshareddata/xcschemes/\(newName)\\ \(platform).xcscheme"
- try runAndPrint(bash: "mv \(oldSchemePath) \(newSchemePath)")
- }
-
- try runAndPrint(bash: "mv \(oldName).xcodeproj/ \(newName).xcodeproj/")
- try runAndPrint(bash: "mv \(oldName).xcworkspace/ \(newName).xcworkspace/")
- try runAndPrint(bash: "mv \(oldName).podspec \(newName).podspec")
- try runAndPrint(bash: "mv Sources/Supporting\\ Files/\(oldName).h Sources/Supporting\\ Files/\(newName).h")
-}
-
-private func renameOrganization(from oldName: String, to newName: String, projectName: String) throws {
- var filesToReplaceContent: [Path] = [
- Path("LICENSE.md"),
- Path("README.md"),
- Path("\(projectName).podspec"),
- Path("\(projectName).xcodeproj/project.pbxproj"),
- Path("Sources/Supporting Files/\(projectName).h")
- ]
-
- filesToReplaceContent += Path.glob("Sources/**/*.swift")
- filesToReplaceContent += Path.glob("Tests/**/*.swift")
-
- // replace normal URL appearances
- let oldNameWithoutWhitespaces = oldName.components(separatedBy: .whitespaces).joined()
- let newNameWithoutWhitespaces = newName.components(separatedBy: .whitespaces).joined()
-
- let urlRegex = try Regex("\(oldNameWithoutWhitespaces)/")
- try filesToReplaceContent.forEach { swiftFilePath in
- try replaceInFile(fileUrl: swiftFilePath.url, regex: urlRegex, replacement: "\(newNameWithoutWhitespaces)/")
- }
-
- // replace reversed URl appearances
- let reversedUrlRegex = try Regex("com.\(oldNameWithoutWhitespaces.lowercased())")
- try filesToReplaceContent.forEach { swiftFilePath in
- try replaceInFile(fileUrl: swiftFilePath.url, regex: reversedUrlRegex, replacement: "com.\(newNameWithoutWhitespaces.lowercased())")
- }
-
- // replace other
- try filesToReplaceContent.forEach { swiftFilePath in
- try replaceInFile(fileUrl: swiftFilePath.url, regex: try Regex(oldName), replacement: newName)
- }
-}
-
-private func replaceInFile(fileUrl: URL, regex: Regex, replacement: String) throws {
- print("Replacing occurences of regex '\(regex)' in file '\(fileUrl.lastPathComponent)' with '\(replacement)' ...", level: .info)
- var content = try String(contentsOf: fileUrl, encoding: .utf8)
- content = regex.replacingMatches(in: content, with: replacement)
- try content.write(to: fileUrl, atomically: false, encoding: .utf8)
-}
-
-private func replaceInFile(fileUrl: URL, substring: String, replacement: String) throws {
- print("Replacing occurences of substring '\(substring)' in file '\(fileUrl.lastPathComponent)' with '\(replacement)' ...", level: .info)
- var content = try String(contentsOf: fileUrl, encoding: .utf8)
- content = content.replacingOccurrences(of: substring, with: replacement)
- try content.write(to: fileUrl, atomically: false, encoding: .utf8)
-}
-
-private enum PrintLevel {
- case info
- case warning
- case error
-}
-
-private func print(_ message: String, level: PrintLevel) {
- switch level {
- case .info:
- print("ℹ️ ", message.lightBlue)
-
- case .warning:
- print("⚠️ ", message.yellow)
-
- case .error:
- print("❌ ", message.red)
- }
-}
-
-private let semanticVersionRegex = try Regex("(\\d+)\\.(\\d+)\\.(\\d+)\\s")
-
-private struct SemanticVersion: Comparable, CustomStringConvertible {
- let major: Int
- let minor: Int
- let patch: Int
-
- init(_ string: String) {
- guard let captures = semanticVersionRegex.firstMatch(in: string)?.captures else {
- fatalError("SemanticVersion initializer was used without checking the structure.")
- }
-
- major = Int(captures[0]!)!
- minor = Int(captures[1]!)!
- patch = Int(captures[2]!)!
- }
-
- static func < (lhs: SemanticVersion, rhs: SemanticVersion) -> Bool {
- guard lhs.major == rhs.major else { return lhs.major < rhs.major }
- guard lhs.minor == rhs.minor else { return lhs.minor < rhs.minor }
- return lhs.patch < rhs.patch
- }
-
- static func == (lhs: SemanticVersion, rhs: SemanticVersion) -> Bool {
- return lhs.major == rhs.major && lhs.minor == rhs.minor && lhs.patch == rhs.patch
- }
-
- var description: String {
- return "\(major).\(minor)"
- }
-}
-
-private func appendEntryToCartfile(_ tagline: String?, _ githubSubpath: String, _ version: String) throws {
- let comment = tagline != nil ? "# \(tagline!)\n" : ""
- let repoSpecifier = "github \"\(githubSubpath)\""
- let versionSpecifier: String = {
- guard version != "latest" else {
- let tagListCommand = "git ls-remote --tags https://github.com/\(githubSubpath).git"
- let commandOutput = run(bash: tagListCommand).stdout
- let availableSemanticVersions = semanticVersionRegex.matches(in: commandOutput).map { SemanticVersion($0.string) }
- guard !availableSemanticVersions.isEmpty else {
- print("Dependency '\(githubSubpath)' has no tagged versions.", level: .error)
- fatalError()
- }
- let latestVersion = availableSemanticVersions.sorted().last!
- return " ~> \(latestVersion)"
- }
-
- return " ~> \(version)"
- }()
-
- let textToAddToCartfile = "\n\(comment)\(repoSpecifier)\(versionSpecifier)\n"
-
- let command = "echo '\(textToAddToCartfile)' >> Cartfile"
- print("Adding entry to Cartfile with: '\(command)'", level: .info)
- try runAndPrint(bash: command)
-}
-
-private func fetchGitHubTagline(subpath: String) throws -> String? {
- let taglineRegex = try Regex("[^\\:]+\\: (.*)<\\/title>")
- let url = URL(string: "https://github.com/\(subpath)")!
- let html = try String(contentsOf: url, encoding: .utf8)
- guard let firstMatch = taglineRegex.firstMatch(in: html) else { return nil }
- guard let firstCapture = firstMatch.captures.first else { return nil }
- return firstCapture!
-}
-
-private func pathOfXcodeProject() -> Path {
- return Path.current.glob("*.xcodeproj").first!
-}
-
-typealias Framework = (identifier: String, name: String)
-
-private func pbxProjectFilePath() -> Path {
- return pathOfXcodeProject() + Path("project.pbxproj")
-}
-
-private func pbxProjectFileContent() throws -> String {
- return try pbxProjectFilePath().read(.utf8)
-}
-
-private struct CartfileEntry: CustomStringConvertible {
- let commentLine: String?
- let dependencyDefinitionLine: String
-
- var description: String {
- guard let commentLine = commentLine else { return dependencyDefinitionLine }
- return [commentLine, dependencyDefinitionLine].joined(separator: "\n")
- }
-}
-
-// MARK: - Tasks
-/// Initializes the project with the given info.
-public func initialize(projectName: String, organization: String) throws {
- try ["README.md", "Logo.png"].forEach { try deleteFile($0) }
- try runAndPrint(bash: "mv README.md.sample README.md")
- try renameProject(from: "NewFrameworkTemplate", to: projectName)
- try renameOrganization(from: "Flinesoft", to: organization, projectName: projectName)
- try installDependencies()
-}
-
-/// Installs project dependencies.
-public func installDependencies() throws {
- let command = "carthage bootstrap --platform \(supportedPlatforms.joined(separator: ",")) --cache-builds"
- print("Installing dependencies via Carthage: '\(command)'", level: .info)
- try runAndPrint(bash: command)
-}
-
-/// Updates project dependencies.
-public func updateDependencies() throws {
- let command = "carthage update --platform \(supportedPlatforms.joined(separator: ",")) --cache-builds"
- print("Updating dependencies via Carthage: \(command)", level: .info)
- try runAndPrint(bash: command)
-}
-
-/// Adds a dependency using the configured package manager.
-public func addDependency(github githubSubpath: String, version: String = "latest") throws {
- let tagline = try fetchGitHubTagline(subpath: githubSubpath)
- try appendEntryToCartfile(tagline, githubSubpath, version)
- try sortCartfile()
- try updateDependencies()
-
- print("Please add the new frameworks to your projects 'Carthage >> Framework' groups related platforms in the project navigator.", level: .warning)
-
- run(bash: "open -a Finder Carthage/Build/")
-}
-
-/// Sorts the contents of Cartfile and Cartfile.private.
-public func sortCartfile() throws {
- let dependecyLineRegex = try Regex("#? ?(?:github|binary|git) \"[^\"]+/([^\"]+)\".*")
-
- try ["Cartfile", "Cartfile.private"].forEach { fileName in
- let cartfileContents = try String(contentsOfFile: fileName)
- let cartfileLines = cartfileContents.components(separatedBy: .newlines).filter { !$0.isBlank }
-
- var temporaryComment: String?
- let cartfileEntries: [CartfileEntry] = cartfileLines.compactMap { line in
- if dependecyLineRegex.matches(line) {
- let newEntry = CartfileEntry(commentLine: temporaryComment, dependencyDefinitionLine: line)
- temporaryComment = nil
- return newEntry
- } else {
- temporaryComment = line
- return nil
- }
- }
-
- let compareClosure = { (lhs: CartfileEntry, rhs: CartfileEntry) -> Bool in
- let lhsDependencyName = dependecyLineRegex.firstMatch(in: lhs.dependencyDefinitionLine)!.captures.first!!.lowercased()
- let rhsDependencyName = dependecyLineRegex.firstMatch(in: rhs.dependencyDefinitionLine)!.captures.first!!.lowercased()
- return lhsDependencyName < rhsDependencyName
- }
-
- let sortedCartfilEntries = cartfileEntries.sorted(by: compareClosure, stable: false)
- let newCartfileContents = sortedCartfilEntries.map { $0.description }.joined(separator: "\n\n") + "\n"
- try newCartfileContents.write(toFile: fileName, atomically: false, encoding: .utf8)
- }
-}
-
-/// Generates the LinuxMain.swift file by automatically searching the Tests path for tests.
-public func generateLinuxMain() {
- run("sourcery --sources Tests --templates .sourcery/LinuxMain.stencil --output .sourcery --force-parse generated")
- run("mv .sourcery/LinuxMain.generated.swift Tests/LinuxMain.swift")
-}