Skip to content

Commit

Permalink
Unblocks nonmutating set on $TCDateWrappers (#55)
Browse files Browse the repository at this point in the history
* Adds dependency on `NIOConcurrencyHelpers` to `TecoDateHelpers`

* Uses `NIOLockedValueBox` to allow nonmutating set on `$dateWrapper`s

* Simplifies `private` member naming for `TCDateWrapper`s
  • Loading branch information
stevapple authored Oct 18, 2023
1 parent 6fddf6f commit 3b8b2a5
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 41 deletions.
3 changes: 2 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ let package = Package(
]),
.target(name: "TecoPaginationHelpers",
dependencies: ["TecoCore"]),
.target(name: "TecoDateHelpers"),
.target(name: "TecoDateHelpers",
dependencies: [.product(name: "NIOConcurrencyHelpers", package: "swift-nio")]),
.target(name: "INIParser"),
.target(
name: "TecoSigner",
Expand Down
3 changes: 2 additions & 1 deletion Package@swift-5.5.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ let package = Package(
]),
.target(name: "TecoPaginationHelpers",
dependencies: ["TecoCore"]),
.target(name: "TecoDateHelpers"),
.target(name: "TecoDateHelpers",
dependencies: [.product(name: "NIOConcurrencyHelpers", package: "swift-nio")]),
.target(name: "INIParser"),
.target(
name: "TecoSigner",
Expand Down
3 changes: 2 additions & 1 deletion Package@swift-5.6.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ let package = Package(
]),
.target(name: "TecoPaginationHelpers",
dependencies: ["TecoCore"]),
.target(name: "TecoDateHelpers"),
.target(name: "TecoDateHelpers",
dependencies: [.product(name: "NIOConcurrencyHelpers", package: "swift-nio")]),
.target(name: "INIParser"),
.target(
name: "TecoSigner",
Expand Down
26 changes: 16 additions & 10 deletions Sources/TecoDateHelpers/Property Wrappers/TCDateEncoding.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,35 +18,41 @@ import struct Foundation.Date
import struct Foundation.Locale
import struct Foundation.TimeZone
import class Foundation.DateFormatter
@_implementationOnly import struct NIOConcurrencyHelpers.NIOLockedValueBox

@propertyWrapper
public struct TCDateEncoding<WrappedValue: TCDateValue>: Codable {
public var wrappedValue: WrappedValue {
self._dateValue
self.date
}

public var projectedValue: StorageValue {
get {
self._stringValue
self.string.withLockedValue {
$0
}
}
set {
self._stringValue = newValue
nonmutating set {
self.string.withLockedValue {
$0 = newValue
}
}
}

private var _dateValue: WrappedValue
private let date: WrappedValue

private var _stringValue: StorageValue
private let string: NIOLockedValueBox<StorageValue>

public init(wrappedValue: WrappedValue) {
self._dateValue = wrappedValue
self._stringValue = wrappedValue.encode(formatter: Self._formatter)
self.date = wrappedValue
self.string = NIOLockedValueBox(wrappedValue.encode(formatter: Self._formatter))
}

public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
self._stringValue = try container.decode(StorageValue.self)
self._dateValue = try WrappedValue.decode(from: self._stringValue, formatter: Self._formatter, container: container, wrapper: Self.self)
let dateString = try container.decode(StorageValue.self)
self.date = try WrappedValue.decode(from: dateString, formatter: Self._formatter, container: container, wrapper: Self.self)
self.string = NIOLockedValueBox(dateString)
}
}

Expand Down
26 changes: 16 additions & 10 deletions Sources/TecoDateHelpers/Property Wrappers/TCTimestampEncoding.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,35 +18,41 @@ import struct Foundation.Date
import struct Foundation.Locale
import struct Foundation.TimeZone
import class Foundation.DateFormatter
@_implementationOnly import struct NIOConcurrencyHelpers.NIOLockedValueBox

@propertyWrapper
public struct TCTimestampEncoding<WrappedValue: TCDateValue>: Codable {
public var wrappedValue: WrappedValue {
self._dateValue
self.date
}

public var projectedValue: StorageValue {
get {
self._stringValue
self.string.withLockedValue {
$0
}
}
set {
self._stringValue = newValue
nonmutating set {
self.string.withLockedValue {
$0 = newValue
}
}
}

private var _dateValue: WrappedValue
private let date: WrappedValue

private var _stringValue: StorageValue
private let string: NIOLockedValueBox<StorageValue>

public init(wrappedValue: WrappedValue) {
self._dateValue = wrappedValue
self._stringValue = wrappedValue.encode(formatter: Self._formatter)
self.date = wrappedValue
self.string = NIOLockedValueBox(wrappedValue.encode(formatter: Self._formatter))
}

public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
self._stringValue = try container.decode(StorageValue.self)
self._dateValue = try WrappedValue.decode(from: self._stringValue, formatter: Self._formatter, container: container, wrapper: Self.self)
let dateString = try container.decode(StorageValue.self)
self.date = try WrappedValue.decode(from: dateString, formatter: Self._formatter, container: container, wrapper: Self.self)
self.string = NIOLockedValueBox(dateString)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,35 +16,41 @@

import struct Foundation.Date
import class Foundation.ISO8601DateFormatter
@_implementationOnly import struct NIOConcurrencyHelpers.NIOLockedValueBox

@propertyWrapper
public struct TCTimestampISO8601Encoding<WrappedValue: TCDateValue>: Codable {
public var wrappedValue: WrappedValue {
self._dateValue
self.date
}

public var projectedValue: StorageValue {
get {
self._stringValue
self.string.withLockedValue {
$0
}
}
set {
self._stringValue = newValue
nonmutating set {
self.string.withLockedValue {
$0 = newValue
}
}
}

private var _dateValue: WrappedValue
private let date: WrappedValue

private var _stringValue: StorageValue
private let string: NIOLockedValueBox<StorageValue>

public init(wrappedValue: WrappedValue) {
self._dateValue = wrappedValue
self._stringValue = wrappedValue.encode(formatter: Self._formatter)
self.date = wrappedValue
self.string = NIOLockedValueBox(wrappedValue.encode(formatter: Self._formatter))
}

public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
self._stringValue = try container.decode(StorageValue.self)
self._dateValue = try WrappedValue.decode(from: self._stringValue, formatter: Self._formatter, container: container, wrapper: Self.self)
let dateString = try container.decode(StorageValue.self)
self.date = try WrappedValue.decode(from: dateString, formatter: Self._formatter, container: container, wrapper: Self.self)
self.string = NIOLockedValueBox(dateString)
}
}

Expand Down
14 changes: 7 additions & 7 deletions Sources/TecoDateHelpers/Protocols/TCDateValue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ extension Foundation.Date: TCDateValue {
formatter.string(from: self)
}

public static func decode<Wrapper: TCDateWrapper>(from stringValue: String, formatter: TCDateFormatter, container: SingleValueDecodingContainer, wrapper: Wrapper.Type = Wrapper.self) throws -> Date {
guard let date = formatter.date(from: stringValue) else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid \(wrapper._valueDescription): \(stringValue)")
public static func decode<Wrapper: TCDateWrapper>(from string: String, formatter: TCDateFormatter, container: SingleValueDecodingContainer, wrapper: Wrapper.Type = Wrapper.self) throws -> Date {
guard let date = formatter.date(from: string) else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid \(wrapper._valueDescription): \(string)")
}
return date
}
Expand All @@ -45,12 +45,12 @@ extension Swift.Optional: TCDateValue where Wrapped == Foundation.Date {
}
}

public static func decode<Wrapper: TCDateWrapper>(from stringValue: String?, formatter: TCDateFormatter, container: SingleValueDecodingContainer, wrapper: Wrapper.Type = Wrapper.self) throws -> Date? {
guard let stringValue = stringValue else {
public static func decode<Wrapper: TCDateWrapper>(from string: String?, formatter: TCDateFormatter, container: SingleValueDecodingContainer, wrapper: Wrapper.Type = Wrapper.self) throws -> Date? {
guard let string = string else {
return nil
}
guard let date = formatter.date(from: stringValue) else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid \(wrapper._valueDescription): \(stringValue)")
guard let date = formatter.date(from: string) else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid \(wrapper._valueDescription): \(string)")
}
return date
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/TecoDateHelpers/Protocols/TCDateWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public protocol TCDateWrapper: Codable, _TecoDateSendable {
associatedtype Formatter: TCDateFormatter

var wrappedValue: WrappedValue { get }
var projectedValue: StorageValue { get }
var projectedValue: StorageValue { get nonmutating set }

init(wrappedValue: WrappedValue)

Expand Down

0 comments on commit 3b8b2a5

Please sign in to comment.