Skip to content

Commit f057ef4

Browse files
authored
Implement list item delimiter attribute (#1272)
1 parent bd7483e commit f057ef4

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

Sources/FoundationEssentials/AttributedString/FoundationAttributes.swift

+40
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ extension AttributeScopes {
5454
public let presentationIntent: PresentationIntentAttribute
5555
@available(macOS 13, iOS 16, tvOS 16, watchOS 9, *)
5656
public let markdownSourcePosition: MarkdownSourcePositionAttribute
57+
@available(FoundationPreview 6.2, *)
58+
public let listItemDelimiter: ListItemDelimiterAttribute
5759

5860
@available(macOS 13, iOS 16, tvOS 16, watchOS 9, *)
5961
public let localizedStringArgumentAttributes: LocalizedStringArgumentAttributes
@@ -437,6 +439,44 @@ extension AttributeScopes.FoundationAttributes {
437439
public typealias Value = AttributedString.MarkdownSourcePosition
438440
}
439441

442+
@frozen
443+
@available(FoundationPreview 6.2, *)
444+
public enum ListItemDelimiterAttribute : CodableAttributedStringKey, ObjectiveCConvertibleAttributedStringKey {
445+
public typealias Value = Character
446+
public typealias ObjectiveCValue = NSString
447+
448+
public static let name = NSAttributedString.Key.listItemDelimiter.rawValue
449+
450+
public static func objectiveCValue(for value: Character) throws -> NSString {
451+
String(value) as NSString
452+
}
453+
454+
public static func value(for object: NSString) throws -> Character {
455+
let stringValue = object as String
456+
guard stringValue.count == 1 else {
457+
throw CocoaError(.coderInvalidValue)
458+
}
459+
return stringValue[stringValue.startIndex]
460+
}
461+
462+
public static func encode(_ value: Character, to encoder: any Encoder) throws {
463+
var container = encoder.singleValueContainer()
464+
try container.encode(String(value))
465+
}
466+
467+
public static func decode(from decoder: any Decoder) throws -> Character {
468+
let container = try decoder.singleValueContainer()
469+
let text = try container.decode(String.self)
470+
guard text.count == 1 else {
471+
throw DecodingError.dataCorrupted(DecodingError.Context(
472+
codingPath: container.codingPath,
473+
debugDescription: "List item delimeter encoded value must contain only one character / grapheme cluster"
474+
))
475+
}
476+
return text[text.startIndex]
477+
}
478+
}
479+
440480
#endif // FOUNDATION_FRAMEWORK
441481

442482
@frozen

0 commit comments

Comments
 (0)