From bb361465c342135bf99820ddca415b9ee9424fea Mon Sep 17 00:00:00 2001 From: Jaidyn Ann <10477760+JadedCtrl@users.noreply.github.com> Date: Sun, 23 Jun 2024 22:47:55 -0500 Subject: [PATCH] Parse even unknown ActivityStreams classes By means of a *default-class* that is a catch-all. --- src/activity-streams.lisp | 19 +++++++++++++++---- src/activity-vocabulary.lisp | 2 ++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/activity-streams.lisp b/src/activity-streams.lisp index e6da30a..fdf78b7 100644 --- a/src/activity-streams.lisp +++ b/src/activity-streams.lisp @@ -23,7 +23,7 @@ :parse :encode :define-class-encoders ;; Globals - :*ap-packages* + :*ap-packages* :*default-class* ;; Classes :object ;; Slots @@ -41,6 +41,12 @@ during JSON parsing. The class-name searched for is simply the value of the JSON object’s “type” key. The package first in the list to export such a symbol is the winner.") +(defparameter *default-class* 'activity-servist/activity-streams:object + "The class used for ActivityStreams objects found during parsing that don’t +have a corresponding class defined. Notably, all keys and values without +corresponding slots are placed in the MISC slot. +The class you choose should inherit ACTIVITY-SERVIST/ACTIVITY-STREAMS:OBJECT.") + ;; Private, internal variable. (defparameter *@context* nil "Used in YASON:ENCODE to ensure that a single top-level @context can be @@ -96,8 +102,9 @@ again and again, by YASON:ENCODE-SLOTS." (defun parse-table (table) "Parse a hash-table corresponding to YASON-parsed JSON into an ActivityPub object." - (let* ((class (car (find-registered-classes (param-case (gethash "type" table))))) - (obj (make-instance class))) + (let* ((found-class (car (find-registered-classes (param-case (gethash "type" table))))) + (class (or found-class (find-class *default-class*))) + (obj (make-instance class))) (loop for key being each hash-key of table for val being each hash-value of table do (let ((slot-sym (car (find-registered-symbols (param-case key)))) @@ -232,7 +239,11 @@ items in each will be contained in the resultant list." *ap-packages* list." (remove-if #'not - (mapcar (lambda (package) (find-symbol (string-upcase str) package)) + (mapcar (lambda (package) + (multiple-value-bind (sym context) + (find-symbol (string-upcase str) package) + (unless (eq context :inherited) + sym))) *ap-packages*))) (defun find-registered-classes (str) diff --git a/src/activity-vocabulary.lisp b/src/activity-vocabulary.lisp index 5a4a4e5..29c952b 100644 --- a/src/activity-vocabulary.lisp +++ b/src/activity-vocabulary.lisp @@ -54,6 +54,8 @@ (in-package #:activity-servist/activity-vocabulary) +(setq activity-servist/activity-streams:*default-class* + 'activity-servist/activity-vocabulary:object) ;;; Macros