diff options
author | Sean Allred <code@seanallred.com> | 2015-01-04 11:41:30 -0500 |
---|---|---|
committer | Sean Allred <code@seanallred.com> | 2015-01-04 11:57:52 -0500 |
commit | 59327f6f9c6ba419543c47670a62af0aa41271ca (patch) | |
tree | 4c5dcd1ab569769f3ad338976abb601cf787c2db | |
parent | 0e03d9086eedd486a4492e5f198e45990ad5a3bf (diff) |
Tree-style specification for filter-from-nil
Instead of saying
(field-a
field-b
object-a.subfield
field-c
object-b.subfield-a object-b.subfield-b)
you can rather say
(field-a
field-b
(object-a subfield)
field-c
(object-b subfield-a subfield-b))
To avoid a dependency loop, sx-browse-filter has been moved to
sx-filter.el.
-rw-r--r-- | sx-filter.el | 87 | ||||
-rw-r--r-- | sx-networks.el | 26 | ||||
-rw-r--r-- | sx-site.el | 12 | ||||
-rw-r--r-- | sx.el | 61 | ||||
-rw-r--r-- | test/test-macros.el | 22 | ||||
-rw-r--r-- | test/test-util.el | 14 |
6 files changed, 132 insertions, 90 deletions
diff --git a/sx-filter.el b/sx-filter.el index ad37e67..d484f43 100644 --- a/sx-filter.el +++ b/sx-filter.el @@ -42,39 +42,26 @@ Structure: ;;; Creation - (defmacro sx-filter-from-nil (included) "Creates a filter data structure with INCLUDED fields. All wrapper fields are included by default." - ;; @OTODO: it would be neat to have syntax like - ;; - ;; (field-a - ;; field-b - ;; (object-a subfield) - ;; field-c - ;; (object-b subfield-a subfield-b)) - ;; - ;; expand into - ;; - ;; (field-a - ;; field-b - ;; object-a.subfield - ;; field-c - ;; object-b.subfield-a object-b.subfield-b) - `(quote ((,@included - .backoff - .error_id - .error_message - .error_name - .has_more - .items - .page - .page_size - .quota_max - .quota_remaining - .total - .type) - nil none))) + `(quote + ((,@(sx--tree-expand + (lambda (path) + (intern (mapconcat #'symbol-name path "."))) + included) + .backoff + .error_id + .error_message + .error_name + .has_more + .items + .page + .page_size + .quota_max + .quota_remaining + .total) + nil none))) ;;; @TODO allow BASE to be a precompiled filter name (defun sx-filter-compile (&optional include exclude base) @@ -114,6 +101,46 @@ return the compiled filter." (sx-cache-set 'filter sx--filter-alist) filter)))) + +;;; Browsing filter +(defvar sx-browse-filter + (sx-filter-from-nil + ((question body_markdown + comments + answers + last_editor + last_activity_date + accepted_answer_id + link + upvoted + downvoted + question_id + share_link) + (user display_name) + (comment owner + body_markdown + body + link + edited + creation_date + upvoted + score + post_type + post_id + comment_id) + (answer answer_id + last_editor + last_activity_date + link + share_link + owner + body_markdown + upvoted + downvoted + comments))) + "The filter applied when retrieving question data. +See `sx-question-get-questions' and `sx-question-get-question'.") + (provide 'sx-filter) ;;; sx-filter.el ends here diff --git a/sx-networks.el b/sx-networks.el index 20ac65c..58ebff5 100644 --- a/sx-networks.el +++ b/sx-networks.el @@ -28,19 +28,19 @@ (defvar sx-network--user-filter (sx-filter-from-nil - (badge_count.bronze - badge_count.silver - badge_count.gold - network_user.account_id - network_user.answer_count - network_user.badge_counts - network_user.creation_date - network_user.last_access_date - network_user.reputation - network_user.site_name - network_user.site_url - network_user.user_id - network_user.user_type))) + ((badge_count bronze + silver + gold) + (network_user account_id + answer_count + badge_counts + creation_date + last_access_date + reputation + site_name + site_url + user_id + user_type)))) (defun sx-network--get-associated () "Retrieve cached information for network user. @@ -27,12 +27,12 @@ (defvar sx-site-browse-filter (sx-filter-from-nil - (site.site_type - site.name - site.api_site_parameter - site.related_sites - related_site.api_site_parameter - related_site.relation)) + ((site site_type + name + api_site_parameter + related_sites) + (related_site api_site_parameter + relation))) "Filter for browsing sites.") (defun sx-site--get-site-list () @@ -136,6 +136,26 @@ with a `link' property)." result)) result)) +(defun sx--tree-paths (tree) + "Return a list of all paths in TREE. +Adapted from http://stackoverflow.com/q/3019250." + (if (atom tree) + (list (list tree)) + (apply #'append + (mapcar (lambda (node) + (mapcar (lambda (path) + (cons (car tree) path)) + (sx--tree-paths node))) + (cdr tree))))) + +(defun sx--tree-expand (path-func tree) + "Apply PATH-FUNC to every path in TREE. +Return the result. See `sx--tree-paths'." + (mapcar path-func + (apply #'append + (mapcar #'sx--tree-paths + tree)))) + (defmacro sx-assoc-let (alist &rest body) "Use ALIST with `let-alist' to execute BODY. `.site_par' has a special meaning, thanks to `sx--ensure-site'. @@ -149,47 +169,6 @@ If ALIST doesn't have a `site' property, one is created using the `(let-alist ,alist ,@body)))) -;;; Browsing filter -(defvar sx-browse-filter - ;; @TODO: Use `sx-filter-from-nil' - '((question.body_markdown - question.comments - question.answers - question.last_editor - question.last_activity_date - question.accepted_answer_id - question.link - question.upvoted - question.downvoted - question.question_id - question.share_link - user.display_name - comment.owner - comment.body_markdown - comment.body - comment.link - comment.edited - comment.creation_date - comment.upvoted - comment.score - comment.post_type - comment.post_id - comment.comment_id - answer.answer_id - answer.last_editor - answer.last_activity_date - answer.link - answer.share_link - answer.owner - answer.body_markdown - answer.upvoted - answer.downvoted - answer.comments) - (user.profile_image shallow_user.profile_image)) - "The filter applied when retrieving question data. -See `sx-question-get-questions' and `sx-question-get-question'.") - - ;;; Utility Functions (defun sx-completing-read (&rest args) "Like `completing-read', but possibly use ido. diff --git a/test/test-macros.el b/test/test-macros.el index b6bf20b..1634603 100644 --- a/test/test-macros.el +++ b/test/test-macros.el @@ -20,3 +20,25 @@ (should (equal (sx-assoc-let data (cons .test-one .test-two)) '(1 . 2))))) + +(ert-deftest macro-test--sx-filter-from-nil () + "Test `sx-filter-from-nil'" + (should + (equal + (sx-filter-from-nil + (one two (three four five) (six seven) + (a b c d e))) + '((one two three.four three.five six.seven + a.b a.c a.d a.e + .backoff + .error_id + .error_message + .error_name + .has_more + .items + .page + .page_size + .quota_max + .quota_remaining + .total) + nil none)))) diff --git a/test/test-util.el b/test/test-util.el index 5db1691..1e3dc2b 100644 --- a/test/test-util.el +++ b/test/test-util.el @@ -29,3 +29,17 @@ (string= (sx--thing-as-string 'test& nil t) "test%26"))) + +(ert-deftest tree () + (should + (equal + (sx--tree-expand + (lambda (path) (mapconcat #'symbol-name path ".")) + '(a b (c d (e f g) h i (j k) l) m (n o) p)) + '("a" "b" "c.d" "c.e.f" "c.e.g" "c.h" "c.i" "c.j.k" "c.l" "m" "n.o" "p"))) + (should + (equal + (sx--tree-expand + (lambda (path) (intern (mapconcat #'symbol-name path "/"))) + '(a b (c d (e f g) h i (j k) l) m (n o) p)) + '(a b c/d c/e/f c/e/g c/h c/i c/j/k c/l m n/o p)))) |