Clojure EDN как источник метаданных генерации кода
Новичок в Clojure и интересно, как его использовать, чтобы упростить программирование на других языках.
Одна вещь, которую я хотел бы сделать, это использовать Clojure для генерации кода.
Например, учитывая входные данные из файла данных (формат EDN), как мне (1) пройти эту структуру или (2) протолкнуть данные в существующий механизм шаблонов?
Данные ниже предназначены для определения простого REST API, чтобы вы могли генерировать из него клиентов. Генерация клиентов на нескольких языках с использованием разных шаблонов.
(:restcall "GetAccountBalance"
{:method "GET" :path "account/balance"}
{:id int})
(:restcall "GetLastTransactions"
{:method "GET" :path "account/transactions"}
{:page int})
результирующий код будет что-то вроде
public void GetAccountBalance(int id)
{
var input = new { id = id };
callIntoRestLibrary("GET", "account/balance", input);
}
public void GetLastTransactions(int page)
{
var input = new { page = page };
callIntoRestLibrary("GET", "account/transactions", input);
}
Примечание: моей конечной целью было бы иметь их как вызовы System.Net.Http.HttpClient через C#, но также иметь возможность переводить их в вызовы JavaScript/Ajax также
1 ответ
У вас есть несколько вариантов создания шаблонов с Clojure. Одним из мест, где можно посмотреть, является Clojure Toolbox.
Вот пример с clostache, небольшой библиотекой (358 loc) реализации усов.
(ns so.core
(:require [clostache.parser :refer (render)]))
(def template "
public void {{restcall}}({{id}} id)
{
var input = new { id = id };
callIntoRestLibrary(\"{{method}}\", \"{{path}}\", input);
}")
(def data
{:restcall "GetAccountBalance"
:method "GET" :path "account/balance" :id "int"})
(print (render template data))
Выход:
public void GetAccountBalance(int id)
{
var input = new { id = id };
callIntoRestLibrary("GET", "account/balance", input);
}
Чтобы прояснить путаницу о том, что значит читать EDN.
(spit "foo.txt" (prn-str data))
Теперь файл foo.txt
содержит текстовое представление data
предположительно ваша отправная точка.
(def data2 (with-open [r (java.io.PushbackReader. (java.io.FileReader. "foo.txt"))]
(clojure.edn/read r)))
(= data data2) ;=> true
Так, read
не только извлекает текст, но и анализирует его в своем представлении данных.