aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtur Malabarba <bruce.connor.am@gmail.com>2015-01-04 17:11:07 -0200
committerArtur Malabarba <bruce.connor.am@gmail.com>2015-01-04 17:11:07 -0200
commit917e70936ef82cfd2a34b541348ebd485049f46a (patch)
tree0fe936bfa609ea19c454cdcb4d1c2349d5c0c746
parent89834aa61adf1fff29379c82ab96629f0b2960d0 (diff)
parent01df71244d3fe5412e2420127dcd2282d9fa39c7 (diff)
Merge pull request #192 from vermiculus/filter-macro
Filter macro
-rw-r--r--sx-filter.el86
-rw-r--r--sx-networks.el26
-rw-r--r--sx-site.el12
-rw-r--r--sx.el61
-rw-r--r--test/test-macros.el22
-rw-r--r--test/test-util.el14
6 files changed, 132 insertions, 89 deletions
diff --git a/sx-filter.el b/sx-filter.el
index c67d05b..d484f43 100644
--- a/sx-filter.el
+++ b/sx-filter.el
@@ -42,38 +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
- .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)
@@ -113,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.
diff --git a/sx-site.el b/sx-site.el
index 1bc86a6..2f0a31d 100644
--- a/sx-site.el
+++ b/sx-site.el
@@ -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 ()
diff --git a/sx.el b/sx.el
index 3aa87e7..f77b313 100644
--- a/sx.el
+++ b/sx.el
@@ -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))))