Skip to content

Commit

Permalink
Add basic var support to the org-src blocks. (#62)
Browse files Browse the repository at this point in the history
* Add basic var support to the org-src blocks.

This will just wrap the variables into (if needed) nested &[&str]
constants.

It will also not care about the types of the passed variables, except if
they are lists - all other typeinformation doesn't matter - everything
will be a &str in the end.

* Add tests to check the three support cases of vars.
  • Loading branch information
bergmannf authored Oct 25, 2024
1 parent 34abafb commit 2f3c5ff
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 1 deletion.
49 changes: 48 additions & 1 deletion rustic-babel.el
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,51 @@ executed with the parameter `:include'."
(module (expand-file-name (format "%s.rs" b) src-dir)))
(write-region contents nil module nil 0))))

(defun rustic-babel-variable-to-type (var)
"Return a valid const type for the passed variable.
Only supports three cases:
1. Simple value: A='a' -> &str
2. Simple list: A=('a' 'b') -> &[&str]
3. Nested list (org-table): A=(('a' 'b')) -> &[&[&str]]"
(if (listp var)
(if (listp (car var)) "&[&[&str]]" "&[&str]")
"&str"))

(defun rustic-babel-variable-to-rust (var)
"Return a valid rust assignment of an org VAR.
This will convert a simple variable to a &str and list to nested
list of strings. Tables will be converted to &[&[&str]] but need
to be homogenous."
(if (listp var)
(if (listp (car var))
(concat "&[" (string-join (mapcar #'rustic-babel-variable-to-rust var) ",") "]")
(concat "&["
(string-join
(mapcar (lambda (v) (format "\"%s\"" v)) var)
", ")
"]"))
(concat "\"" var "\"")))

(defun rustic-babel-variable-assignments:rust (vars)
"Convert the passed org-src block VARS into a matching const type.
There are only 3 cases:
1. Simple value: A='a' -> &str
2. Simple list: A=('a' 'b') -> &[&str]
2. Nested list (org-table): A=(('a' 'b')) -> &[&[&str]]"
(string-join
(mapcar
(lambda (pair)
(let ((key (car pair))
(value (cdr pair)))
(format "const %s: %s = %s;\n" key (rustic-babel-variable-to-type value) (rustic-babel-variable-to-rust value))))
(org-babel--get-vars vars))
"\n"))

(defun org-babel-execute:rustic (body params)
"Execute a block of Rust code with org-babel.
Expand All @@ -376,6 +421,7 @@ kill the running process."
(dir (setq rustic-babel-dir (expand-file-name project)))
(main-p (cdr (assq :main params)))
(main (expand-file-name "main.rs" (concat dir "/src")))
(vars (cdr (assq :var params)))
(wrap-main (cond ((string= main-p "yes") t)
((string= main-p "no") nil)
(t rustic-babel-auto-wrap-main)))
Expand All @@ -399,7 +445,8 @@ kill the running process."
(concat "#![allow(non_snake_case, unused)]\n"
(if use-blocks (rustic-babel-insert-mod use-blocks) "")
(if include-blocks (rustic-babel-include-blocks include-blocks) "")
(if wrap-main (rustic-babel-ensure-main-wrap body) body))
(if wrap-main (rustic-babel-ensure-main-wrap body) body)
(if (not (eq vars nil)) (rustic-babel-variable-assignments:rust params) ""))
nil main nil 0)
(rustic-babel-eval dir toolchain main-p)
(setq rustic-babel-src-location
Expand Down
24 changes: 24 additions & 0 deletions test/rustic-babel-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -271,4 +271,28 @@
(rustic-test-babel-execute-block buf)
(should (eq (rustic-test-babel-check-results buf) nil)))))

(ert-deftest rustic-test-babel-block-with-simple-var ()
(let* ((string "println!(\"{}\", A)")
(params ":main yes :var A=\"A\"")
(buf (rustic-test-get-babel-block string params)))
(with-current-buffer buf
(rustic-test-babel-execute-block buf)
(should (string-equal (rustic-test-babel-check-results buf) "A\n")))))

(ert-deftest rustic-test-babel-block-with-list-var ()
(let* ((string "println!(\"{:?}\", A)")
(params ":main yes :var A='(\"A\" \"B\")")
(buf (rustic-test-get-babel-block string params)))
(with-current-buffer buf
(rustic-test-babel-execute-block buf)
(should (string-equal (rustic-test-babel-check-results buf) "[\"A\", \"B\"]\n")))))

(ert-deftest rustic-test-babel-block-with-nested-list-var ()
(let* ((string "println!(\"{:?}\", A)")
(params ":main yes :var A='((\"A\" \"B\") (\"C\" \"D\"))")
(buf (rustic-test-get-babel-block string params)))
(with-current-buffer buf
(rustic-test-babel-execute-block buf)
(should (string-equal (rustic-test-babel-check-results buf) "[[\"A\", \"B\"], [\"C\", \"D\"]]\n")))))

(provide 'rustic-babel-test)

0 comments on commit 2f3c5ff

Please sign in to comment.