Проверка нескольких полиморфных значений с использованием призматической схемы
Некоторое время назад я спросил о простых полиморфных схемах, и ответ там некоторое время работал хорошо.
Теперь карта, которую я хочу проверить, имеет дополнительное значение, которое зависит от значения другого ключа.
Придуманный пример объекта:
{:type :foo {:type :bert {:type :foo
:foo-param :bar :bert-size :medium :foo-param :bar
:method :baz :method :baz :method :bang
:baz-rate :max} :baz-rate :max} :bangness :considerable}
Дискриминаторы здесь :type
а также :method
каждый из которых имеет свой собственный набор допустимых ключей и значений.
Только ранее :type
существовал, и работал следующее:
(def ^:private test-base-schema {:type (s/enum :foo :abc :banana)})
(def test-schema
(s/conditional #(= (:type %) :foo)
(merge test-base-schema {:foo-param s/Keyword})
; other conditions here
))
Однако теперь, когда существует более одного дискриминатора, число условных ветвей будет комбинаторным.
Один из вариантов - разрешить {s/Any s/Any}
в картах и использовании s/both
, но я не могу допустить, чтобы схемы были "свободными", так как неожиданный ключ / значения должны рассматриваться как недействительные.
Я также не хочу изменять структуру проверяемой карты только для того, чтобы проверка работала с использованием этой библиотеки.
Есть ли разумный способ добиться строгой проверки карт, которые имеют несколько условных подсхем?
1 ответ
Причудливый ответ заключается в том, что это может быть запахом, что ваша модель данных не идеальна, и вы должны рассмотреть возможность ее рефакторинга, чтобы иметь вложенную структуру, такую как
{:type-info {:type :foo :foo-param :bar}
:method-info {:method :baz :baz-rate :max}}
(Возможно) более полезный ответ заключается в том, что я не думаю, что это легко с готовым набором схем, помимо простого написания пользовательского предиката для проверки.
Если это не желательно, я думаю, вам нужно ввести новый тип схемы. К счастью, это легко сделать в пользовательском коде (или сторонней библиотеке). К сожалению, я не вижу простого способа представить эти два понятия (строгое объединение и условную структуру карты) четким и ортогональным способом (без объединения их в единую схему условного объединения или без объединения условий с учетом условий). Я верю, что есть способ, но для меня это не очевидно с первого взгляда.