Skip to content

Commit

Permalink
Swift - UniFFI boundary - update into_custom and from_custom espe…
Browse files Browse the repository at this point in the history
…cially for date. (#153)

Swift - change UniFFI into_custom and from_custom to use ISO8601DateFormatter.
  • Loading branch information
CyonAlexRDX authored May 31, 2024
1 parent e9a5edd commit 2743c0a
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 20 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sargon"
version = "1.0.6"
version = "1.0.7"
edition = "2021"
build = "build.rs"

Expand Down
74 changes: 74 additions & 0 deletions apple/Tests/TestCases/Prelude/DateTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import CustomDump
import Foundation
import Sargon
import SargonUniFFI
import XCTest

final class DateTests: TestCase {

func test_date() {

/// This matches `[bindings.swift.custom_types.Timestamp]`
/// inside `uniffi.toml` with the only difference that we use `$0` here but
/// the toml uses `{}`;
let into_custom: (String) -> Date = {
let stringToDeserialize = $0
let formatter = ISO8601DateFormatter()
let formatOptionMS = ISO8601DateFormatter.Options.withFractionalSeconds
formatter.formatOptions.insert(formatOptionMS)

func format() -> Date? {
formatter.date(from: stringToDeserialize)
}

if let date = format() {
return date
}

// try without fractional seconds
formatter.formatOptions.remove(formatOptionMS)
return format()!
}

/// This matches `[bindings.swift.custom_types.Timestamp]`
/// inside `uniffi.toml`
let from_custom: (Date) -> String = {
let dateToSerialize = $0
let formatter = ISO8601DateFormatter()
formatter.formatOptions.insert(.withFractionalSeconds)
return formatter.string(from: dateToSerialize)
}

func testIntoThenFrom(_ vector: (String, String?)) {
let sut = vector.0
let expected = vector.1 ?? sut

let string = from_custom(into_custom(sut))

XCTAssertEqual(string, expected)
}

func testFromThenInto(_ vector: (String, String?)) {
let lhs = vector.0
let rhs = vector.1 ?? lhs

let lhsString = from_custom(into_custom(lhs))
let rhsString = from_custom(into_custom(rhs))

XCTAssertEqual(rhsString, rhs)

XCTAssertEqual(
into_custom(lhsString),
into_custom(rhsString)
)
}

let vectors = [
("2023-12-24T17:13:56.123456Z", "2023-12-24T17:13:56.123Z"), // precision lost (which is OK)
("2023-12-24T17:13:56.123Z", nil), // unchanged
("2023-12-24T17:13:56Z", "2023-12-24T17:13:56.000Z") // (000 added, which is OK)
]
vectors.forEach(testIntoThenFrom)
vectors.forEach(testFromThenInto)
}
}
17 changes: 1 addition & 16 deletions apple/Tests/TestCases/Profile/DeviceInfoTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,21 +76,6 @@ final class DeviceInfoTests: Test<DeviceInfo> {
}
""", expected: nil)
}


}

extension JSONEncoder {
static var iso8601: JSONEncoder {
let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .iso8601
return encoder
}
}

extension JSONDecoder {
static var iso8601: JSONDecoder {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
return decoder
}
}
24 changes: 24 additions & 0 deletions apple/Tests/Utils/Extensions/JSON+ISO8601.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// File.swift
//
//
// Created by Alexander Cyon on 2024-05-31.
//

import Foundation

extension JSONEncoder {
static var iso8601: JSONEncoder {
let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .iso8601
return encoder
}
}

extension JSONDecoder {
static var iso8601: JSONDecoder {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
return decoder
}
}
30 changes: 28 additions & 2 deletions uniffi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,34 @@ from_custom = "{}.toString()"
[bindings.swift.custom_types.Timestamp]
type_name = "Date"
imports = ["Foundation"]
into_custom = "{let df = DateFormatter();df.dateFormat = \"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ\";return df.date(from: {})!}()"
from_custom = "{let df = DateFormatter();df.dateFormat = \"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ\";return df.string(from: {})}()"
into_custom = """
{
let stringToDeserialize = {} // this is UniFFIs counterpart to `$0`
let formatter = ISO8601DateFormatter()
let formatOptionMS = ISO8601DateFormatter.Options.withFractionalSeconds
formatter.formatOptions.insert(formatOptionMS)
func format() -> Date? {
formatter.date(from: stringToDeserialize)
}
if let date = format() {
return date
}
// try without fractional seconds
formatter.formatOptions.remove(formatOptionMS)
return format()!
}()
"""
from_custom = """
{
let dateToSerialize = {} // this is UniFFIs counterpart to `$0`
let formatter = ISO8601DateFormatter()
formatter.formatOptions.insert(.withFractionalSeconds)
return formatter.string(from: dateToSerialize)
}()
"""

[bindings.kotlin.custom_types.Timestamp]
type_name = "OffsetDateTime"
Expand Down

0 comments on commit 2743c0a

Please sign in to comment.