mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-08-20 19:33:08 +09:00
98 lines
3.3 KiB
Swift
98 lines
3.3 KiB
Swift
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
import Shared
|
|
import SwiftyJSON
|
|
|
|
private let log = Logger.browserLogger
|
|
|
|
public typealias IdentifierString = String
|
|
public extension IdentifierString {
|
|
func validate() -> Bool {
|
|
// Regex located here: http://gecko.readthedocs.io/en/latest/toolkit/components/telemetry/telemetry/collection/events.html#limits
|
|
let regex = try! NSRegularExpression(pattern: "^[a-zA-Z][a-zA-Z0-9_.]*[a-zA-Z0-9]$", options: [])
|
|
return regex.matches(in: self, options: [], range: NSRange(location: 0, length: self.characters.count)).count > 0
|
|
}
|
|
}
|
|
|
|
// Telemetry Events
|
|
// Documentation: http://gecko.readthedocs.io/en/latest/toolkit/components/telemetry/telemetry/collection/events.html#events
|
|
public struct Event {
|
|
let timestamp: Timestamp
|
|
let category: IdentifierString
|
|
let method: IdentifierString
|
|
let object: IdentifierString
|
|
let value: String?
|
|
let extra: [String: String]?
|
|
|
|
public init(category: IdentifierString,
|
|
method: IdentifierString,
|
|
object: IdentifierString,
|
|
value: String? = nil,
|
|
extra: [String: String]? = nil) {
|
|
|
|
self.init(timestamp: .uptimeInMilliseconds(),
|
|
category: category,
|
|
method: method,
|
|
object: object,
|
|
value: value,
|
|
extra: extra)
|
|
}
|
|
|
|
init(timestamp: Timestamp,
|
|
category: IdentifierString,
|
|
method: IdentifierString,
|
|
object: IdentifierString,
|
|
value: String? = nil,
|
|
extra: [String: String]? = nil) {
|
|
self.timestamp = timestamp
|
|
self.category = category
|
|
self.method = method
|
|
self.object = object
|
|
self.value = value
|
|
self.extra = extra
|
|
}
|
|
|
|
public func validate() -> Bool {
|
|
let results = [category, method, object].map { $0.validate() }
|
|
// Fold down the results into false if any of the results is false.
|
|
return results.reduce(true) { $0 ? $1 :$0 }
|
|
}
|
|
|
|
public func pickle() -> Data? {
|
|
do {
|
|
return try JSONSerialization.data(withJSONObject: toArray(), options: [])
|
|
} catch let error {
|
|
log.error("Error pickling telemetry event. Error: \(error), Event: \(self)")
|
|
return nil
|
|
}
|
|
}
|
|
|
|
public static func unpickle(_ data: Data) -> Event? {
|
|
do {
|
|
let array = try JSONSerialization.jsonObject(with: data, options: []) as! [Any]
|
|
return Event(
|
|
timestamp: Timestamp(array[0] as! UInt64),
|
|
category: array[1] as! String,
|
|
method: array[2] as! String,
|
|
object: array[3] as! String,
|
|
value: array[4] as? String,
|
|
extra: array[5] as? [String: String]
|
|
)
|
|
} catch let error {
|
|
log.error("Error unpickling telemetry event: \(error)")
|
|
return nil
|
|
}
|
|
}
|
|
|
|
public func toArray() -> [Any] {
|
|
return [timestamp, category, method, object, value ?? NSNull(), extra ?? NSNull()]
|
|
}
|
|
}
|
|
|
|
extension Event: CustomDebugStringConvertible {
|
|
public var debugDescription: String {
|
|
return toArray().description
|
|
}
|
|
}
|