Skip to content

Commit c13edfd

Browse files
committed
Add search strategy and comments
1 parent 7eb43dd commit c13edfd

12 files changed

Lines changed: 335 additions & 34 deletions
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
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+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
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+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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+
}

0 commit comments

Comments
 (0)