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 не только извлекает текст, но и анализирует его в своем представлении данных.

Другие вопросы по тегам