Files
kontakte/Kontakte/ContactMetadataDSL.swift

72 lines
2.0 KiB
Swift

import Foundation
struct ContactMetadata {
var isFavorite: Bool = false
var isMyCard: Bool = false
var hasAnyValue: Bool {
isFavorite || isMyCard
}
}
enum ContactMetadataDSL {
private static let startMarker = "[[kontakte]]"
private static let endMarker = "[[/kontakte]]"
static func parse(note: String) -> ContactMetadata {
guard let range = metadataBlockRange(in: note) else {
return ContactMetadata()
}
let block = note[range]
var metadata = ContactMetadata()
for rawLine in block.components(separatedBy: .newlines) {
let line = rawLine.trimmingCharacters(in: .whitespacesAndNewlines)
if line == "favorite=1" {
metadata.isFavorite = true
} else if line == "my_card=1" {
metadata.isMyCard = true
}
}
return metadata
}
static func updating(note: String, metadata: ContactMetadata) -> String {
var base = note
if let range = metadataBlockRange(in: note) {
base.removeSubrange(range)
}
base = base.trimmingCharacters(in: .whitespacesAndNewlines)
guard metadata.hasAnyValue else {
return base
}
var lines: [String] = []
lines.append(startMarker)
if metadata.isFavorite {
lines.append("favorite=1")
}
if metadata.isMyCard {
lines.append("my_card=1")
}
lines.append(endMarker)
let block = lines.joined(separator: "\n")
if base.isEmpty {
return block
}
return base + "\n\n" + block
}
private static func metadataBlockRange(in note: String) -> Range<String.Index>? {
guard let start = note.range(of: startMarker),
let end = note.range(of: endMarker, range: start.upperBound..<note.endIndex) else {
return nil
}
return start.lowerBound..<end.upperBound
}
}