Использование спецификации/слияния со спецификацией/мультиспецификацией

Могу ли я использовать s/merge с s/multi-spec? Например

(require '[clojure.spec :as s])

(s/def :field/common (s/keys :req-un [:field/type :field/name]
                             :opt-un [:field/default]))

(s/def :field/max-length int?)

(defmulti field-type :type)
(defmethod field-type :character [_]
  (s/merge :field/common
           (s/keys :req-un [:field/max-length])))
(defmethod field-type :foreign-key [_]
  (s/merge :field/common
           (s/keys :req-un [:field/references])))
(defmethod field-type :int [_]
  ;; ??? what to do here? - I only want the common keys
  :field/common)
(defmethod field-type :boolean [_]
  ;; ??? what to do here? - I only want the common keys
  :field/common)

(s/def ::field (s/multi-spec field-type :field/type))

Что бы я поставил для методов :int и :boolean? Мне нужны только общие поля.


person Frank Henard    schedule 08.02.2019    source источник


Ответы (1)


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

(require '[clojure.spec :as s])

(s/def :field/common (s/keys :req-un [:field/type :field/name]
                             :opt-un [:field/default]))

(s/def :field/max-length int?)

(defmulti field-type :type)
(defmethod field-type :character [_]
  (s/merge :field/common
           (s/keys :req-un [:field/max-length])))
(defmethod field-type :foreign-key [_]
  (s/merge :field/common
           (s/keys :req-un [:field/references])))

(defmethod field-type :field/common [_]
  :field/common)

(derive :int :field/common)
(derive :boolean :field/common)

(s/def ::field (s/multi-spec field-type :field/type))
person l0st3d    schedule 11.02.2019
comment
Если это работает, мне это нравится. Спасибо, попробую! - person Frank Henard; 11.02.2019