Skip to content

Commit

Permalink
[ADD] Added matching keyword to improve chords searching
Browse files Browse the repository at this point in the history
[MOD] Updated Swift tools version to 5.9
  • Loading branch information
x-0o0 committed Jul 28, 2024
1 parent 38562c1 commit e59e463
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 6 deletions.
15 changes: 9 additions & 6 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
// swift-tools-version:5.4
// The swift-tools-version declares the minimum version of Swift required to build this package.
// swift-tools-version:5.9

import PackageDescription

let package = Package(
name: "SwiftyChords",
platforms: [.iOS(.v13), .macOS(.v11)],
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.library(
name: "SwiftyChords",
targets: ["SwiftyChords"]),
targets: ["SwiftyChords"]
),
],
dependencies: [],
targets: [
.target(
name: "SwiftyChords",
dependencies: [],
resources: [.process("Resources")]
),
.testTarget(
name: "SwiftyChordsTests",
dependencies: [
"SwiftyChords"
]
)
]
)
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ Returns all suspended chords in the database along with their variants such as s
Chords.guitar.matching(group: .suspended)
```

### Filter by String Keyword
Returns all Dsus4 chords. This works the same as filtering by key and suffix.

```swift
Chords.guitar.matching(keyword: "Dsus4") // same as Chords.guitar.matching(key: .d).matching(suffix: .sus4)
```


## Display
Swifty Chords suports a number of alternative texts you can use in your UI including an accessibility text-to-speech friendly variant.
Display texts from both Key and Suffix properties can be combined to complete the chord name.
Expand Down
37 changes: 37 additions & 0 deletions Sources/SwiftyChords/Array+Chords.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,41 @@ public extension Array where Element == ChordPosition {
return self.filter { $0.suffix.group == group }
}

func matching(keyword: String) -> [ChordPosition] {
// check keyword invalidation...
let trimmedKeyword = keyword.trimmingCharacters(in: .whitespaces)
if trimmedKeyword.isEmpty { return [] }

// If the keyword has 1 or 0 character, returns the matching `ChordPosition`s immediately
if trimmedKeyword.count < 2 {
guard let key = Chords.Key(rawValue: trimmedKeyword) else { return [] }
return self.matching(key: key)
}

// Get second character
let sharpOrFlat = trimmedKeyword[trimmedKeyword.index(trimmedKeyword.startIndex, offsetBy: 1)]
let hasSharpOrFlat = (sharpOrFlat == "b") || (sharpOrFlat == "#") // C#, Bb, Eb, D#, ...

// Get string for key
let keyString = String(trimmedKeyword.prefix(hasSharpOrFlat ? 2 : 1))

// If the string for key is invalid, returns immediately
guard let key = Chords.Key(rawValue: keyString) else { return [] }

// Get string for suffix
var suffixString = String(trimmedKeyword.dropFirst(hasSharpOrFlat ? 2 : 1))

// If the string for suffix is empty, assigns "major" instead.
// If the string for suffix is "m", assigns "minor" instead.
if suffixString.isEmpty {
suffixString = "major"
} else if suffixString == "m" {
suffixString = "minor"
}

guard let suffix = Chords.Suffix(rawValue: suffixString) else { return [] }

// Returns the matching chord positions
return self.matching(key: key).matching(suffix: suffix)
}
}
27 changes: 27 additions & 0 deletions Tests/SwiftyChordsTests/ArrayExtensionTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// ArrayExtensionTests.swift
//
//
// Created on 7/28/24.
//

#if canImport(Testing)
import Testing
@testable import SwiftyChords

@Suite
struct ArrayExtensionTests {
@Test(
"Tests 'matching(keyword:)'",
arguments: Chord.allCases
)
func matchingKeyword(chord: Chord) throws {
let chords = Chords.guitar
let positions = chords.matching(keyword: chord.keyword)

#expect(positions.filter { $0.key.rawValue != chord.key.rawValue }.isEmpty)
#expect(positions.filter { $0.suffix.rawValue != chord.suffix.rawValue }.isEmpty)
}
}
#endif

45 changes: 45 additions & 0 deletions Tests/SwiftyChordsTests/Chord.Tests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//
// Chord.Tests.swift
//
//
// Created on 7/28/24.
//

enum Chord: CaseIterable {
case cSharpMajor, aMinor, cBasedG, dSus4, g7

var keyword: String {
switch self {
case .cSharpMajor:
"C#"
case .aMinor:
"Am"
case .cBasedG:
"C/G"
case .dSus4:
"Dsus4"
case .g7:
"G7"
}
}
var key: Chords.Key {
switch self {
case .cSharpMajor: Chords.Key.cSharp
case .aMinor: Chords.Key.a
case .cBasedG: Chords.Key.c
case .dSus4: Chords.Key.d
case .g7: Chords.Key.g
}
}

var suffix: Chords.Suffix {
switch self {
case .cSharpMajor: Chords.Suffix.major
case .aMinor: Chords.Suffix.minor
case .cBasedG: Chords.Suffix.slashG
case .dSus4: Chords.Suffix.susFour
case .g7: Chords.Suffix.seven
}
}
}

0 comments on commit e59e463

Please sign in to comment.