Avatar
omochimetaru 9/7/2020 6:12 AM
それ最近全く同じ事やったな
6:12 AM
struct ErrorProperties<T> { typealias ErrorsGetter = (T) -> [ValidationError] var getters: [ErrorsGetter] = [] init(of type: T.Type, configure: (inout ErrorProperties<T>) -> Void) { _ = type configure(&self) } mutating func add<X>(_ keyPath: KeyPath<T, Validator<X>>) { getters.append({ (target) in target[keyPath: keyPath].errors }) } mutating func add(_ keyPath: KeyPath<T, [ValidationError]>) { getters.append({ (target) in target[keyPath: keyPath] }) } func errors(of target: T) -> [ValidationError] { getters.flatMap { (getter) in getter(target) } } }
6:13 AM
Optionalじゃなくて配列だったけど struct Props: Encodable { var name: String = "" var nameErrors: [ValidationError] = [] var email: String = "" var emailErrors: [ValidationError] = [] var password: String = "" var passwordErrors: [ValidationError] = [] var passwordHints: [ValidationError] = [] var passwordConfirm: String = "" var passwordConfirmErrors: [ValidationError] = [] static let errorProperties = ErrorProperties(of: Self.self) { (c) in c.add(\.nameErrors) c.add(\.emailErrors) c.add(\.passwordErrors) c.add(\.passwordConfirmErrors) } var validationErrors: [ValidationError] { Self.errorProperties.errors(of: self) } }
6:13 AM
この実装だと取りこぼすリスクはあるけど。
6:14 AM
型のメタデータを自分で定義してることに相当すると思う。 static let errorProeprties だし。