2015-12-19 2 views
4

Я пытаюсь соответствовать следующие последовательности с использованием радужный/Schema:Необязательный элемент в последовательности

[{:n "some text"}] ; => valid 

и

[{:k "some text"} {:n "some text"}] ; => valid 

То, что я пробовал:

(s/def Elem3 
    {:k s/Str}) 

(s/def Elem2 
    {:n s/Str}) 

(s/def Elem 
    [(s/optional Elem2 "elem2") Elem3]) 

(s/validate Elem [{:k "huji"}]) 
;; => 
;; Value does not match schema: [(named {:n missing-required-key, :k 
;; disallowed-key} "elem2")] 

(s/def Elem 
    [(s/maybe Elem2) Elem3]) 

(s/validate Elem [{:k "huji"}]) 
;; => 
;; [(maybe {:n Str}) {:k java.lang.String}] is not a valid sequence 
;; schema; a valid sequence schema consists of zero or more `one` 
;; elements, followed by zero or more `optional` elements, followed by 
;; an optional schema that will match the remaining elements. 

(s/defrecord ElemOption1 
    [elem3 :- Elem3]) 

(s/defrecord ElemOption2 
    [elem2 :- Elem2 
    elem3 :- Elem3]) 

(s/def Elem 
    (s/conditional 
    #(= 2 (count %)) ElemOption2 
    :else ElemOption1)) 

(s/validate Elem [{:k "huji"}]) 
;; => 
;; Value does not match schema: (not (instance? 
;; peg_dsl.standard_app.ElemOption1 [{:k "huji"}])) 

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

ответ

1

Проблема с первой попытки, что, начиная с необязательно означает, что он не ожидает, что {: к s/Str} или ничего, и он видит {:n s/Str}, так что это явно не так.

У вашей второй попытки есть две проблемы. Maybe может быть значением или nil, но оно должно присутствовать. Вы также не записываете схему последовательности . Но проблема с схемой последовательности - это элементы, которые должны быть в порядке s/one* s/optional*, а вы хотите s/optional s/one.

Ваша третья попытка ближе, используя условное обозначение, но вы не можете сопоставлять , потому что вы не проверяете экземпляры записей , вы проверяете карты.

Решение выглядит следующим образом:

(def ElemKNList [(s/one {:k s/Str} "k") (s/one {:n s/Str} "n")]) 
(def ElemNList [(s/one {:n s/Str} "n")]) 

(def Elem (s/conditional #(= 2 (count %)) ElemKNList 
         :else ElemNList)) 

(s/validate Elem [{:k "huji"} {:n "huji"}])  
    => [{:k "huji"} {:n "huji"}] 
(s/validate Elem [{:n "huji"}]) 
    => [{:n "huji"}]   
(s/validate Elem [{:k "huji"}]) 
    => ExceptionInfo Value does not match schema: [(named {:n missing-required-key, :k disallowed-key} "n")] schema.core/validator/fn--18435 (core.clj:151)    
+0

Что я ожидал сделать в моей первой попытки схемы, чтобы сказать: «Я ожидаю последовательность, состоящую из необязательно {: нс/Str} с последующим a {: ks/Str}. Когда я проверяю [{: k "huji"}], я вижу, что {: ns/Str} нет, но затем идет {: ks/Str}, все в порядке! " – foki