Skip to content

Commit

Permalink
Feat: string-case multiple-items clauses
Browse files Browse the repository at this point in the history
Now string-case supports multiple-items clauses.
  • Loading branch information
kilianmh committed Jun 3, 2024
1 parent fbf3407 commit b9d14b4
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 3 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -887,8 +887,9 @@ A case-like macro that works with strings (CL case's test function is
Example:

~~~lisp
(str:string-case input
("foo" (do something))
(str:string-case "hello"
("foo" 1)
(("hello" "test") 5)
(nil (print "input is nil"))
(otherwise (print "non of the previous forms was caught.")))
~~~
Expand Down
9 changes: 8 additions & 1 deletion str.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -711,11 +711,13 @@ Returns the string written to file."

(defmacro string-case (str &body forms)
"A case-like macro that works with strings (case works only with symbols).
You can either supply single-item clauses, multiple-items clauses, or otherwise.
Example:
(str:string-case input
(\"foo\" (do something))
((\"hello\" \"test\") 5)
(nil (print \"input is nil\")
(otherwise (print \"none of the previous forms was caught\")))
Expand All @@ -729,7 +731,12 @@ Returns the string written to file."
(cond
,@(loop :for (s . f) :in forms
:if (stringp s) :collect `((string= ,test ,s) ,@f)
:else :if (string= s 'otherwise) :collect `(t ,@f)
:else :if (consp s)
:append (loop for element :in s
:if (stringp element)
:collect `((string= ,test ,element) ,@f)
:else :collect `((eql ,test ,s) ,@f))
:else :if (string= s 'otherwise) :collect `(t ,@f)
:else :collect `((eql ,test ,s) ,@f))))))

(defun expand-match-branch (str block patterns forms)
Expand Down
5 changes: 5 additions & 0 deletions test/test-str.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,11 @@
("hello" (format nil "yes"))
(otherwise nil))
"string-case base case")
(is (string-case "two-forms"
("first" nil)
(("hello" "two-forms") t)
(otherwise nil))
"multiple-item clause")
(is (string= nil (string-case "no"
("hello" t)
(otherwise nil)))
Expand Down

0 comments on commit b9d14b4

Please sign in to comment.