another.im-ios/AnotherXMPP/models/XMLElement.swift

99 lines
2.4 KiB
Swift
Raw Normal View History

2024-06-19 15:06:39 +00:00
import Foundation
2024-12-18 04:08:11 +00:00
public struct XMLElement: Codable, Equatable, CustomStringConvertible {
public let name: String
public let xmlns: String?
public let attributes: [String: String]
public let content: String?
public let nodes: [XMLElement]
public var woClose: Bool = false
2024-06-19 15:06:39 +00:00
2024-12-18 04:08:11 +00:00
public var stringRepresentation: String {
2024-06-19 15:06:39 +00:00
var result = "<\(name)"
for (key, value) in attributes {
let val = value.escaped
result += " \(key)='\(val)'"
}
if let xmlns {
result += " xmlns='\(xmlns)'"
}
if !nodes.isEmpty {
result += ">"
for child in nodes {
result += child.stringRepresentation
}
result += "</\(name)>"
} else {
if let content = content {
result += ">"
result += content
result += "</\(name)>"
} else {
result += woClose ? ">" : "/>"
}
}
return result
}
2024-12-18 04:08:11 +00:00
public var description: String {
2024-06-19 15:06:39 +00:00
stringRepresentation.prettyStr
}
var data: Data {
Data(stringRepresentation.utf8)
}
}
// I decided to not use mutation functions and just
// make a new element during update
extension XMLElement {
func updateXmlns(_ new: String?) -> XMLElement {
XMLElement(
name: name,
xmlns: new,
attributes: attributes,
content: content,
nodes: nodes,
woClose: woClose
)
}
func addNode(_ new: XMLElement) -> XMLElement {
var nodes = nodes
nodes.append(new)
return XMLElement(
name: name,
xmlns: xmlns,
attributes: attributes,
content: content,
nodes: nodes,
woClose: woClose
)
}
func updateContent(_ new: String?) -> XMLElement {
guard let new else { return self }
var content = self.content ?? ""
content += new
return XMLElement(
name: name,
xmlns: xmlns,
attributes: attributes,
content: content,
nodes: nodes,
woClose: woClose
)
}
}
//
extension XMLElement {
static var randomId: String {
let letters = "abcdefghijklmnopqrstuvwxyz0123456789"
return String((0 ..< 8).map { _ in letters.randomElement() ?? "x" })
}
}