Призматическое приведение схемы - переименование ключа карты

Я пытаюсь привести карту с помощью призматической схемы (1.0.4)

Я пытаюсь заставить

{:a 1}

в

{:b 1}

Использование собственного сопоставителя со схемой:

{:b s/Int}

Но этот код не работает:

(require '[schema.core :as s])
(require '[schema.coerce :as coerce])

((coerce/coercer {:b s/Int}
                 (fn [s]
                   (when (= s s/Keyword)
                     (fn [x]
                       (if (= x :a)
                       :b
                       x))))) 
{:a 1})

Выход:

 #schema.utils.ErrorContainer{:error {:b missing-required-key, :a disallowed-key}}

Я попытался отладить его, запустив следующий код, который соответствует всем в схеме и выводит текущее значение и сопоставляемую схему:

 ((coerce/coercer {:b s/Int}
             (fn [s]
               (when true
                 (fn [x]
                   (println s x)
                   x)))) 
  {:a 1})

Выход:

 {:b Int} {:a 1}
 =>
 #schema.utils.ErrorContainer{:error {:b missing-required-key, :a disallowed-key}}

Похоже, что бомбардировщик сработает, как только доберется до карты?

1 ответ

Решение

Схема сначала разбивает вашу карту на части, соответствующие схеме, затем приводит каждый MapEntry к соответствующей схеме MapEntry и так далее вниз. Эта поломка не работает в вашем случае, поэтому вы никогда не получите ключ.

Чтобы выполнить то, что вы хотите, вам нужно прикрепить приведение к схеме карты и использовать, например, clojure.set/rename-keys в вашей функции принуждения:

(def Foo {:b s/Int})
((coerce/coercer 
   Foo
   (fn [s]
     (when (= s Foo)
       #(clojure.set/rename-keys % {:a :b}))))
 {:a 1})
Другие вопросы по тегам