Можно ли изменить интерполяцию строк Swift для псевдонима типа String?
В моем приложении много DTO, которые регистрируют какое-то поле. Это поле не должно быть зарегистрировано, потому что данные являются конфиденциальными. Модель выглядит так:
typealias HiddenFieldType = String
struct DTO1 {
var field1_1: String
var fieldToHide: HiddenFieldType
var field1_2: String
var field1_3: String
}
struct DTO2 {
var field2_1: String
var field2_2: String
var fieldToHide: HiddenFieldType
var field2_3: String
}
код, который выводит данные, такой (на самом деле этоos_log
в реальном приложении):
func test() {
let dto1 = DTO1(field1_1: "1_1", fieldToHide: "super-secret-1", field1_2: "1_2", field1_3: "1_3")
let dto2 = DTO2(field2_1: "2_1", field2_2: "2_2", fieldToHide: "super-secret-2", field2_3: "2_3")
print("Test1: dto1=\(dto1) dto2=\(dto2)")
}
Подход №1
Кажется, поле можно скрыть в DTO1 с помощью такого кода:
extension String.StringInterpolation {
mutating func appendInterpolation(_ value: DTO1) {
appendInterpolation("field1_1: \(value.field1_1), fieldToHide: ♀️, field1_2: \(value.field1_2), field1_3: \(value.field1_3)")
}
}
Однако решение нельзя ни масштабировать, ни поддерживать:
- одно и то же расширение должно быть добавлено для каждого DTO
- каждое поле должно быть включено в - много шаблонов
- если в какой-то DTO добавляется новое поле, мы можем забыть обновить и т. д.
Подход №2
Я попытался добавить интерполяцию для (при условии, что это тип, какDTO1
...):
extension String.StringInterpolation {
mutating func appendInterpolation(_ value: HiddenFieldType) {
appendInterpolation("♀️")
}
}
Но это решение вообще не работает:
- компилятор говорит: "Вызов функции вызывает бесконечную рекурсию"
- и это фактически вызывает бесконечную рекурсию
- при изменении
appendInterpolation
кappendLiteral
, рекурсии нет, но "суперсекрет-1" не скрыт
Подход №3
я пытался переопределитьDefaultStringInterpolation
, в соответствии сExpressibleByStringLiteral
/ExpressibleByStringInterpolation
, но это не работает: компилятор говорит, чтоString
, иConformance of 'String' to protocol 'ExpressibleByStringLiteral' was already stated in the type's module 'Swift'
Единственный подход, который я могу себе представить, - это перейти наstruct HiddenFieldType { let value: String }
, поэтому он становится "настоящим" типом.
Подход № 4
Тогда такой код больше не вызывает бесконечную рекурсию, но и не работает (значение не скрыто)
struct HiddenFieldType {
let value: String
}
extension String.StringInterpolation {
mutating func appendInterpolation(_ value: HiddenFieldType) {
appendInterpolation("♀️")
}
}
Подход № 5
Этот код наконец работает:
struct HiddenFieldType {
let value: String
}
extension HiddenFieldType: CustomStringConvertible {
var description: String {
"♀️"
}
}
Поскольку я не могу представить ничего лучше, на данный момент я бы использовал этот подход, но у него также есть небольшие проблемы с масштабируемостью, так как я должен обновить каждую точку инициализации: from
let dto1 = DTO1(field1_1: "1_1", fieldToHide: "super-secret-1", field1_2: "1_2", field1_3: "1_3")
к
let dto1 = DTO1(field1_1: "1_1", fieldToHide: .init(value: "super-secret-1"), field1_2: "1_2", field1_3: "1_3")
и я надеялся только добавить какое-то расширение в файл, который содержитtypealias HiddenFieldType = String
, а не обновлять весь код.
Вопросы
- Можно ли скрыть значение
HiddenFieldType
не меняя его сtypealias
кstruct
, и без обновления каждогоDTO
? - Есть ли лучший подход, чем 5?
заранее спасибо