2017-12-12 3 views
1

Ich habe eine Spezifikationsdefinition, die den Inhalt eingehender Daten validiert. Da die Daten eine Zuordnung von Feldern sind, verwende ich spec/keys für die Validierung. Zum Beispiel:Strukturdefinitionscode von clojure spec/keys wiederverwenden

Aber ein zusätzliches Bedürfnis, das ich habe, soll sicherstellen, dass eingehende Daten nur die Schlüssel enthalten, die ich will. . (In diesem Fall :name und :age Schlüssel nur für das, ich so etwas wie:.

(def permitted-keys [:age :name]) 
(select-keys some-input permitted-keys) 

, um sicherzustellen, nur die Tasten bekommen gefiltert

Gibt es eine Weise, die ich einige Codes zwischen meinem spec wiederverwenden kann Definition für die Abbildungsstruktur (s/keys) und diesen zusätzlichen Schritt I die zulässigen Tasten zum Filtern nehmen (permitted-keys)?

vielleicht durch entweder die Liste der Schlüssel aus der s/keys Definition Extraktion oder durch einen vorhandenen Vektor von Schlüsseln zuPassieren 10?

+0

Auschecken [dieses Makro] (https://github.com/gfredericks/schpec/blob/master/src/com/gfredericks/schpec.clj#L13-L35). –

Antwort

1

ich bei this macro suchen empfehlen würde, da es alle Basen abdeckt und einen Generator, aber hier ist eine andere nehmen, die nur verwendet unnamespaced Schlüssel Ihre Karten gelten folgende Voraussetzungen: für die Wiederverwendung

(defmacro keys-strict 
    [& args] 
    (let [{:keys [req opt req-un opt-un]} args 
     ks (into #{} (->> (concat req opt req-un opt-un) 
          (map #(keyword (name %)))))] ;; strip namespaces from keywords 
    `(s/and (s/keys [email protected]) (s/map-of ~ks any?)))) 

Der einzige Trick Die gleiche Quelle der Wahrheit für die Schlüssel ist, dass Ihre Schlüsselspezifikationen Namespace sein werden, aber Ihre Map-Schlüssel nicht. Sie könnten das gleiche ohne ein Makro tun, nur s/and Ihre s/keys Spezifikation mit einer s/map-of Spezifikation oder eine andere Spezifikation, die die zulässigen Schlüssel beschränkt.

Gibt es eine Möglichkeit, Code zwischen meiner Spezifikationsdefinition für die Kartenstruktur (s/keys) und diesen zusätzlichen Schritt zum Filtern der zulässigen Schlüssel (erlaubte Schlüssel) wiederzuverwenden?

Ja, das ist in dem obigen Beispiel durch Spleißen args auf den s/keys Anruf behandelt, und in ähnlicher Weise in dieser vollständigere Makro here getan.

Hinweis: Es kann Situationen geben, in denen Sie wirklich einschränken müssen, welche Schlüssel Sie akzeptieren, aber ich denke, es wird generell empfohlen, Kartenspezifikationen zu definieren, die später geöffnet werden können.

+0

Ehrfürchtig. Dies hilft definitiv, strenge Karten zu spezifizieren. Auch wenn Sie es nicht explizit angegeben haben, haben Sie auf einen Teil meiner Frage "Wie kann ich einen vorhandenen Schlüsselvektor an eine s/keys-Definition übergeben" in Ihrer '~ @ args'-Spleißfunktion in der Makrodefinition geantwortet. Dies ist es wert, als Teil Ihrer Antwort angegeben zu werden. –