Skip to content

Commit 325a6f8

Browse files
author
Dmitry Lobanov
committed
Deeplink: Encoding deeplink has been added.
1 parent fbf9291 commit 325a6f8

File tree

3 files changed

+132
-0
lines changed

3 files changed

+132
-0
lines changed

Sources/Deeplink/Deeplink.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ public enum Deeplink<Value>: Equatable, Hashable {
4545
case .interpolated(let interpolation): return interpolation
4646
}
4747
}
48+
49+
public func encode(
50+
_ value: Value
51+
) -> String {
52+
interpolation.encode(value)
53+
}
4854
}
4955

5056
// MARK: - ExpressibleByStringLiteral

Sources/Deeplink/DeeplinkInterpolation.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,17 @@ public struct DeeplinkInterpolation<Value>: Equatable, Hashable, StringInterpola
6969
case .argumentList: return "{{ argument list }}"
7070
}
7171
}
72+
73+
func encode(value: Value) -> String {
74+
switch self {
75+
case let .literal(v):
76+
return v
77+
case let .argument(v):
78+
return value[keyPath: v] ?? ""
79+
case let .argumentList(v, separator: character):
80+
return value[keyPath: v]?.joined(separator: String(character)) ?? ""
81+
}
82+
}
7283
}
7384

7485
// MARK: - Properties
@@ -206,6 +217,14 @@ public struct DeeplinkInterpolation<Value>: Equatable, Hashable, StringInterpola
206217
// Use the url data to pattern match the deeplink components.
207218
try data.match(components: self.components, into: &instance)
208219
}
220+
221+
func encode(
222+
_ value: Value
223+
) -> String {
224+
self.components.map({
225+
$0.encode(value: value)
226+
}).joined()
227+
}
209228
}
210229

211230
// MARK: - CustomStringConvertible
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
//
2+
// EncodingDeeplinkTests.swift
3+
//
4+
//
5+
// Created by Dmitry Lobanov on 28.01.2024.
6+
//
7+
8+
import Foundation
9+
import XCTest
10+
@testable import Deeplink
11+
12+
@MainActor
13+
class EncodingDeeplinkTests: XCTestCase {
14+
15+
struct Artist: Equatable {
16+
var id: String?
17+
var slug: String?
18+
}
19+
20+
struct Event: Equatable {
21+
var id: String?
22+
var slug: String?
23+
}
24+
25+
struct EventType: Equatable {
26+
var id: String?
27+
var slug: String?
28+
var event = Event()
29+
}
30+
31+
struct Search: Equatable {
32+
var query: String?
33+
}
34+
35+
struct CustomData: Equatable {
36+
var testData: Int?
37+
38+
var testDataString: String? {
39+
get { testData.map { "\($0)" } }
40+
set { testData = newValue.flatMap(Int.init) }
41+
}
42+
}
43+
44+
struct Restaurants: Equatable {
45+
var ids: [String]?
46+
}
47+
48+
func testEncoding_Artist() {
49+
let deeplink = try! "/artist/\(\.slug)/\(\.id)" as Deeplink<Artist>
50+
51+
let url = "/artist/123/1"
52+
53+
var object = Artist()
54+
object.slug = "123"
55+
object.id = "1"
56+
XCTAssertEqual(url, deeplink.encode(object))
57+
}
58+
59+
func testEncoding_EventType() {
60+
let deeplink = try! "/event/\(\.event.slug)/\(\.slug)/\(\.event.id)/\(\.id)" as Deeplink<EventType>
61+
62+
let url = "/event/food/restaurants/123/1"
63+
64+
var object = EventType()
65+
var event = Event()
66+
67+
event.slug = "food"
68+
object.slug = "restaurants"
69+
event.id = "123"
70+
object.id = "1"
71+
object.event = event
72+
73+
XCTAssertEqual(url, deeplink.encode(object))
74+
}
75+
76+
func testEncoding_Search() {
77+
let deeplink = try! "/search?query=\(\.query)" as Deeplink<Search>
78+
79+
let url = "/search?query=food"
80+
81+
var object = Search()
82+
object.query = "food"
83+
XCTAssertEqual(url, deeplink.encode(object))
84+
}
85+
86+
func testEncoding_CustomData() {
87+
let deeplink = try! "/test/\(\.testDataString)" as Deeplink<CustomData>
88+
89+
let url = "/test/123"
90+
91+
var object = CustomData()
92+
object.testData = 123
93+
94+
XCTAssertEqual(url, deeplink.encode(object))
95+
}
96+
97+
func testEncoding_Restaurants() {
98+
let deeplink = try! "/restaurants/ids=\(\.ids, separator: ",")" as Deeplink<Restaurants>
99+
100+
let url = "/restaurants/ids=123,456,789"
101+
102+
var object = Restaurants()
103+
object.ids = ["123", "456", "789"]
104+
105+
XCTAssertEqual(url, deeplink.encode(object))
106+
}
107+
}

0 commit comments

Comments
 (0)