CandidateNode // Subclass: ServiceMenuNode.
This commit is contained in:
parent
040c597345
commit
dc79c629a1
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public class CandidateNode {
|
open class CandidateNode {
|
||||||
public var name: String
|
public var name: String
|
||||||
public var members: [CandidateNode]
|
public var members: [CandidateNode]
|
||||||
public var previous: CandidateNode?
|
public var previous: CandidateNode?
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||||
|
// ====================
|
||||||
|
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
|
||||||
|
// ... with NTL restriction stating that:
|
||||||
|
// No trademark license is granted to use the trade names, trademarks, service
|
||||||
|
// marks, or product names of Contributor, except as required to fulfill notice
|
||||||
|
// requirements defined in MIT License.
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public extension CandidateNode {
|
||||||
|
convenience init(
|
||||||
|
name: String, services: [CandidateTextService], previous: CandidateNode? = nil
|
||||||
|
) {
|
||||||
|
self.init(name: name, members: services.map(\.asCandidateNode), previous: previous)
|
||||||
|
}
|
||||||
|
|
||||||
|
var asServiceMenuNode: ServiceMenuNode? {
|
||||||
|
self as? ServiceMenuNode
|
||||||
|
}
|
||||||
|
|
||||||
|
var containsCandidateServices: Bool {
|
||||||
|
!members.compactMap(\.asServiceMenuNode).isEmpty
|
||||||
|
}
|
||||||
|
|
||||||
|
class ServiceMenuNode: CandidateNode {
|
||||||
|
public var service: CandidateTextService
|
||||||
|
public init(
|
||||||
|
name: String, service givenService: CandidateTextService, previous: CandidateNode? = nil
|
||||||
|
) {
|
||||||
|
service = givenService
|
||||||
|
super.init(name: name, previous: previous)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension CandidateTextService {
|
||||||
|
var asCandidateNode: CandidateNode.ServiceMenuNode {
|
||||||
|
.init(name: menuTitle, service: self)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func getCurrentServiceMenu(
|
||||||
|
fromMap map: [String]? = nil, candidate: String, reading: [String]
|
||||||
|
) -> CandidateNode? {
|
||||||
|
let fetchedRaw = map ?? PrefMgr().candidateServiceMenuContents
|
||||||
|
let fetched = fetchedRaw.parseIntoCandidateTextServiceStack(candidate: candidate, reading: reading)
|
||||||
|
return fetched.isEmpty ? nil : .init(name: candidate, services: fetched)
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,4 +32,17 @@ final class SharedTests: XCTestCase {
|
||||||
}
|
}
|
||||||
XCTAssertEqual(stacked.rawRepresentation, Self.testDataMap)
|
XCTAssertEqual(stacked.rawRepresentation, Self.testDataMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testCandidateServiceMenuNode() throws {
|
||||||
|
let rootNode = CandidateTextService.getCurrentServiceMenu(
|
||||||
|
fromMap: Self.testDataMap,
|
||||||
|
candidate: "🍰", reading: ["ㄉㄢˋ", "ㄍㄠ"]
|
||||||
|
)
|
||||||
|
guard let rootNode = rootNode else {
|
||||||
|
XCTAssertThrowsError("Root Node Construction Failed.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
print(rootNode.members.map(\.name))
|
||||||
|
print(rootNode.members.compactMap(\.asServiceMenuNode?.service))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue