changelog shortlog graph tags branches files raw help

Mercurial > demo / changeset: rust ffi macros, general stuff

changeset 7: 315fedf35bc7
parent 6: 3d202b181d6c
child 8: bebb76da449c
author: ellis <ellis@rwest.io>
date: Sun, 07 May 2023 18:06:13 -0400
files: .hgignore Cargo.toml build.py build.rs cbindgen.toml ffi/build.py ffi/demo.h ffi/mpk_ffi.h gen.rs lib.rs makefile obj/src/lib.rs obj/src/types.rs proc_macros/Cargo.toml proc_macros/src/lib.rs scripts/fmt.ros tk.lisp
description: rust ffi macros, general stuff
     1.1--- a/.hgignore	Sun May 07 01:32:31 2023 -0400
     1.2+++ b/.hgignore	Sun May 07 18:06:13 2023 -0400
     1.3@@ -1,4 +1,9 @@
     1.4 out/.*
     1.5 .*Cargo.lock$
     1.6 .*target/.*
     1.7-.*[.]fasl$
     1.8\ No newline at end of file
     1.9+ffi/_demo.c$
    1.10+.*[.]fasl$
    1.11+.*[.]o$
    1.12+.*[.]so$
    1.13+.*[.]dylib$
    1.14+.*[.]a$
    1.15\ No newline at end of file
     2.1--- a/Cargo.toml	Sun May 07 01:32:31 2023 -0400
     2.2+++ b/Cargo.toml	Sun May 07 18:06:13 2023 -0400
     2.3@@ -1,7 +1,6 @@
     2.4 [package]
     2.5-name = "demo_ffi"
     2.6+name = "demo"
     2.7 version = "0.1.0"
     2.8-edition = "2021"
     2.9 build = "build.rs"
    2.10 [lib]
    2.11 path = "lib.rs"
    2.12@@ -13,4 +12,4 @@
    2.13 obj = {version = "0.1.0",path = "obj"}
    2.14 fig = {version = "0.1.0",path = "fig"}
    2.15 [build-dependencies]
    2.16-cbindgen = "0.20"
    2.17\ No newline at end of file
    2.18+cbindgen = "0.24.3"
    2.19\ No newline at end of file
     4.1--- a/build.rs	Sun May 07 01:32:31 2023 -0400
     4.2+++ b/build.rs	Sun May 07 18:06:13 2023 -0400
     4.3@@ -6,13 +6,11 @@
     4.4     .expect("CARGO_MANIFEST_DIR env var is not defined")
     4.5     .into();
     4.6   // let mpk_py = "build.py";
     4.7-  let config = cbindgen::Config::from_file("cbindgen.toml")
     4.8-    .expect("Unable to find cbindgen.toml configuration file");
     4.9   let build_dir = crate_dir.join("ffi/");
    4.10   if !build_dir.exists() {
    4.11     create_dir(&build_dir).unwrap();
    4.12   }
    4.13-  cbindgen::generate_with_config(&crate_dir, config)
    4.14-    .unwrap()
    4.15-    .write_to_file(build_dir.join("mpk_ffi.h"));
    4.16+  cbindgen::generate(crate_dir)
    4.17+    .expect("Unable to find cbindgen.toml configuration file")
    4.18+    .write_to_file(build_dir.join("demo.h"));
    4.19 }
     5.1--- a/cbindgen.toml	Sun May 07 01:32:31 2023 -0400
     5.2+++ b/cbindgen.toml	Sun May 07 18:06:13 2023 -0400
     5.3@@ -1,11 +1,14 @@
     5.4-include_guard = "mpk_ffi_h"
     5.5+include_guard = "demo_h"
     5.6 autogen_warning = "/* DO NOT TOUCH */"
     5.7 include_version = true
     5.8 language = "C"
     5.9 cpp_compat = true
    5.10 line_length = 88
    5.11-
    5.12+documentation = true	
    5.13 [parse]
    5.14 parse_deps = true
    5.15-include = ["mpk_config", "mpk_hash"]
    5.16-extra_bindings = ["mpk_hash", "mpk_config"]
    5.17+include = ["obj","fig","libc"]
    5.18+extra_bindings = ["obj","fig","libc"]
    5.19+#expand = ["demo","obj"]
    5.20+#[parse.expand]
    5.21+#crates = ["demo"]
    5.22\ No newline at end of file
     6.1--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2+++ b/ffi/build.py	Sun May 07 18:06:13 2023 -0400
     6.3@@ -0,0 +1,48 @@
     6.4+try:
     6.5+    from cffi import FFI
     6.6+except ImportError:
     6.7+    print("pip install cffi, included with PyPy")
     6.8+
     6.9+import os
    6.10+import re
    6.11+import pathlib
    6.12+
    6.13+
    6.14+def parse_header(header):
    6.15+    h = open(header, "r").read().lstrip()
    6.16+    cdef = re.sub(
    6.17+        r"^(#|\s*\/*\*|extern).*[\r\n]|.*\"C\"$|^(?:[\t ]*(?:\r?\n|\r))+",
    6.18+        "",
    6.19+        h,
    6.20+        flags=re.MULTILINE,
    6.21+    )
    6.22+    return cdef
    6.23+
    6.24+
    6.25+def init_ffi(cdef):
    6.26+    ffi = FFI()
    6.27+    ffi.set_source(
    6.28+        "_demo",
    6.29+        """
    6.30+        #include "demo.h"
    6.31+        """,
    6.32+#        libraries=["demo"],
    6.33+        library_dirs=["."],
    6.34+        include_dirs=["."],
    6.35+    )
    6.36+
    6.37+    ffi.cdef(cdef)
    6.38+
    6.39+    return ffi
    6.40+
    6.41+
    6.42+def compile(ffi, lib_dir, v):
    6.43+    os.environ["LD_RUN_PATH"] = os.path.abspath(lib_dir)
    6.44+    ffi.compile(verbose=v)
    6.45+
    6.46+
    6.47+if __name__ == "__main__":
    6.48+    build_dir = pathlib.Path(__file__).parent
    6.49+    cdef = parse_header(build_dir / "demo.h")
    6.50+    print(cdef)
    6.51+    compile(init_ffi(cdef), build_dir, True)
     7.1--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2+++ b/ffi/demo.h	Sun May 07 18:06:13 2023 -0400
     7.3@@ -0,0 +1,60 @@
     7.4+#ifndef demo_h
     7.5+#define demo_h
     7.6+
     7.7+/* Generated with cbindgen:0.24.3 */
     7.8+
     7.9+/* DO NOT TOUCH */
    7.10+
    7.11+#include <stdarg.h>
    7.12+#include <stdbool.h>
    7.13+#include <stdint.h>
    7.14+#include <stdlib.h>
    7.15+
    7.16+typedef struct CustomService CustomService;
    7.17+
    7.18+/**
    7.19+ * APPLICATION TYPES
    7.20+ */
    7.21+typedef struct Service Service;
    7.22+
    7.23+#ifdef __cplusplus
    7.24+extern "C" {
    7.25+#endif // __cplusplus
    7.26+
    7.27+void free_service(struct Service *ptr);
    7.28+
    7.29+struct Service *service_from_string(const char *ptr);
    7.30+
    7.31+struct Service *service_from_json_string(const char *ptr);
    7.32+
    7.33+char *service_to_json_string(const struct Service *ptr);
    7.34+
    7.35+struct Service *service_from_ron_string(const char *ptr);
    7.36+
    7.37+char *service_to_ron_string(const struct Service *ptr);
    7.38+
    7.39+struct Service *service_decode(const uint8_t *ptr, size_t len);
    7.40+
    7.41+uint8_t *service_encode(const struct Service *ptr);
    7.42+
    7.43+void free_custom_service(struct CustomService *ptr);
    7.44+
    7.45+struct CustomService *custom_service_from_string(const char *ptr);
    7.46+
    7.47+struct CustomService *custom_service_from_json_string(const char *ptr);
    7.48+
    7.49+char *custom_service_to_json_string(const struct CustomService *ptr);
    7.50+
    7.51+struct CustomService *custom_service_from_ron_string(const char *ptr);
    7.52+
    7.53+char *custom_service_to_ron_string(const struct CustomService *ptr);
    7.54+
    7.55+struct CustomService *custom_service_decode(const uint8_t *ptr, size_t len);
    7.56+
    7.57+uint8_t *custom_service_encode(const struct CustomService *ptr);
    7.58+
    7.59+#ifdef __cplusplus
    7.60+} // extern "C"
    7.61+#endif // __cplusplus
    7.62+
    7.63+#endif /* demo_h */
     8.1--- a/ffi/mpk_ffi.h	Sun May 07 01:32:31 2023 -0400
     8.2+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3@@ -1,13 +0,0 @@
     8.4-#ifndef mpk_ffi_h
     8.5-#define mpk_ffi_h
     8.6-
     8.7-/* Generated with cbindgen:0.20.0 */
     8.8-
     8.9-/* DO NOT TOUCH */
    8.10-
    8.11-#include <stdarg.h>
    8.12-#include <stdbool.h>
    8.13-#include <stdint.h>
    8.14-#include <stdlib.h>
    8.15-
    8.16-#endif /* mpk_ffi_h */
     9.1--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2+++ b/gen.rs	Sun May 07 18:06:13 2023 -0400
     9.3@@ -0,0 +1,84 @@
     9.4+//! demo
     9.5+pub use fig::*;
     9.6+pub use obj::*;
     9.7+use std::ffi::{CStr, CString}; //OsStr,Path
     9.8+                               //use std::os::unix::ffi::OsStrExt;
     9.9+use std::slice;
    9.10+use libc::{c_char,size_t};
    9.11+
    9.12+#[macro_export]
    9.13+macro_rules! cdefn {
    9.14+  (free $t:tt $n:tt) => {
    9.15+    #[no_mangle]
    9.16+    pub unsafe extern "C" fn $n(ptr: *mut $t) {
    9.17+      if ptr.is_null() {
    9.18+        return;
    9.19+      }
    9.20+      let _ = Box::from_raw(ptr);
    9.21+    }
    9.22+  };
    9.23+  (from_string $t:tt $n:tt) => {
    9.24+    #[no_mangle]
    9.25+    pub unsafe extern "C" fn $n(ptr: *const c_char) -> *mut $t {
    9.26+      assert!(!ptr.is_null());
    9.27+      let p = CStr::from_ptr(ptr).to_str().unwrap();
    9.28+      Box::into_raw(Box::new(p.into()))
    9.29+    }
    9.30+  };
    9.31+  (json_string $t:tt $r:tt $w:tt) => {
    9.32+    #[no_mangle]
    9.33+    pub unsafe extern "C" fn $r(ptr: *const c_char) -> *mut $t {
    9.34+      assert!(!ptr.is_null());
    9.35+      let s = CStr::from_ptr(ptr);
    9.36+      Box::into_raw(Box::new($t::from_json_str(&s.to_str().unwrap()).unwrap()))
    9.37+    }
    9.38+
    9.39+    #[no_mangle]
    9.40+    pub unsafe extern "C" fn $w(ptr: *const $t) -> *mut c_char {
    9.41+      let p = &*ptr;
    9.42+      let x = p.to_json_string().unwrap();
    9.43+      CString::new(x.as_str().as_bytes()).unwrap().into_raw()
    9.44+    }
    9.45+  };
    9.46+  (ron_string $t:tt $r:tt $w:tt) => {
    9.47+    #[no_mangle]
    9.48+    pub unsafe extern "C" fn $r(ptr: *const c_char) -> *mut $t {
    9.49+      assert!(!ptr.is_null());
    9.50+      let s = CStr::from_ptr(ptr);
    9.51+      Box::into_raw(Box::new($t::from_ron_str(&s.to_str().unwrap()).unwrap()))
    9.52+    }
    9.53+
    9.54+    #[no_mangle]
    9.55+    pub unsafe extern "C" fn $w(ptr: *const $t) -> *mut c_char {
    9.56+      let p = &*ptr;
    9.57+      let x = p.to_ron_string().unwrap();
    9.58+      CString::new(x.as_str().as_bytes()).unwrap().into_raw()
    9.59+    }
    9.60+  };
    9.61+  (bytes $t:tt $r:tt $w:tt) => {
    9.62+    #[no_mangle]
    9.63+    pub unsafe extern "C" fn $r(ptr: *const u8, len: size_t) -> *mut $t {
    9.64+      Box::into_raw(Box::new($t::decode(slice::from_raw_parts(ptr,len)).unwrap()))
    9.65+    }
    9.66+
    9.67+    #[no_mangle]
    9.68+    pub unsafe extern "C" fn $w(ptr: *const $t) -> *mut u8 {
    9.69+      let p = &*ptr;
    9.70+      let mut x = p.encode().unwrap();
    9.71+      let r = x.as_mut_ptr();
    9.72+      std::mem::forget(x);
    9.73+      r
    9.74+    }
    9.75+  }
    9.76+}
    9.77+
    9.78+cdefn!(free Service free_service);
    9.79+cdefn!(from_string Service service_from_string);
    9.80+cdefn!(json_string Service service_from_json_string service_to_json_string);
    9.81+cdefn!(ron_string Service service_from_ron_string service_to_ron_string);
    9.82+cdefn!(bytes Service service_decode service_encode);
    9.83+cdefn!(free CustomService free_custom_service);
    9.84+cdefn!(from_string CustomService custom_service_from_string);
    9.85+cdefn!(json_string CustomService custom_service_from_json_string custom_service_to_json_string);
    9.86+cdefn!(ron_string CustomService custom_service_from_ron_string custom_service_to_ron_string);
    9.87+cdefn!(bytes CustomService custom_service_decode custom_service_encode);
    10.1--- a/lib.rs	Sun May 07 01:32:31 2023 -0400
    10.2+++ b/lib.rs	Sun May 07 18:06:13 2023 -0400
    10.3@@ -1,3 +1,118 @@
    10.4-//! demo_ffi
    10.5-pub use obj::Service;
    10.6-pub use fig;
    10.7+//! demo/lib.rs --- generated by DEMO:RS-MACROEXPAND
    10.8+extern crate obj;
    10.9+extern crate libc;
   10.10+//pub use fig::*;
   10.11+use obj::{Objective,Service,CustomService};
   10.12+use std::ffi::{CStr, CString};
   10.13+use std::slice;
   10.14+use libc::{c_char, size_t};
   10.15+#[no_mangle]
   10.16+pub unsafe extern "C" fn free_service(ptr: *mut Service) {
   10.17+    if ptr.is_null() {
   10.18+        return;
   10.19+    }
   10.20+    let _ = Box::from_raw(ptr);
   10.21+}
   10.22+#[no_mangle]
   10.23+pub unsafe extern "C" fn service_from_string(ptr: *const c_char) -> *mut Service {
   10.24+  assert!(!ptr.is_null());
   10.25+  let p = CStr::from_ptr(ptr).to_str().unwrap();
   10.26+  Box::into_raw(Box::new(p.into()))
   10.27+}
   10.28+#[no_mangle]
   10.29+pub unsafe extern "C" fn service_from_json_string(ptr: *const c_char) -> *mut Service {
   10.30+  assert!(!ptr.is_null());
   10.31+  let s = CStr::from_ptr(ptr);
   10.32+  Box::into_raw(Box::new(Service::from_json_str(&s.to_str().unwrap()).unwrap()))
   10.33+}
   10.34+#[no_mangle]
   10.35+pub unsafe extern "C" fn service_to_json_string(ptr: *const Service) -> *mut c_char {
   10.36+    let p = &*ptr;
   10.37+    let x = p.to_json_string().unwrap();
   10.38+    CString::new(x.as_str().as_bytes()).unwrap().into_raw()
   10.39+}
   10.40+#[no_mangle]
   10.41+pub unsafe extern "C" fn service_from_ron_string(ptr: *const c_char) -> *mut Service {
   10.42+  assert!(!ptr.is_null());
   10.43+  let s = CStr::from_ptr(ptr);
   10.44+  Box::into_raw(Box::new(Service::from_ron_str(&s.to_str().unwrap()).unwrap()))
   10.45+}
   10.46+#[no_mangle]
   10.47+pub unsafe extern "C" fn service_to_ron_string(ptr: *const Service) -> *mut c_char {
   10.48+    let p = &*ptr;
   10.49+    let x = p.to_ron_string().unwrap();
   10.50+    CString::new(x.as_str().as_bytes()).unwrap().into_raw()
   10.51+}
   10.52+#[no_mangle]
   10.53+pub unsafe extern "C" fn service_decode(ptr: *const u8, len: size_t) -> *mut Service {
   10.54+    Box::into_raw(Box::new(Service::decode(slice::from_raw_parts(ptr, len)).unwrap()))
   10.55+}
   10.56+#[no_mangle]
   10.57+pub unsafe extern "C" fn service_encode(ptr: *const Service) -> *mut u8 {
   10.58+    let p = &*ptr;
   10.59+    let mut x = p.encode().unwrap();
   10.60+    let r = x.as_mut_ptr();
   10.61+    std::mem::forget(x);
   10.62+    r
   10.63+}
   10.64+#[no_mangle]
   10.65+pub unsafe extern "C" fn free_custom_service(ptr: *mut CustomService) {
   10.66+    if ptr.is_null() {
   10.67+        return;
   10.68+    }
   10.69+    let _ = Box::from_raw(ptr);
   10.70+}
   10.71+#[no_mangle]
   10.72+pub unsafe extern "C" fn custom_service_from_string(
   10.73+    ptr: *const c_char,
   10.74+) -> *mut CustomService {
   10.75+  assert!(!ptr.is_null());
   10.76+  let p = CStr::from_ptr(ptr).to_str().unwrap();
   10.77+  Box::into_raw(Box::new(p.into()))
   10.78+}
   10.79+#[no_mangle]
   10.80+pub unsafe extern "C" fn custom_service_from_json_string(ptr: *const c_char) -> *mut CustomService {
   10.81+  assert!(!ptr.is_null());
   10.82+  let s = CStr::from_ptr(ptr);
   10.83+  Box::into_raw(Box::new(CustomService::from_json_str(&s.to_str().unwrap()).unwrap()))}
   10.84+#[no_mangle]
   10.85+pub unsafe extern "C" fn custom_service_to_json_string(
   10.86+    ptr: *const CustomService,
   10.87+) -> *mut c_char {
   10.88+    let p = &*ptr;
   10.89+    let x = p.to_json_string().unwrap();
   10.90+    CString::new(x.as_str().as_bytes()).unwrap().into_raw()
   10.91+}
   10.92+#[no_mangle]
   10.93+pub unsafe extern "C" fn custom_service_from_ron_string(
   10.94+    ptr: *const c_char,
   10.95+) -> *mut CustomService {
   10.96+  assert!(!ptr.is_null());
   10.97+  let s = CStr::from_ptr(ptr);
   10.98+  Box::into_raw(Box::new(CustomService::from_ron_str(&s.to_str().unwrap()).unwrap()))
   10.99+}
  10.100+#[no_mangle]
  10.101+pub unsafe extern "C" fn custom_service_to_ron_string(
  10.102+    ptr: *const CustomService,
  10.103+) -> *mut c_char {
  10.104+    let p = &*ptr;
  10.105+    let x = p.to_ron_string().unwrap();
  10.106+    CString::new(x.as_str().as_bytes()).unwrap().into_raw()
  10.107+}
  10.108+#[no_mangle]
  10.109+pub unsafe extern "C" fn custom_service_decode(
  10.110+    ptr: *const u8,
  10.111+    len: size_t,
  10.112+) -> *mut CustomService {
  10.113+    Box::into_raw(
  10.114+        Box::new(CustomService::decode(slice::from_raw_parts(ptr, len)).unwrap()),
  10.115+    )
  10.116+}
  10.117+#[no_mangle]
  10.118+pub unsafe extern "C" fn custom_service_encode(ptr: *const CustomService) -> *mut u8 {
  10.119+    let p = &*ptr;
  10.120+    let mut x = p.encode().unwrap();
  10.121+    let r = x.as_mut_ptr();
  10.122+    std::mem::forget(x);
  10.123+    r
  10.124+}
    11.1--- a/makefile	Sun May 07 01:32:31 2023 -0400
    11.2+++ b/makefile	Sun May 07 18:06:13 2023 -0400
    11.3@@ -3,9 +3,10 @@
    11.4 .PHONY:build
    11.5 $(O):;mkdir -p $@
    11.6 clean:;rm -rf out *.fasl;cargo clean
    11.7+fmt:;scripts/fmt.ros
    11.8 build:;scripts/build.ros
    11.9 docs:;scripts/docs.ros
   11.10 test:;scripts/test.ros
   11.11 pack:;scripts/pack.ros
   11.12 check:;scripts/check.ros
   11.13-ci:clean build docs test pack;
   11.14+ci:clean fmt build docs test pack;
    12.1--- a/obj/src/lib.rs	Sun May 07 01:32:31 2023 -0400
    12.2+++ b/obj/src/lib.rs	Sun May 07 18:06:13 2023 -0400
    12.3@@ -5,13 +5,13 @@
    12.4 mod types;
    12.5 pub use types::*;
    12.6 
    12.7+pub use bincode;
    12.8 pub use ron;
    12.9-pub use bincode;
   12.10-pub use serde_json;
   12.11 use ron::extensions::Extensions;
   12.12 use serde::{de::DeserializeOwned, Deserialize, Serialize};
   12.13+pub use serde_json;
   12.14+use std::collections::{BTreeMap, HashMap};
   12.15 use std::io;
   12.16-use std::collections::{HashMap, BTreeMap};
   12.17 
   12.18 /// common trait for all config modules. This trait provides functions
   12.19 /// for de/serializing to/from RON, updating fields, and formatting.
   12.20@@ -39,7 +39,7 @@
   12.21     Ok(bincode::serialize_into(writer, self)?)
   12.22   }
   12.23 
   12.24-  fn decode<'a>(&self, bytes: &'a [u8]) -> Result<Self>
   12.25+  fn decode<'a>(bytes: &'a [u8]) -> Result<Self>
   12.26   where
   12.27     Self: Deserialize<'a>,
   12.28   {
   12.29@@ -130,5 +130,5 @@
   12.30 }
   12.31 
   12.32 impl<T> Objective for Vec<T> {}
   12.33-impl<K,V> Objective for HashMap<K,V> {}
   12.34-impl<K,V> Objective for BTreeMap<K,V> {}
   12.35+impl<K, V> Objective for HashMap<K, V> {}
   12.36+impl<K, V> Objective for BTreeMap<K, V> {}
    13.1--- a/obj/src/types.rs	Sun May 07 01:32:31 2023 -0400
    13.2+++ b/obj/src/types.rs	Sun May 07 18:06:13 2023 -0400
    13.3@@ -1,15 +1,55 @@
    13.4 //! obj/src/types.rs --- OBJ type descriptions used by our demo
    13.5-use crate::{Error, Result, Objective, Serialize, Deserialize};
    13.6+use crate::{Deserialize, Objective, Result, Serialize};
    13.7 /// APPLICATION TYPES
    13.8 #[derive(Serialize, Deserialize)]
    13.9 pub enum Service {
   13.10-  Nws,
   13.11-  Fin,
   13.12-  Pvp,
   13.13+  Weather,
   13.14+  Stocks,
   13.15+  Dynamic(Vec<Service>),
   13.16+  Custom(CustomService),
   13.17+  Test,
   13.18 }
   13.19 
   13.20 impl Objective for Service {}
   13.21 
   13.22+impl From<&str> for Service {
   13.23+  fn from(value: &str) -> Self {
   13.24+    match value {
   13.25+      "weather" => Service::Weather,
   13.26+      "stocks" => Service::Stocks,
   13.27+      "test" => Service::Test,
   13.28+      s => {
   13.29+        if s.contains(",") {
   13.30+          let x = s.split(",");
   13.31+          Service::Dynamic(
   13.32+            x.map(|y| Service::Custom(y.into()))
   13.33+              .collect::<Vec<Service>>(),
   13.34+          )
   13.35+        } else {
   13.36+          Service::Custom(s.into())
   13.37+        }
   13.38+      }
   13.39+    }
   13.40+  }
   13.41+}
   13.42+
   13.43+#[derive(Serialize, Deserialize)]
   13.44+pub struct CustomService {
   13.45+  name: String,
   13.46+}
   13.47+impl Objective for CustomService {}
   13.48+impl From<CustomService> for Service {
   13.49+  fn from(value: CustomService) -> Self {
   13.50+    Service::Custom(value)
   13.51+  }
   13.52+}
   13.53+impl From<&str> for CustomService {
   13.54+  fn from(value: &str) -> Self {
   13.55+    let name = value.to_owned();
   13.56+    CustomService { name }
   13.57+  }
   13.58+}
   13.59+
   13.60 #[derive(Serialize, Deserialize)]
   13.61 pub struct Complex<X: Objective> {
   13.62   data: X,
    14.1--- a/proc_macros/Cargo.toml	Sun May 07 01:32:31 2023 -0400
    14.2+++ b/proc_macros/Cargo.toml	Sun May 07 18:06:13 2023 -0400
    14.3@@ -2,10 +2,8 @@
    14.4 name = "proc_macros"
    14.5 version = "0.1.0"
    14.6 edition = "2021"
    14.7-
    14.8 [lib]
    14.9 proc-macro = true
   14.10-
   14.11 [dependencies]
   14.12 quote = "1.0"
   14.13 proc-macro2 = "1.0"
    15.1--- a/proc_macros/src/lib.rs	Sun May 07 01:32:31 2023 -0400
    15.2+++ b/proc_macros/src/lib.rs	Sun May 07 18:06:13 2023 -0400
    15.3@@ -0,0 +1,1 @@
    15.4+
    16.1--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2+++ b/scripts/fmt.ros	Sun May 07 18:06:13 2023 -0400
    16.3@@ -0,0 +1,18 @@
    16.4+#!/bin/sh
    16.5+#|-*- mode:lisp -*-|#
    16.6+#|
    16.7+exec ros -Q -- $0 "$@"
    16.8+|#
    16.9+(progn ;;init forms
   16.10+  (ros:ensure-asdf)
   16.11+  #+quicklisp(ql:quickload '() :silent t)
   16.12+  )
   16.13+
   16.14+(defpackage :ros.script.build.3891893519
   16.15+  (:use :cl))
   16.16+(in-package :ros.script.build.3891893519)
   16.17+
   16.18+(defun main (&rest argv)
   16.19+  (declare (ignorable argv))
   16.20+  (uiop:run-program "cargo fmt"))
   16.21+;;; vim: set ft=lisp lisp:
    17.1--- a/tk.lisp	Sun May 07 01:32:31 2023 -0400
    17.2+++ b/tk.lisp	Sun May 07 18:06:13 2023 -0400
    17.3@@ -2,7 +2,7 @@
    17.4 
    17.5 (defvar *cargo-target* #P"/Users/ellis/dev/otom8/demo/target/")
    17.6 
    17.7-(defmacro find-rust-dll (name &optional debug)
    17.8+(defmacro rs-find-dll (name &optional debug)
    17.9   "Find the rust dll specified by NAME."
   17.10   (cond
   17.11     ((uiop:directory-exists-p (merge-pathnames *cargo-target* "release"))
   17.12@@ -13,6 +13,13 @@
   17.13 	 (uiop:run-program `("cargo" "build" ,(unless debug "--release")) :output t)
   17.14 	 `,(find-rust-dll name debug)))))
   17.15 
   17.16+(defmacro rs-macroexpand (env &body body)
   17.17+  "Cbindgen is quite the menace and really doesn't like our macros used
   17.18+to generate C FFI bindings. To compensate for this, we use a tool
   17.19+called cargo-expand by the most excellent dtolnay which expands Rust
   17.20+macros. The expansions are assembled into an equivalent Rust source
   17.21+file which cbindgen won't get stuck in an infinite compile loop on.")
   17.22+
   17.23 (defun random-id ()
   17.24   (format NIL "~8,'0x-~8,'0x" (random #xFFFFFFFF) (get-universal-time)))
   17.25