+;; generate search functions
+
+(defmacro musicbrainz--defsearch-1 (name format-string format-args)
+ "Generate search function to format a single item.
+NAME FORMAT-STRING FORMAT-ARGS
+See listenbrainz--deformatter for details."
+ (let ((f (intern (concat "musicbrainz-search-" name)))
+ (doc (format "Search for %s using QUERY and show matches.
+Optionally return LIMIT number of results." name)))
+ `(defun ,f (query &optional limit) ,doc
+ (let* ((max (if limit limit 1))
+ (response
+ (musicbrainz-search ,name query max)))
+ (let-alist response
+ (format ,format-string ,@format-args))))))
+
+
+(defmacro musicbrainz--defsearch-2 (name format-string format-args alist)
+ "Generate lookup function to format multiple items.
+QUERY SUBQUERY FORMAT-STRING FORMAT-ARGS ALIST
+See listenbrainz--deformatter for details."
+ (let ((f (intern (concat "musicbrainz-search-" name)))
+ (doc (format "Search for %s using QUERY and show matches.
+Optionally return LIMIT number of results." name)))
+ `(defun ,f (query &optional limit) ,doc
+ (let* ((max (if limit limit 1))
+ (response
+ (musicbrainz-search ,name query max)))
+ (let-alist response
+ (seq-map
+ (lambda (i)
+ (let-alist i
+ (format ,format-string ,@format-args)))
+ ,alist))))))