001  (ns dog-and-duck.quack.picky.collections
002    (:require [dog-and-duck.quack.picky.objects :refer [object-faults
003                                                        object-reference-or-faults]]
004              [dog-and-duck.quack.picky.utils :refer [concat-non-empty
005                                                      cond-make-fault-object]]))
006  
007  
008  ;;;     Copyright (C) Simon Brooke, 2022
009  
010  ;;;     This program is free software; you can redistribute it and/or
011  ;;;     modify it under the terms of the GNU General Public License
012  ;;;     as published by the Free Software Foundation; either version 2
013  ;;;     of the License, or (at your option) any later version.
014  
015  ;;;     This program is distributed in the hope that it will be useful,
016  ;;;     but WITHOUT ANY WARRANTY; without even the implied warranty of
017  ;;;     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
018  ;;;     GNU General Public License for more details.
019  
020  ;;;     You should have received a copy of the GNU General Public License
021  ;;;     along with this program; if not, write to the Free Software
022  ;;;     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
023  
024  (defn paged-collection-faults
025    "Return a list of faults found in `x` considered as a paged collection
026     object of this sub-`type`, or `nil` if none are found."
027    [x type]
028    (concat-non-empty
029     (object-faults x type)
030     (list (object-reference-or-faults x type :critical :expected-collection)
031           (cond-make-fault-object (integer? (:totalItems x)) :should :no-total-items)
032           (object-reference-or-faults (:first x) (str type "Page") :must :no-first-page)
033           (object-reference-or-faults (:last x) (str type "Page") :should :no-last-page))))
034  
035  (defn simple-collection-faults
036    "Return a list of faults found in `x` considered as a non-paged collection
037     object of this sub-`type`, or `nil` if none are found."
038    [x type]
039    (concat-non-empty
040     (object-faults x type)
041     (concat
042      (list (cond-make-fault-object (integer? (:totalItems x)) :should :no-total-items)
043            (cond-make-fault-object (coll? (:items x)) :must :no-items-collection))
044      (reduce
045       concat
046       (map #(object-reference-or-faults % nil :must :not-object-reference) (:items x))))))
047  
048  (defn collection-page-faults
049    "Return a list of faults found in `x` considered as a collection page
050     object of this sub-`type`, or `nil` if none are found."
051    [x type]
052    (concat-non-empty
053     (simple-collection-faults x type)
054     (list
055      (object-reference-or-faults (:partOf x)
056                                  (apply str (drop-last 4 type))
057                                  :should
058                                  :n-part-of)
059      (object-reference-or-faults (:next x) type :minor :no-next-page)
060      (object-reference-or-faults (:prev x) type :minor :no-prev-page))))