Проверка нескольких полиморфных значений с использованием призматической схемы

Некоторое время назад я спросил о простых полиморфных схемах, и ответ там некоторое время работал хорошо.

Теперь карта, которую я хочу проверить, имеет дополнительное значение, которое зависит от значения другого ключа.

Придуманный пример объекта:

{: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}}

(Возможно) более полезный ответ заключается в том, что я не думаю, что это легко с готовым набором схем, помимо простого написания пользовательского предиката для проверки.

Если это не желательно, я думаю, вам нужно ввести новый тип схемы. К счастью, это легко сделать в пользовательском коде (или сторонней библиотеке). К сожалению, я не вижу простого способа представить эти два понятия (строгое объединение и условную структуру карты) четким и ортогональным способом (без объединения их в единую схему условного объединения или без объединения условий с учетом условий). Я верю, что есть способ, но для меня это не очевидно с первого взгляда.

Другие вопросы по тегам