<commit_before>;;;; pkg-module.lisp
;;;;
;;;; This file is part of the RESTAS library, released under Lisp-LGPL.
;;;; See file COPYING for details.
;;;;
;;;; Author: <NAME> <<EMAIL>>

(in-package #:restas)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Use packages as modules
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defparameter +routes-symbol+ "*ROUTES*")
(defparameter +baseurl-symbol+ "*BASEURL*")
(defparameter +submodules-symbol+ "*SUBMODULES*")
(defparameter +render-method-symbol+ "*DEFAULT-RENDER-METHOD*")
(defparameter +content-type-symbol+ "*DEFAULT-CONTENT-TYPE*")
(defparameter +headers-symbol+ "*DEFAULT-HEADERS*")
(defparameter +decorators-sybmol+ "*DECORATORS*")

(defclass pkg-submodule (submodule)
  ((submodules :accessor submodule-submodules)))

(defmethod shared-initialize :after ((obj pkg-submodule) slot-names &key)
  (setf (submodule-submodules obj)
        (iter (for (key thing) in-hashtable (symbol-value (find-symbol +submodules-symbol+ (submodule-module obj))))
              (destructuring-bind (pkg ctxt decorators) thing
                (collect (make-instance 'pkg-submodule
                                        :symbol key
                                        :module (find-package pkg)
                                        :context (copy-restas-context ctxt)
                                        :parent obj
                                        :decorators decorators))))))

(defmethod initialize-module-instance ((module package) context)
  (iter (for child in (submodule-submodules *submodule*))
        (let ((*submodule* child))
          (initialize-module-instance (submodule-module child)
                                      (submodule-context child)))))

(defmethod finalize-module-instance ((module package) context)
  (iter (for child in (submodule-submodules *submodule*))
        (let ((*submodule* child))
          (finalize-module-instance (submodule-module child)
                                    (submodule-context child)))))

(defmacro with-submodule-context (submodule &body body)
  `(with-context (slot-value ,submodule 'context)
     ,@body))

(defmacro with-submodule (submodule &body body)
  (alexandria:once-only (submodule)
    `(if (eq *submodule* ,submodule)
         (progn ,@body)
         (let ((*submodule* ,submodule))
           (with-submodule-context *submodule*
             ,@body)))))

(defmethod submodule-baseurl ((submodule pkg-submodule))
  (with-submodule-context submodule
    (symbol-value (find-symbol +baseurl-symbol+
                               (submodule-module submodule)))))

(defmethod find-child-submodule ((symbol symbol) (parent pkg-submodule))
  (find symbol
        (submodule-submodules parent)
        :key #'submodule-symbol))

(defun find-upper-submodule (module &optional (current-submodule *submodule*)
                             &aux (package (find-package module)))
  (unless current-submodule
    (error "Can not find a submodule: ~A" package))
  (if (eql (submodule-module current-submodule) package)
      current-submodule
      (find-upper-submodule module (submodule-parent current-submodule))))

(defmethod module-routes ((module package) submodule
                          &aux (decorators (symbol-value (find-symbol +decorators-sybmol+ module))))
  (with-submodule-context submodule
    (mapcar
     (lambda (route)
       (apply-decorators route decorators))
     (alexandria:flatten (list* (iter (for route-symbol in-package (symbol-value (find-symbol +routes-symbol+ module)))
                                      (collect (create-route-from-symbol (find-symbol (symbol-name route-symbol)
                                                                                      module)
                                                                         submodule )))
                                (iter (for ss in (submodule-submodules submodule))
                                      (collect (submodule-routes ss))))))))

(defmethod make-submodule ((module symbol) &key (context (make-context)))
  (make-submodule (or (find-package module)
                      (error "Package ~A not found" module))
                  :context context))

(defmethod make-submodule ((package package) &key (context (make-context)))
  (make-instance 'pkg-submodule
                 :module package
                 :context context))


(defmacro define-module (name &rest options)
  (let* ((export (cdr (assoc :export options)))
         (impl-package-name (format nil "~:@(~A.IMPL.ROUTES~)" name))
         (defpackage-options (remove-if #'(lambda (opt)
                                            (member (car opt)
                                                    '(:export :default-render-method :default-content-type :decorators)))<commit_msg>Use &body insted &rest in 'define-module<commit_after>;;;; pkg-module.lisp
;;;;
;;;; This file is part of the RESTAS library, released under Lisp-LGPL.
;;;; See file COPYING for details.
;;;;
;;;; Author: <NAME> <<EMAIL>>

(in-package #:restas)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Use packages as modules
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defparameter +routes-symbol+ "*ROUTES*")
(defparameter +baseurl-symbol+ "*BASEURL*")
(defparameter +submodules-symbol+ "*SUBMODULES*")
(defparameter +render-method-symbol+ "*DEFAULT-RENDER-METHOD*")
(defparameter +content-type-symbol+ "*DEFAULT-CONTENT-TYPE*")
(defparameter +headers-symbol+ "*DEFAULT-HEADERS*")
(defparameter +decorators-sybmol+ "*DECORATORS*")

(defclass pkg-submodule (submodule)
  ((submodules :accessor submodule-submodules)))

(defmethod shared-initialize :after ((obj pkg-submodule) slot-names &key)
  (setf (submodule-submodules obj)
        (iter (for (key thing) in-hashtable (symbol-value (find-symbol +submodules-symbol+ (submodule-module obj))))
              (destructuring-bind (pkg ctxt decorators) thing
                (collect (make-instance 'pkg-submodule
                                        :symbol key
                                        :module (find-package pkg)
                                        :context (copy-restas-context ctxt)
                                        :parent obj
                                        :decorators decorators))))))

(defmethod initialize-module-instance ((module package) context)
  (iter (for child in (submodule-submodules *submodule*))
        (let ((*submodule* child))
          (initialize-module-instance (submodule-module child)
                                      (submodule-context child)))))

(defmethod finalize-module-instance ((module package) context)
  (iter (for child in (submodule-submodules *submodule*))
        (let ((*submodule* child))
          (finalize-module-instance (submodule-module child)
                                    (submodule-context child)))))

(defmacro with-submodule-context (submodule &body body)
  `(with-context (slot-value ,submodule 'context)
     ,@body))

(defmacro with-submodule (submodule &body body)
  (alexandria:once-only (submodule)
    `(if (eq *submodule* ,submodule)
         (progn ,@body)
         (let ((*submodule* ,submodule))
           (with-submodule-context *submodule*
             ,@body)))))

(defmethod submodule-baseurl ((submodule pkg-submodule))
  (with-submodule-context submodule
    (symbol-value (find-symbol +baseurl-symbol+
                               (submodule-module submodule)))))

(defmethod find-child-submodule ((symbol symbol) (parent pkg-submodule))
  (find symbol
        (submodule-submodules parent)
        :key #'submodule-symbol))

(defun find-upper-submodule (module &optional (current-submodule *submodule*)
                             &aux (package (find-package module)))
  (unless current-submodule
    (error "Can not find a submodule: ~A" package))
  (if (eql (submodule-module current-submodule) package)
      current-submodule
      (find-upper-submodule module (submodule-parent current-submodule))))

(defmethod module-routes ((module package) submodule
                          &aux (decorators (symbol-value (find-symbol +decorators-sybmol+ module))))
  (with-submodule-context submodule
    (mapcar
     (lambda (route)
       (apply-decorators route decorators))
     (alexandria:flatten (list* (iter (for route-symbol in-package (symbol-value (find-symbol +routes-symbol+ module)))
                                      (collect (create-route-from-symbol (find-symbol (symbol-name route-symbol)
                                                                                      module)
                                                                         submodule )))
                                (iter (for ss in (submodule-submodules submodule))
                                      (collect (submodule-routes ss))))))))

(defmethod make-submodule ((module symbol) &key (context (make-context)))
  (make-submodule (or (find-package module)
                      (error "Package ~A not found" module))
                  :context context))

(defmethod make-submodule ((package package) &key (context (make-context)))
  (make-instance 'pkg-submodule
                 :module package
                 :context context))


(defmacro define-module (name &body options)
  (let* ((export (cdr (assoc :export options)))
         (impl-package-name (format nil "~:@(~A.IMPL.ROUTES~)" name))
         (defpackage-options (remove-if #'(lambda (opt)
                                            (member (car opt)
                                                    '(:export :default-render-method :default-content-type :decorators)))
{'fraction_non_alphanumeric': 0.1608540925266904, 'fraction_numerical': 0.0, 'mean_word_length': 2.29073268651723, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 40, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1958741', 'n_tokens_mistral': 2736, 'n_tokens_neox': 2585, 'n_words': 640}