File tree Expand file tree Collapse file tree
Sources/StringContainsOperators
Tests/StringContainsOperatorsTests Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ //
2+ // String+removeDiacriticsAndCase.swift
3+ //
4+ //
5+ // Created by Victor C Tavernari on 23/03/2023.
6+ //
7+
8+ import Foundation
9+
10+ /// An extension of String that removes diacritics and lowercase the string.
11+ extension String {
12+
13+ /// Removes diacritics and lowercase the string.
14+ ///
15+ /// - Returns: The string with removed diacritics and lowercase.
16+ func removeDiacriticsAndCase( ) -> String {
17+
18+ return folding ( options: . diacriticInsensitive,
19+ locale: Locale . current)
20+ }
21+ }
Original file line number Diff line number Diff line change 1+ //
2+ // AndOnlyPredicateSearchStrategy.swift
3+ //
4+ //
5+ // Created by Victor C Tavernari on 23/03/2023.
6+ //
7+
8+ import Foundation
9+
10+ /// `AndOnlyPredicateSearchStrategy` is a type of `SearchStrategy` that searches for multiple `StringPredicate`s with an "AND" condition.
11+ final class AndOnlyPredicateSearchStrategy : SearchStrategy {
12+
13+ /// The list of `StringPredicate`s to be searched.
14+ let predicates : [ StringPredicate ]
15+
16+ /// Initializes a new instance of `AndOnlyPredicateSearchStrategy`.
17+ ///
18+ /// - Parameter predicates: The list of `StringPredicate`s to be searched.
19+ init ( predicates: [ StringPredicate ] ) {
20+
21+ self . predicates = predicates
22+ }
23+
24+ /// Evaluates if a given string contains all of the `StringPredicate`s in the `predicates` array.
25+ ///
26+ /// - Parameter string: The string to be evaluated.
27+ /// - Returns: `true` if the string contains all of the `StringPredicate`s in the `predicates` array, `false` otherwise.
28+ func evaluate( string: String ) -> Bool {
29+
30+ return predicates. allSatisfy ( string. contains)
31+ }
32+ }
Original file line number Diff line number Diff line change 1+ //
2+ // AndPredicateSearchStrategy.swift
3+ //
4+ //
5+ // Created by Victor C Tavernari on 23/03/2023.
6+ //
7+
8+ import Foundation
9+
10+ /// `AndPredicateSearchStrategy` is a type of `SearchStrategy` that searches for a `String` and a `StringPredicate` with an "AND" condition.
11+ final class AndPredicateSearchStrategy : SearchStrategy {
12+
13+ /// The string to be searched.
14+ let value : String
15+
16+ /// The `StringPredicate` to be searched.
17+ let predicate : StringPredicate
18+
19+ /// Initializes a new instance of `AndPredicateSearchStrategy`.
20+ ///
21+ /// - Parameters:
22+ /// - value: The string to be searched.
23+ /// - predicate: The `StringPredicate` to be searched.
24+ init ( value: String , predicate: StringPredicate ) {
25+
26+ self . value = value
27+ self . predicate = predicate
28+ }
29+
30+ /// Evaluates if a given string contains both the string `value` and the `StringPredicate` `predicate`.
31+ ///
32+ /// - Parameter string: The string to be evaluated.
33+ /// - Returns: `true` if the string contains both the string `value` and the `StringPredicate` `predicate`, `false` otherwise.
34+ func evaluate( string: String ) -> Bool {
35+
36+ return string. contains ( self . predicate) && string. contains ( self . value)
37+ }
38+ }
Original file line number Diff line number Diff line change 1+ //
2+ // AndSearchStrategy.swift
3+ //
4+ //
5+ // Created by Victor C Tavernari on 23/03/2023.
6+ //
7+
8+ import Foundation
9+
10+ /// `AndSearchStrategy` is a type of `SearchStrategy` that searches for multiple `String`s with an "AND" condition.
11+ final class AndSearchStrategy : SearchStrategy {
12+
13+ /// The list of strings to be searched.
14+ let strings : [ String ]
15+
16+ /// Initializes a new instance of `AndSearchStrategy`.
17+ ///
18+ /// - Parameter strings: The list of strings to be searched.
19+ init ( strings: [ String ] ) {
20+
21+ self . strings = strings
22+ }
23+
24+ /// Evaluates if a given string contains all of the `String`s in the `strings` array.
25+ ///
26+ /// - Parameter string: The string to be evaluated.
27+ /// - Returns: `true` if the string contains all of the `String`s in the `strings` array, `false` otherwise.
28+ func evaluate( string: String ) -> Bool {
29+
30+ return strings. allSatisfy ( string. contains)
31+ }
32+ }
Original file line number Diff line number Diff line change 1+ //
2+ // DiacriticAndCaseInsensitiveSearchStrategy.swift
3+ //
4+ //
5+ // Created by Victor C Tavernari on 23/03/2023.
6+ //
7+
8+ import Foundation
9+
10+ /// `DiacriticAndCaseInsensitiveSearchStrategy` is a type of `SearchStrategy` that searches for a `String` case-insensitively and without diacritics.
11+ final class DiacriticAndCaseInsensitiveSearchStrategy : SearchStrategy {
12+
13+ /// The string to be searched without diacritics and case-insensitively.
14+ let value : String
15+
16+ /// Initializes a new instance of `DiacriticAndCaseInsensitiveSearchStrategy`.
17+ ///
18+ /// - Parameter value: The string to be searched.
19+ init ( value: String ) {
20+
21+ self . value = value. removeDiacriticsAndCase ( ) . lowercased ( )
22+ }
23+
24+ /// Evaluates if a given string contains the `value` string without diacritics and case-insensitively.
25+ ///
26+ /// - Parameter string: The string to be evaluated.
27+ /// - Returns: `true` if the string contains the `value` string without diacritics and case-insensitively, `false` otherwise.
28+ func evaluate( string: String ) -> Bool {
29+
30+ return string
31+ . removeDiacriticsAndCase ( )
32+ . lowercased ( )
33+ . contains ( self . value)
34+ }
35+ }
Original file line number Diff line number Diff line change 1+ //
2+ // OrOnlyPredicateSearchStrategy.swift
3+ //
4+ //
5+ // Created by Victor C Tavernari on 23/03/2023.
6+ //
7+
8+ import Foundation
9+
10+ /// `OrOnlyPredicateSearchStrategy` is a type of `SearchStrategy` that searches for multiple `StringPredicate`s with an "OR" condition.
11+ final class OrOnlyPredicateSearchStrategy : SearchStrategy {
12+
13+ /// The list of `StringPredicate`s to be searched.
14+ let predicates : [ StringPredicate ]
15+
16+ /// Initializes a new instance of `OrOnlyPredicateSearchStrategy`.
17+ ///
18+ /// - Parameter predicates: The list of `StringPredicate`s to be searched.
19+ init ( predicates: [ StringPredicate ] ) {
20+
21+ self . predicates = predicates
22+ }
23+
24+ /// Evaluates if a given string contains at least one of the `StringPredicate`s in the `predicates` array.
25+ ///
26+ /// - Parameter string: The string to be evaluated.
27+ /// - Returns: `true` if the string contains at least one of the `StringPredicate`s in the `predicates` array, `false` otherwise.
28+ func evaluate( string: String ) -> Bool {
29+
30+ self . predicates. contains ( where: string. contains)
31+ }
32+ }
Original file line number Diff line number Diff line change 1+ //
2+ // OrPredicateSearchStrategy.swift
3+ //
4+ //
5+ // Created by Victor C Tavernari on 23/03/2023.
6+ //
7+
8+ import Foundation
9+
10+
11+ /// An OrPredicateSearchStrategy is a SearchStrategy that searches for the occurrence of a given string or a given StringPredicate.
12+ final class OrPredicateSearchStrategy : SearchStrategy {
13+
14+ /// The string to search for.
15+ let value : String
16+
17+ /// The predicate to search for.
18+ let predicate : StringPredicate
19+
20+ /// Creates a new `OrPredicateSearchStrategy` instance with the given string and predicate.
21+ ///
22+ /// - Parameters:
23+ /// - value: The string to search for.
24+ /// - predicate: The predicate to search for.
25+ init ( value: String , predicate: StringPredicate ) {
26+
27+ self . value = value
28+ self . predicate = predicate
29+ }
30+
31+ /// Evaluates whether the given string contains either the string or the predicate that this strategy is looking for.
32+ ///
33+ /// - Parameter string: The string to evaluate.
34+ /// - Returns: `true` if the string contains either the string or the predicate that this strategy is looking for, `false` otherwise.
35+ func evaluate( string: String ) -> Bool {
36+
37+ return string. contains ( self . predicate) || string. contains ( self . value)
38+ }
39+ }
Original file line number Diff line number Diff line change 1+ //
2+ // OrSearchStrategy.swift
3+ //
4+ //
5+ // Created by Victor C Tavernari on 23/03/2023.
6+ //
7+
8+ import Foundation
9+
10+ /// OrSearchStrategy is a concrete class that represents a strategy to search for a string that contains at least one of a given array of strings.
11+ final class OrSearchStrategy : SearchStrategy {
12+
13+ /// An array of strings to search.
14+ let strings : [ String ]
15+
16+ /// Initializes an instance of `OrSearchStrategy`.
17+ /// - Parameter strings: An array of strings to search.
18+ init ( strings: [ String ] ) {
19+
20+ self . strings = strings
21+ }
22+
23+ /// Evaluates if a given string contains at least one of the strings in `strings`.
24+ /// - Parameter string: The string to search.
25+ /// - Returns: `true` if the string contains at least one of the strings in `strings`, `false` otherwise.
26+ func evaluate( string: String ) -> Bool {
27+
28+ self . strings. contains ( where: string. contains)
29+ }
30+ }
Original file line number Diff line number Diff line change 1+ //
2+ // SearchStrategy.swift
3+ //
4+ //
5+ // Created by Victor C Tavernari on 23/03/2023.
6+ //
7+
8+ import Foundation
9+
10+ /// A protocol that defines the behavior of a search strategy.
11+ protocol SearchStrategy {
12+
13+ /// Evaluates if a given string matches the search strategy.
14+ ///
15+ /// - Parameter string: The string to evaluate.
16+ /// - Returns: `true` if the string matches the search strategy, otherwise `false`.
17+ func evaluate( string: String ) -> Bool
18+ }
Original file line number Diff line number Diff line change 1+ //
2+ // File.swift
3+ //
4+ //
5+ // Created by Victor C Tavernari on 23/03/2023.
6+ //
7+
8+ import Foundation
9+
10+ /// `SearchStrategyMaker` is a factory that produces `SearchStrategy` objects based on a given `StringPredicate`.
11+ enum SearchStrategyMaker {
12+
13+ /// Creates an appropriate `SearchStrategy` based on the given `StringPredicate`.
14+ ///
15+ /// - Parameter predicate: The `StringPredicate` to base the `SearchStrategy` on.
16+ /// - Returns: The appropriate `SearchStrategy`.
17+ static func make( predicate: StringPredicate ) -> SearchStrategy {
18+
19+ switch predicate {
20+
21+ case let . or( strings) :
22+ return OrSearchStrategy ( strings: strings)
23+
24+ case let . orPredicates( value, predicate) :
25+ return OrPredicateSearchStrategy ( value: value, predicate: predicate)
26+
27+ case let . orOnlyPredicates( predicates) :
28+ return OrOnlyPredicateSearchStrategy ( predicates: predicates)
29+
30+ case let . and( strings) :
31+ return AndSearchStrategy ( strings: strings)
32+
33+ case let . andPredicates( value, predicate) :
34+ return AndPredicateSearchStrategy ( value: value, predicate: predicate)
35+
36+ case let . andOnlyPredicates( predicates) :
37+ return AndOnlyPredicateSearchStrategy ( predicates: predicates)
38+
39+ case let . diacriticAndCaseInsensitive( value) :
40+ return DiacriticAndCaseInsensitiveSearchStrategy ( value: value)
41+ }
42+ }
43+ }
You can’t perform that action at this time.
0 commit comments