Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 4 additions & 4 deletions Sources/Redis/Redis+Cache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ extension Application.Caches {
}

/// A cache configured for a given Redis ID and the default coders.
public func redis(_ id: RedisID) -> Cache {
self.redis(id, encoder: JSONEncoder(), decoder: JSONDecoder())
public func redis(_ id: RedisID, jsonEncoder: JSONEncoder = JSONEncoder(), jsonDecoder: JSONDecoder = JSONDecoder()) -> Cache {
self.redis(id, encoder: jsonEncoder, decoder: jsonDecoder)
}

/// A cache configured for a given Redis ID and using the provided encoder and decoder.
Expand All @@ -58,8 +58,8 @@ extension Application.Caches.Provider {
}

/// Configures the application cache to use the given Redis ID and the default coders.
public static func redis(_ id: RedisID) -> Self {
self.redis(id, encoder: JSONEncoder(), decoder: JSONDecoder())
public static func redis(_ id: RedisID, jsonEncoder: JSONEncoder = JSONEncoder(), jsonDecoder: JSONDecoder = JSONDecoder()) -> Self {
self.redis(id, encoder: jsonEncoder, decoder: jsonDecoder)
}

/// Configures the application cache to use the given Redis ID and the provided encoder and decoder.
Expand Down
12 changes: 6 additions & 6 deletions Sources/Redis/Redis+Concurrency.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,25 +56,25 @@ extension Application.Redis {

extension RedisClient {
/// Gets the provided key as a decodable type.
public func get<D>(_ key: RedisKey, asJSON type: D.Type) async throws -> D?
public func get<D>(_ key: RedisKey, asJSON type: D.Type, jsonDecoder: JSONDecoder = JSONDecoder()) async throws -> D?
where D: Decodable
{
let data = try await self.get(key, as: Data.self).get()
return try data.flatMap { try JSONDecoder().decode(D.self, from: $0) }
return try data.flatMap { try jsonDecoder.decode(D.self, from: $0) }
}

/// Sets key to an encodable item.
public func set<E>(_ key: RedisKey, toJSON entity: E) async throws
public func set<E>(_ key: RedisKey, toJSON entity: E, jsonEncoder: JSONEncoder = JSONEncoder()) async throws
where E: Encodable
{
try await self.set(key, to: JSONEncoder().encode(entity)).get()
try await self.set(key, to: jsonEncoder.encode(entity)).get()
}

/// Sets key to an encodable item with an expiration time.
public func setex<E>(_ key: RedisKey, toJSON entity: E, expirationInSeconds expiration: Int) async throws
public func setex<E>(_ key: RedisKey, toJSON entity: E, expirationInSeconds expiration: Int, jsonEncoder: JSONEncoder = JSONEncoder()) async throws
where E: Encodable
{
try await self.setex(key, to: JSONEncoder().encode(entity), expirationInSeconds: expiration).get()
try await self.setex(key, to: jsonEncoder.encode(entity), expirationInSeconds: expiration).get()
}
}

Expand Down
12 changes: 6 additions & 6 deletions Sources/Redis/RedisClient+Codable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,31 @@ import NIOCore

extension RedisClient {
/// Gets the provided key as a decodable type.
public func get<D>(_ key: RedisKey, asJSON type: D.Type) -> EventLoopFuture<D?>
public func get<D>(_ key: RedisKey, asJSON type: D.Type, jsonDecoder: JSONDecoder = JSONDecoder()) -> EventLoopFuture<D?>
where D: Decodable
{
return self.get(key, as: Data.self).flatMapThrowing { data in
return try data.flatMap { try JSONDecoder().decode(D.self, from: $0) }
return try data.flatMap { try jsonDecoder.decode(D.self, from: $0) }
}
}

/// Sets key to an encodable item.
public func set<E>(_ key: RedisKey, toJSON entity: E) -> EventLoopFuture<Void>
public func set<E>(_ key: RedisKey, toJSON entity: E, jsonEncoder: JSONEncoder = JSONEncoder()) -> EventLoopFuture<Void>
where E: Encodable
{
do {
return try self.set(key, to: JSONEncoder().encode(entity))
return try self.set(key, to: jsonEncoder.encode(entity))
} catch {
return self.eventLoop.makeFailedFuture(error)
}
}

/// Sets key to an encodable item with an expiration time.
public func setex<E>(_ key: RedisKey, toJSON entity: E, expirationInSeconds expiration: Int) -> EventLoopFuture<Void>
public func setex<E>(_ key: RedisKey, toJSON entity: E, expirationInSeconds expiration: Int, jsonEncoder: JSONEncoder = JSONEncoder()) -> EventLoopFuture<Void>
where E: Encodable
{
do {
return try self.setex(key, to: JSONEncoder().encode(entity), expirationInSeconds: expiration)
return try self.setex(key, to: jsonEncoder.encode(entity), expirationInSeconds: expiration)
} catch {
return self.eventLoop.makeFailedFuture(error)
}
Expand Down
23 changes: 23 additions & 0 deletions Tests/RedisTests/RedisTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,29 @@ extension RedisTests {
let value = try XCTUnwrap(app.cache.get("test", as: Date.self).wait())
XCTAssertEqual(value, date)
}

func testRedisClientCustomCoders() throws {
let app = Application()
defer { app.shutdown() }

let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .iso8601
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601

app.redis.configuration = redisConfig

try app.boot()

let date = Date(timeIntervalSince1970: 10_000_000_000)
let isoDate = ISO8601DateFormatter().string(from: date)

try app.redis.set("test", toJSON: date, jsonEncoder: encoder).wait()
let rawValue = try XCTUnwrap(app.redis.get("test", as: String.self).wait())
XCTAssertEqual(rawValue, #""\#(isoDate)""#)
let value = try XCTUnwrap(app.redis.get("test", asJSON: Date.self, jsonDecoder: decoder).wait())
XCTAssertEqual(value, date)
}
}

// MARK: Test Helpers
Expand Down