Changes
3 changed files (+104/-1)
-
-
@@ -116,6 +116,50 @@ self.itemKey = itemKeyself.hint = hint self.inputPrompt = inputPrompt } /// Newer browsing pages, such as third-party cloud service's pages, *may* return /// `[[ID|label]]` formatted text for subtitle. As the text will be nearly unreadable, /// this helper getter function parses that and returns label part. The format is not specified. public var correctedSubtitle: String? { guard let subtitle = subtitle else { return nil } var source = subtitle[...] var components: [Substring] = [] while true { guard let starts = source.firstRange(of: "[[") else { components.append(source) break } guard let idEnds = source.firstIndex(of: "|") else { components.append(source) break } guard let ends = source.firstRange(of: "]]") else { components.append(source) break } guard starts.upperBound < idEnds, idEnds < ends.lowerBound else { components.append(source) break } components.append(source[..<starts.lowerBound]) components.append(source[source.index(after: idEnds)..<ends.lowerBound]) if ends.upperBound >= source.index(before: source.endIndex) { break } source = source[ends.upperBound...] } return components.joined() } } public enum ListHint: LosslessStringConvertible, Codable, Sendable {
-
-
-
@@ -0,0 +1,59 @@// Copyright 2025 Shota FUJI // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // SPDX-License-Identifier: Apache-2.0 import Foundation import Testing @testable import RoonKit @Suite("Subtitle parsing") struct BrowseServiceSubtitleParsingTests { @Test func fullLink() { let item = BrowseService.Item(title: "Foo", subtitle: "[[123456|Subtitle]]") #expect(item.correctedSubtitle == "Subtitle") } @Test func nonLink() { let item = BrowseService.Item(title: "Foo", subtitle: "[123456|Subtitle]") #expect(item.correctedSubtitle == "[123456|Subtitle]") } @Test func linkStartsInMiddle() { let item = BrowseService.Item(title: "Foo", subtitle: "foo [[123456|bar]]") #expect(item.correctedSubtitle == "foo bar") } @Test func linkEndsInMiddle() { let item = BrowseService.Item(title: "Foo", subtitle: "[[123456|foo]] bar") #expect(item.correctedSubtitle == "foo bar") } @Test func linkSurrounded() { let item = BrowseService.Item( title: "Foo", subtitle: "foo [[123456|bar]] baz" ) #expect(item.correctedSubtitle == "foo bar baz") } @Test func multipleLinks() { let item = BrowseService.Item( title: "Foo", subtitle: "[[1|foo]] [[2|bar]] [[3|baz]]" ) #expect(item.correctedSubtitle == "foo bar baz") } }
-
-
-
@@ -135,7 +135,7 @@ Text(item.title).font(.headline) .lineLimit(1) if let subtitle = item.subtitle { if let subtitle = item.correctedSubtitle { Text(subtitle) .font(.subheadline) .lineLimit(1)
-