Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DRY Networking mapping code with generices #10808

Draft
wants to merge 48 commits into
base: trunk
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
eb89a14
Define generic `Envelope` type to DRY some network mapping
mokagio Sep 28, 2023
081b86d
Replace various custom `-Envelope` with generic `Envelope`
mokagio Sep 28, 2023
afad0ec
DRY `ModifiedEntity` assignment logic during mapping
mokagio Sep 28, 2023
c44de26
Replace more custom `-Envelope`s with generic `Envelope`
mokagio Sep 28, 2023
57e13a9
Add utility to DRY extracting data from generic `Envelope`
mokagio Sep 28, 2023
73df407
Allow injecting `siteID` in `Mapper` extraction
mokagio Sep 28, 2023
7c07de7
Replace `ProductTagListBatchCreateEnvelope` with matching `Envelope`
mokagio Sep 28, 2023
eed1538
Replace `ProductTagListBatchDeleteEnvelope` with matching `Envelope`
mokagio Sep 28, 2023
9423466
Replace `ProductsReportEnvelope` with matching `Envelope`
mokagio Sep 28, 2023
c599a80
Replace `RefundEnvelope` with `Envelope<Refund>`
mokagio Sep 28, 2023
0576b1c
Replace `ShipmentTrackingListEnvelope` with matching `Envelope`
mokagio Sep 28, 2023
e66c3f2
Replace `ShipmentTrackingProviderListEnvelope` with `Envelope`
mokagio Sep 28, 2023
c1c15c7
Replace `SubscriptionListEnvelope` with `Envelope<SuccessResponse>`
mokagio Sep 28, 2023
adf0445
Replace `ProductsContainerEnvelope` with `Envelope<ProductsContainer>`
mokagio Sep 28, 2023
507da39
Replace `ProductSkuEnvelope` with generic `Envelope`
mokagio Sep 28, 2023
23e9855
Replace `ShippingLabelRefundResponse` with generic `Envelope`
mokagio Sep 28, 2023
74531a6
Replace `ProductVariationsContainerEnvelope` with generic `Envelope`
mokagio Sep 28, 2023
12f0eba
Replace `WCPayNullAccountEnvelope` with `Envelope<[String]>`
mokagio Sep 28, 2023
4f716cd
Replace various `Mapper`s with `typealias`
mokagio Sep 28, 2023
974ac9e
Replace `ProductTypeTotalListEnvelope` with `Envelope`
mokagio Sep 28, 2023
7fc9dc1
Replace `StoreOnboardingTaskListMapper` with generic `Envelope`
mokagio Sep 28, 2023
791474b
Replace `SystemStatusEnvelope` with generic `Envelope`
mokagio Sep 28, 2023
d1ff119
Replace `ShippingLabelPurchaseResponse` with generic `Envelope`
mokagio Sep 28, 2023
9b79116
Replace `ShippingLabelDataEnvelope` with generic `Envelope`
mokagio Sep 28, 2023
195cbff
Replace `ShippingLabelPurchaseResponse` with generic `Envelope`
mokagio Sep 28, 2023
d1ce8b4
Replace `ShippingLabelAccountSettingsMapperEnvelope`
mokagio Sep 28, 2023
a7677f2
Replace `ProductVariationsContainerEnvelope` with generic `Envelope`
mokagio Sep 28, 2023
874e4f4
Replace `ShippingLabelAddressValidationResponseEnvelope` with generic
mokagio Sep 28, 2023
c444329
Replace `ReaderConnectionTokenMapper` with `extract(from:decoder:)`
mokagio Sep 28, 2023
b7e7109
Replace `RemoteReaderLocationEnvelope` with `extract(from:decoder:)`
mokagio Sep 28, 2023
0a1384e
Replace `WCPayPaymentIntentEnvelope` with `extract(from:decoder:)`
mokagio Sep 28, 2023
59e3082
Replace `ProductIDEnvelope` with generic `Envelope`
mokagio Sep 28, 2023
bd7227a
Replace `EntityIDEnvelope` with generic `Envelope`
mokagio Sep 28, 2023
03e3d16
Replace `ContentEnvelope` with generic `Envelope`
mokagio Sep 28, 2023
a300283
Replace custom `AddOnGroupMapper` with generic `typealias`
mokagio Sep 28, 2023
07b0b74
Rewrite `CouponReportListMapper` to use `extract(from:decoder:)`
mokagio Sep 29, 2023
ca797ad
Rewrite `CountryListMapper` to use `extract(from:,decoder:)`
mokagio Sep 29, 2023
9f8cc4d
Replace `DataBool` in favor of generic `Envelope`
mokagio Sep 29, 2023
3df38ea
Remove a couple of unnecessary `import Foundation`
mokagio Sep 29, 2023
befb4c6
Sort `Networking/Networking/Mapper` group alphabetically
mokagio Sep 29, 2023
edeae8c
Make `Mapper` default to `JSONDecoder` to decode data
mokagio Sep 29, 2023
25c807c
Rename `usingJSONDecoderSiteID` to `siteID` in `extract` method
mokagio Sep 29, 2023
e5f8678
Add `Mapper` `extract` method that takes `userInfo` as input
mokagio Sep 29, 2023
a583176
Cleanup some of the `Mapper`s that read a site id property
mokagio Sep 29, 2023
9d5706e
Remove a redundant inlined function call
mokagio Sep 29, 2023
501f106
fixup! Cleanup some of the `Mapper`s that read a site id property
mokagio Sep 29, 2023
c17df0c
Rename `GenericMapper` to `SiteIDMapper`
mokagio Sep 29, 2023
d7ba948
Rewrite more custom `Mapper`s to be generic `typealias`es
mokagio Sep 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 55 additions & 55 deletions Networking/Networking.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 53;
objectVersion = 54;
objects = {

/* Begin PBXBuildFile section */
Expand Down Expand Up @@ -2887,113 +2887,113 @@
B567AF2720A0FA0A00AB6C62 /* Mapper */ = {
isa = PBXGroup;
children = (
EE57C10F297927A000BC31E7 /* ApplicationPassword */,
B567AF2820A0FA1E00AB6C62 /* Mapper.swift */,
B505F6CC20BEE37E00BB1B69 /* AccountMapper.swift */,
93D8BBFC226BBEE800AD2EB3 /* AccountSettingsMapper.swift */,
2685C0F9263B5D5300D9EE97 /* AddOnGroupMapper.swift */,
EE839C252ABEF9C900049545 /* AIProductMapper.swift */,
DE4D23BB29B5FC0D003A4B5D /* AnnouncementListMapper.swift */,
EE57C10F297927A000BC31E7 /* ApplicationPassword */,
740211E221939C83002248DA /* CommentResultMapper.swift */,
45150A9D26836A57006922EA /* CountryListMapper.swift */,
03DCB73F2624AD7D00C8953D /* CouponListMapper.swift */,
03DCB785262739D200C8953D /* CouponMapper.swift */,
DE2095BE279583A100171F1C /* CouponReportListMapper.swift */,
45150A9D26836A57006922EA /* CountryListMapper.swift */,
68CB800D28D8901B00E169F8 /* CustomerMapper.swift */,
035BA3A929113CBD0056F0AD /* DataBoolMapper.swift */,
B524193E21AC5FE400D6FC0A /* DotcomDeviceMapper.swift */,
CE865A9C2A41E1480049B03C /* EntityDateModifiedMapper.swift */,
2676F4CD290AE6BB00C7A15B /* EntityIDMapper.swift */,
DE50295C28C6068B00551736 /* JetpackUserMapper.swift */,
AEF9458A27297FF6001DCCFB /* IgnoringResponseMapper.swift */,
E18152BF28F85D4A0011A0EC /* InAppPurchasesProductMapper.swift */,
E16C59B428F8640B007D55BB /* InAppPurchaseOrderResultMapper.swift */,
E18152BF28F85D4A0011A0EC /* InAppPurchasesProductMapper.swift */,
6846B0142A619A5C008EB143 /* InAppPurchasesTransactionMapper.swift */,
4513382327A951B300AE5E78 /* InboxNoteMapper.swift */,
45CCFCE527A2E3710012E8CB /* InboxNoteListMapper.swift */,
4513382327A951B300AE5E78 /* InboxNoteMapper.swift */,
DE34051828BDEE6A00CF0D97 /* JetpackConnectionURLMapper.swift */,
DE50295C28C6068B00551736 /* JetpackUserMapper.swift */,
036563DC29069BE400D84BFD /* JustInTimeMessageListMapper.swift */,
B567AF2820A0FA1E00AB6C62 /* Mapper.swift */,
020D07BD23D8570800FD9580 /* MediaListMapper.swift */,
D823D904223746CE00C90817 /* NewShipmentTrackingMapper.swift */,
B554FA8E2180BC7000C54DFF /* NoteHashListMapper.swift */,
B59325CB217E2B4C000B0E8E /* NoteListMapper.swift */,
B5C6FCD320A373BA00A4F8E4 /* OrderMapper.swift */,
B567AF2A20A0FA4200AB6C62 /* OrderListMapper.swift */,
74C8F06720EEB7BC00B6EDC9 /* OrderNotesMapper.swift */,
B5C6FCD320A373BA00A4F8E4 /* OrderMapper.swift */,
CE583A0D2109154500D73C1C /* OrderNoteMapper.swift */,
74C8F06720EEB7BC00B6EDC9 /* OrderNotesMapper.swift */,
02C254B825637BA000A04423 /* OrderShippingLabelListMapper.swift */,
D8FBFF1022D3B3FC006E3336 /* OrderStatsV4Mapper.swift */,
26731336255ACA850026F7EF /* PaymentGatewayListMapper.swift */,
0313651828AE559D00EEE571 /* PaymentGatewayMapper.swift */,
74749B96224134FF005C4CF2 /* ProductMapper.swift */,
AE1950F2296DB2C2004D37D2 /* ProductsBulkUpdateMapper.swift */,
45152810257A81730076B03C /* ProductAttributeMapper.swift */,
453305E82459DF2100264E50 /* PostMapper.swift */,
4515280C257A7EEC0076B03C /* ProductAttributeListMapper.swift */,
26B6453F259BCDFE00EF3FB3 /* ProductAttributeTermMapper.swift */,
45152810257A81730076B03C /* ProductAttributeMapper.swift */,
26B64543259BCE0F00EF3FB3 /* ProductAttributeTermListMapper.swift */,
26B6453F259BCDFE00EF3FB3 /* ProductAttributeTermMapper.swift */,
26615474242D7C9500A31661 /* ProductCategoryListMapper.swift */,
45B204B72489095100FE6526 /* ProductCategoryMapper.swift */,
CCF434632906BD7200B4475A /* ProductIDMapper.swift */,
CE0A0F18223987DF0075ED8D /* ProductListMapper.swift */,
45B204B72489095100FE6526 /* ProductCategoryMapper.swift */,
26615474242D7C9500A31661 /* ProductCategoryListMapper.swift */,
74749B96224134FF005C4CF2 /* ProductMapper.swift */,
D88D5A4A230BCF0A007B6E01 /* ProductReviewListMapper.swift */,
D8C251CF230BD72700F49782 /* ProductReviewMapper.swift */,
4599FC5724A624BD0056157A /* ProductTagListMapper.swift */,
0219B03823964BB3007DCD5E /* ProductShippingClassMapper.swift */,
AE1950F2296DB2C2004D37D2 /* ProductsBulkUpdateMapper.swift */,
025CA2C1238EBBAA00B05C81 /* ProductShippingClassListMapper.swift */,
0219B03823964BB3007DCD5E /* ProductShippingClassMapper.swift */,
45D685F723D0BC78005F87D0 /* ProductSkuMapper.swift */,
CE71E2302A4C3DDA00DB5376 /* ProductsReportMapper.swift */,
CE430673234BA6AD0073CBFF /* RefundMapper.swift */,
020EF5E82A8BC957009D2169 /* ProductsTotalMapper.swift */,
4599FC5724A624BD0056157A /* ProductTagListMapper.swift */,
026CF61D237D6985009563D4 /* ProductVariationListMapper.swift */,
02C1CEF324C6A02B00703EBA /* ProductVariationMapper.swift */,
26BD9FCE2965EE71004E0D15 /* ProductVariationsBulkCreateMapper.swift */,
09EA564A27C75FCE00407D40 /* ProductVariationsBulkUpdateMapper.swift */,
D8EDFE2525EE8A60003D2213 /* ReaderConnectionTokenMapper.swift */,
CE430675234BA7920073CBFF /* RefundListMapper.swift */,
CE430673234BA6AD0073CBFF /* RefundMapper.swift */,
31054701262E04F700C5C02B /* RemotePaymentIntentMapper.swift */,
3178A49E2703E5CF00A8B4CA /* RemoteReaderLocationMapper.swift */,
7412A8EB21B6E286005D182A /* ReportOrderTotalsMapper.swift */,
743E84ED2217244C00FAC9D7 /* ShipmentTrackingListMapper.swift */,
D823D91122377DF200C90817 /* ShipmentTrackingProviderListMapper.swift */,
CCF48B272628A4EB0034EA83 /* ShippingLabelAccountSettingsMapper.swift */,
45A4B84D25D2E11300776FB4 /* ShippingLabelAddressValidationSuccessMapper.swift */,
456930AA264EB85A009ED69D /* ShippingLabelCarriersAndRatesMapper.swift */,
CC9A24F32642CF37005DE56E /* ShippingLabelCreationEligibilityMapper.swift */,
451A9831260B9D2D0059D135 /* ShippingLabelPackagesMapper.swift */,
029BA53A255DFABD006171FD /* ShippingLabelPrintDataMapper.swift */,
CC0786602677B2DA00BA9AC1 /* ShippingLabelPurchaseMapper.swift */,
021A84D9257DF92800BC71D1 /* ShippingLabelRefundMapper.swift */,
CC0786C4267BAF0F00BA9AC1 /* ShippingLabelStatusMapper.swift */,
7426CA1021AF30BD004E9FFC /* SiteAPIMapper.swift */,
B56C1EB520EA757B00D749F9 /* SiteListMapper.swift */,
CE50345D21B571A7007573C6 /* SitePlanMapper.swift */,
453305E82459DF2100264E50 /* PostMapper.swift */,
31D27C8626028CE9002EDB1D /* SitePluginsMapper.swift */,
DEC51A94274CDA52009F3DF4 /* SitePluginMapper.swift */,
74046E1E217A6B70007DD7BF /* SiteSettingsMapper.swift */,
31D27C8626028CE9002EDB1D /* SitePluginsMapper.swift */,
DE74F29927E08F5A0002FE59 /* SiteSettingMapper.swift */,
CE12AE9629F2AB3F0056DD17 /* SubscriptionMapper.swift */,
CCE5F38C29EFFBC400087332 /* SubscriptionListMapper.swift */,
B53EF53B21814900003E146F /* SuccessResultMapper.swift */,
74A1D26C21189DFE00931DFA /* SiteVisitStatsMapper.swift */,
74046E1E217A6B70007DD7BF /* SiteSettingsMapper.swift */,
CCA1D60529437D8F00B40560 /* SiteSummaryStatsMapper.swift */,
74A1D26C21189DFE00931DFA /* SiteVisitStatsMapper.swift */,
EE2C09C129AF26B2009396F9 /* StoreOnboardingTaskListMapper.swift */,
311D412D2783C07D00052F64 /* StripeAccountMapper.swift */,
CCE5F38C29EFFBC400087332 /* SubscriptionListMapper.swift */,
CE12AE9629F2AB3F0056DD17 /* SubscriptionMapper.swift */,
CCB2CA9D262091CB00285CA0 /* SuccessDataResultMapper.swift */,
B53EF53B21814900003E146F /* SuccessResultMapper.swift */,
DEC51AE827687AAF009F3DF4 /* SystemPluginMapper.swift */,
077F39D326A58DE700ABEADC /* SystemStatusMapper.swift */,
450106902399B2C800E24722 /* TaxClassListMapper.swift */,
B9DFE4BD2AA2057B00174004 /* TaxRateListMapper.swift */,
B9CFF6512AB2118900C2F616 /* TaxRateMapper.swift */,
74ABA1D2213F25AE00FFAD30 /* TopEarnerStatsMapper.swift */,
026CF61D237D6985009563D4 /* ProductVariationListMapper.swift */,
02C1CEF324C6A02B00703EBA /* ProductVariationMapper.swift */,
09EA564A27C75FCE00407D40 /* ProductVariationsBulkUpdateMapper.swift */,
26BD9FCE2965EE71004E0D15 /* ProductVariationsBulkCreateMapper.swift */,
451A9831260B9D2D0059D135 /* ShippingLabelPackagesMapper.swift */,
029BA53A255DFABD006171FD /* ShippingLabelPrintDataMapper.swift */,
021A84D9257DF92800BC71D1 /* ShippingLabelRefundMapper.swift */,
311D412D2783C07D00052F64 /* StripeAccountMapper.swift */,
3192F21B260D32550067FEF9 /* WCPayAccountMapper.swift */,
D8EDFE2525EE8A60003D2213 /* ReaderConnectionTokenMapper.swift */,
3178A49E2703E5CF00A8B4CA /* RemoteReaderLocationMapper.swift */,
31054701262E04F700C5C02B /* RemotePaymentIntentMapper.swift */,
45A4B84D25D2E11300776FB4 /* ShippingLabelAddressValidationSuccessMapper.swift */,
CCF48B272628A4EB0034EA83 /* ShippingLabelAccountSettingsMapper.swift */,
456930AA264EB85A009ED69D /* ShippingLabelCarriersAndRatesMapper.swift */,
CC9A24F32642CF37005DE56E /* ShippingLabelCreationEligibilityMapper.swift */,
CC0786602677B2DA00BA9AC1 /* ShippingLabelPurchaseMapper.swift */,
CC0786C4267BAF0F00BA9AC1 /* ShippingLabelStatusMapper.swift */,
FE28F6E326842848004465C7 /* UserMapper.swift */,
077F39D326A58DE700ABEADC /* SystemStatusMapper.swift */,
DEC51AE827687AAF009F3DF4 /* SystemPluginMapper.swift */,
68F48B0C28E3B2E80045C15B /* WCAnalyticsCustomerMapper.swift */,
3192F21B260D32550067FEF9 /* WCPayAccountMapper.swift */,
0359EA1C27AADE000048DE2D /* WCPayChargeMapper.swift */,
02C11275274285FF00F4F0B4 /* WooCommerceAvailabilityMapper.swift */,
02BE0A7A274B695F001176D2 /* WordPressMediaMapper.swift */,
02C112772742862600F4F0B4 /* WordPressSiteSettingsMapper.swift */,
0359EA1C27AADE000048DE2D /* WCPayChargeMapper.swift */,
DE34051828BDEE6A00CF0D97 /* JetpackConnectionURLMapper.swift */,
68CB800D28D8901B00E169F8 /* CustomerMapper.swift */,
68F48B0C28E3B2E80045C15B /* WCAnalyticsCustomerMapper.swift */,
DE2E8E9E295310C5002E4B14 /* WordPressSiteMapper.swift */,
EE2C09C129AF26B2009396F9 /* StoreOnboardingTaskListMapper.swift */,
020EF5E82A8BC957009D2169 /* ProductsTotalMapper.swift */,
B9DFE4BD2AA2057B00174004 /* TaxRateListMapper.swift */,
B9CFF6512AB2118900C2F616 /* TaxRateMapper.swift */,
EE839C252ABEF9C900049545 /* AIProductMapper.swift */,
02C112772742862600F4F0B4 /* WordPressSiteSettingsMapper.swift */,
);
path = Mapper;
sourceTree = "<group>";
Expand Down
17 changes: 2 additions & 15 deletions Networking/Networking/Extensions/Mapper+DataEnvelope.swift
Original file line number Diff line number Diff line change
@@ -1,25 +1,12 @@
import Foundation

extension Mapper {

/// Checks whether the JSON data has a `data` key at the root.
///
func hasDataEnvelope(in response: Data) -> Bool {
let decoder = JSONDecoder()
do {
_ = try decoder.decode(ContentEnvelope.self, from: response)
_ = try JSONDecoder().decode(Envelope<AnyDecodable>.self, from: response)
return true
} catch {
return false
}
}
}

/// Helper struct to attempt parsing some JSON data with a `data` key at the root.
///
private struct ContentEnvelope: Decodable {
let content: AnyDecodable

private enum CodingKeys: String, CodingKey {
case content = "data"
}
}
3 changes: 0 additions & 3 deletions Networking/Networking/Mapper/AccountMapper.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import Foundation


/// Mapper: Account
///
class AccountMapper: Mapper {
Expand Down
3 changes: 0 additions & 3 deletions Networking/Networking/Mapper/AccountSettingsMapper.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import Foundation


/// Mapper: AccountSettings
///
struct AccountSettingsMapper: Mapper {
Expand Down
28 changes: 1 addition & 27 deletions Networking/Networking/Mapper/AddOnGroupMapper.swift
Original file line number Diff line number Diff line change
@@ -1,27 +1 @@
import Foundation

/// Maps between a raw json response to an array of `AddOnGroups`
///
struct AddOnGroupMapper: Mapper {
/// Site Identifier associated to the `AddOnGroup` that will be parsed.
/// We're injecting this field via `JSONDecoder.userInfo` because `SiteID` is not returned in any of the `AddOnGroup` endpoints.
///
let siteID: Int64

func map(response: Data) throws -> [AddOnGroup] {
let decoder = JSONDecoder()
decoder.userInfo = [.siteID: siteID]
if hasDataEnvelope(in: response) {
return try decoder.decode(AddOnGroupEnvelope.self, from: response).data
} else {
return try decoder.decode([AddOnGroup].self, from: response)
}
}
}

/// `AddOnGroupEnvelope` Disposable Entity:
/// `AddOnGroup` endpoints returns it's add-on-groups json in the `data` key.
///
private struct AddOnGroupEnvelope: Decodable {
let data: [AddOnGroup]
}
typealias AddOnGroupMapper = SiteIDMapper<[AddOnGroup]>
2 changes: 0 additions & 2 deletions Networking/Networking/Mapper/AnnouncementListMapper.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import Foundation

/// Mapper for `[Announcement]`
struct AnnouncementListMapper: Mapper {

Expand Down
4 changes: 0 additions & 4 deletions Networking/Networking/Mapper/CommentResultMapper.swift
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import Foundation


/// Mapper: Comment Moderation Result
///
struct CommentResultMapper: Mapper {

/// (Attempts) to extract the updated `status` field from a given JSON Encoded response.
///
func map(response: Data) throws -> CommentStatus {

let dictionary = try JSONDecoder().decode([String: AnyDecodable].self, from: response)
let status = (dictionary[Constants.statusKey]?.value as? String) ?? ""
return CommentStatus(rawValue: status) ?? .unknown
Expand Down
23 changes: 1 addition & 22 deletions Networking/Networking/Mapper/CountryListMapper.swift
Original file line number Diff line number Diff line change
@@ -1,29 +1,8 @@
import Foundation


/// Mapper: Country Collection
///
struct CountryListMapper: Mapper {

/// (Attempts) to convert an instance of Data into an array of Country Entities.
///
func map(response: Data) throws -> [Country] {
if hasDataEnvelope(in: response) {
return try JSONDecoder().decode(CountryListEnvelope.self, from: response).data
} else {
return try JSONDecoder().decode([Country].self, from: response)
}
}
}


/// CountryListEnvelope Disposable Entity:
/// This entity allows us to parse [Country] with JSONDecoder.
///
private struct CountryListEnvelope: Decodable {
let data: [Country]

private enum CodingKeys: String, CodingKey {
case data
try extract(from: response)
}
}
17 changes: 1 addition & 16 deletions Networking/Networking/Mapper/CouponListMapper.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import Foundation

/// Mapper: `Coupon` List
///
struct CouponListMapper: Mapper {
Expand All @@ -13,24 +11,11 @@ struct CouponListMapper: Mapper {
func map(response: Data) throws -> [Coupon] {
let decoder = Coupon.decoder
if hasDataEnvelope(in: response) {
let coupons = try decoder.decode(CouponListEnvelope.self, from: response).coupons
let coupons = try decoder.decode(Envelope<[Coupon]>.self, from: response).data
return coupons.map { $0.copy(siteID: siteID) }
} else {
return try decoder.decode([Coupon].self, from: response)
.map { $0.copy(siteID: siteID) }
}
}
}


/// CouponListEnvelope Disposable Entity:
/// Load All Coupons endpoint returns the coupons in the `data` key.
/// This entity allows us to parse all the things with JSONDecoder.
///
private struct CouponListEnvelope: Decodable {
let coupons: [Coupon]

private enum CodingKeys: String, CodingKey {
case coupons = "data"
}
}
17 changes: 1 addition & 16 deletions Networking/Networking/Mapper/CouponMapper.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import Foundation

/// Mapper: `Coupon`
///
struct CouponMapper: Mapper {
Expand All @@ -13,23 +11,10 @@ struct CouponMapper: Mapper {
func map(response: Data) throws -> Coupon {
let decoder = Coupon.decoder
if hasDataEnvelope(in: response) {
let coupon = try decoder.decode(CouponEnvelope.self, from: response).coupon
let coupon = try decoder.decode(Envelope<Coupon>.self, from: response).data
return coupon.copy(siteID: siteID)
} else {
return try decoder.decode(Coupon.self, from: response).copy(siteID: siteID)
}
}
}


/// CouponEnvelope Disposable Entity:
/// Load Coupon endpoint returns the coupon in the `data` key.
/// This entity allows us to parse all the things with JSONDecoder.
///
private struct CouponEnvelope: Decodable {
let coupon: Coupon

private enum CodingKeys: String, CodingKey {
case coupon = "data"
}
}
24 changes: 1 addition & 23 deletions Networking/Networking/Mapper/CouponReportListMapper.swift
Original file line number Diff line number Diff line change
@@ -1,30 +1,8 @@
import Foundation

/// Mapper: `CouponReport`
///
struct CouponReportListMapper: Mapper {

/// (Attempts) to convert a dictionary into `[CouponReport]`.
///
func map(response: Data) throws -> [CouponReport] {
let decoder = JSONDecoder()
if hasDataEnvelope(in: response) {
return try decoder.decode(CouponReportsEnvelope.self, from: response).reports
} else {
return try decoder.decode([CouponReport].self, from: response)
}
}
}


/// CouponReportsEnvelope Disposable Entity:
/// Load Coupon endpoint returns the coupon in the `data` key.
/// This entity allows us to parse all the things with JSONDecoder.
///
private struct CouponReportsEnvelope: Decodable {
let reports: [CouponReport]

private enum CodingKeys: String, CodingKey {
case reports = "data"
try extract(from: response)
}
}
Loading