forked from vapor/postgres-kit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPostgreSQLData+Point.swift
65 lines (57 loc) · 2.18 KB
/
PostgreSQLData+Point.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import Foundation
/// A 2-dimenstional (double[2]) point.
public struct PostgreSQLPoint {
/// The point's x coordinate.
var x: Double
/// The point's y coordinate.
var y: Double
/// Create a new `Point`
public init(x: Double, y: Double) {
self.x = x
self.y = y
}
}
extension PostgreSQLPoint: CustomStringConvertible {
/// See `CustomStringConvertible.description`
public var description: String {
return "(\(x),\(y))"
}
}
extension PostgreSQLPoint: Equatable {
/// See `Equatable.==`
public static func ==(lhs: PostgreSQLPoint, rhs: PostgreSQLPoint) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y
}
}
extension PostgreSQLPoint: PostgreSQLDataCustomConvertible {
/// See `PostgreSQLDataCustomConvertible.preferredDataType`
public static var preferredDataType: PostgreSQLDataType? { return .point }
/// See `PostgreSQLDataCustomConvertible.convertFromPostgreSQLData(_:)`
public static func convertFromPostgreSQLData(_ data: PostgreSQLData) throws -> PostgreSQLPoint {
guard let value = data.data else {
throw PostgreSQLError(identifier: "data", reason: "Could not decode Point from `null` data.")
}
switch data.type {
case .point:
switch data.format {
case .text:
let string = try value.makeString()
let parts = string.split(separator: ",")
var x = parts[0]
var y = parts[1]
assert(x.popFirst()! == "(")
assert(y.popLast()! == ")")
return .init(x: Double(x)!, y: Double(y)!)
case .binary:
let x = value[0..<8]
let y = value[8..<16]
return .init(x: x.makeFloatingPoint(), y: y.makeFloatingPoint())
}
default: throw PostgreSQLError(identifier: "point", reason: "Could not decode Point from data type: \(data.type)")
}
}
/// See `PostgreSQLDataCustomConvertible.convertToPostgreSQLData()`
public func convertToPostgreSQLData() throws -> PostgreSQLData {
return PostgreSQLData(type: .point, format: .binary, data: x.data + y.data)
}
}