1.1--- a/Cargo.toml Sat Jun 03 19:57:46 2023 -0400 1.2+++ b/Cargo.toml Sat Jun 03 22:48:46 2023 -0400 1.3@@ -1,14 +1,2 @@ 1.4-[package] 1.5-name = "demo" 1.6-version = "0.1.0" 1.7-build = "build.rs" 1.8-[lib] 1.9-path = "lib.rs" 1.10-crate-type = ["rlib","cdylib"] 1.11 [workspace] 1.12-members = ["obj","ui"] 1.13-[dependencies] 1.14-libc = "0.2" 1.15-obj = {version = "0.1.0",path = "obj"} 1.16-[build-dependencies] 1.17-cbindgen = "0.24.3" 1.18\ No newline at end of file 1.19+members = ["src/crates/obj","src/crates/ui"]
2.1--- a/Dockerfile Sat Jun 03 19:57:46 2023 -0400 2.2+++ b/Dockerfile Sat Jun 03 22:48:46 2023 -0400 2.3@@ -1,38 +1,10 @@ 2.4-ARG ROSWELL_IMAGE=fukamachi/roswell 2.5-ARG ROSWELL_VERSION 2.6-ARG OS=debian 2.7-FROM fukamachi/roswell:latest-$OS AS build-env 2.8-ARG OS 2.9+ARG OS=archlinux 2.10 ARG VERSION 2.11 ADD https://github.com/sbcl/sbcl/archive/sbcl-$VERSION.tar.gz sbcl.tar.gz 2.12 2.13 RUN set -x; \ 2.14- arch="$(case $(uname -m) in amd64|x86_64) echo x86-64;; aarch64) echo arm64;; *) uname -m ;; esac)"; \ 2.15- if [ "$OS" = "alpine" ]; then \ 2.16- apk add --update build-base linux-headers zstd-dev; \ 2.17- else \ 2.18- apt-get update && apt-get -y install --no-install-recommends \ 2.19- build-essential \ 2.20- zlib1g-dev \ 2.21- libzstd-dev \ 2.22- time; \ 2.23- fi; \ 2.24- ros install sbcl-bin/2.2.7 && \ 2.25 tar xvfz sbcl.tar.gz && rm sbcl.tar.gz && cd "sbcl-sbcl-${VERSION}" && \ 2.26- echo "\"$VERSION\"" > version.lisp-expr && \ 2.27- (sh make.sh \ 2.28- --with-sb-core-compression \ 2.29- "--xc-host=ros -L sbcl-bin without-roswell=t --no-rc run" \ 2.30- "--prefix=$HOME/.roswell/impls/$arch/linux/sbcl-bin/$VERSION/" || true) \ 2.31- && sh install.sh && \ 2.32- rm -f "/root/.roswell/impls/$arch/linux/sbcl-bin/$VERSION/lib/sbcl/sbcl.core.old" \ 2.33- && rm -f "/root/.roswell/impls/$arch/linux/sbcl-bin/$VERSION/bin/sbcl.old" \ 2.34- && find "/root/.roswell/impls/$arch/linux/sbcl-bin" -maxdepth 1 -mindepth 1 | grep -v "/sbcl-bin/$VERSION$" | xargs rm -rf || true \ 2.35- && rm -rf "/root/.roswell/impls/log" 2.36- 2.37-FROM $ROSWELL_IMAGE:$ROSWELL_VERSION-$OS 2.38-# hadolint ignore=DL3010 2.39-COPY --from=build-env /root/.roswell/impls /root/.roswell/impls 2.40+ echo "\"$VERSION\"" > version.s && \ 2.41 2.42 ARG BUILD_DATE 2.43 ARG VCS_REF 2.44@@ -41,25 +13,7 @@ 2.45 2.46 LABEL org.label-schema.build-date=$BUILD_DATE \ 2.47 org.label-schema.vcs-ref=$VCS_REF \ 2.48- org.label-schema.vcs-url="https://github.com/fukamachi/dockerfiles" \ 2.49 org.label-schema.version=$VERSION \ 2.50 org.label-schema.schema-version="1.0" 2.51 2.52-# hadolint ignore=DL3018 2.53-RUN set -x; \ 2.54- if [ "$OS" = "alpine" ]; then \ 2.55- apk add --update --no-cache zstd-libs; \ 2.56- fi; \ 2.57- printf "setup.time\t0\t%s\n" "$(( $(date +%s) + 2208988800 ))" > ~/.roswell/config && \ 2.58- printf "sbcl-bin.version\t0\t%s\n" "$VERSION" >> ~/.roswell/config && \ 2.59- printf "default.lisp\t0\tsbcl-bin\n" >> ~/.roswell/config && \ 2.60- ros setup && \ 2.61- ros -e '(mapc (function ql-dist:uninstall) (ql-dist:installed-releases t))' \ 2.62- && rm -f /root/.roswell/lisp/quicklisp/tmp/quicklisp.tar \ 2.63- && rm -rf /root/.roswell/archives/* /root/.roswell/src/sbcl-* /root/.cache/common-lisp/sbcl-*/root/.roswell/lisp/quicklisp/dists/quicklisp/software 2.64- 2.65-RUN set -x; \ 2.66- printf '#!/bin/sh\nexec ros run -- "$@"\n' > /usr/local/bin/sbcl \ 2.67- && chmod u+x /usr/local/bin/sbcl 2.68- 2.69 ENTRYPOINT ["/usr/local/bin/sbcl"] 2.70\ No newline at end of file
3.1--- a/build.rs Sat Jun 03 19:57:46 2023 -0400 3.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 3.3@@ -1,17 +0,0 @@ 3.4-use std::env; 3.5-use std::fs::create_dir; 3.6-use std::path::PathBuf; 3.7-fn main() { 3.8- let crate_dir: PathBuf = env::var("CARGO_MANIFEST_DIR") 3.9- .expect("CARGO_MANIFEST_DIR env var is not defined") 3.10- .into(); 3.11- // let mpk_py = "build.py"; 3.12- let build_dir = crate_dir.join("ffi/"); 3.13- if !build_dir.exists() { 3.14- create_dir(&build_dir).unwrap(); 3.15- } 3.16- cbindgen::generate(crate_dir) 3.17- .expect("Unable to find cbindgen.toml configuration file") 3.18- .write_to_file(build_dir.join("demo.h")); 3.19- 3.20-}
4.1--- a/cbindgen.toml Sat Jun 03 19:57:46 2023 -0400 4.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 4.3@@ -1,14 +0,0 @@ 4.4-include_guard = "demo_h" 4.5-autogen_warning = "/* DO NOT TOUCH */" 4.6-include_version = true 4.7-language = "C" 4.8-cpp_compat = true 4.9-line_length = 88 4.10-documentation = true 4.11-[parse] 4.12-parse_deps = true 4.13-include = ["obj","fig","libc"] 4.14-extra_bindings = ["obj","fig","libc"] 4.15-#expand = ["demo","obj"] 4.16-#[parse.expand] 4.17-#crates = ["demo"] 4.18\ No newline at end of file
6.1--- a/db.lisp Sat Jun 03 19:57:46 2023 -0400 6.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 6.3@@ -1,197 +0,0 @@ 6.4-(in-package :demo) 6.5- 6.6-(define-foreign-library rocksdb 6.7- (:win32 "rocksdb") 6.8- (t (:default "librocksdb"))) 6.9- 6.10-(use-foreign-library rocksdb) 6.11- 6.12-(defcfun ("rocksdb_options_create" create-options) :pointer) 6.13-(defcfun ("rocksdb_options_destroy" destroy-options) :void (options :pointer)) 6.14-(defcfun ("rocksdb_options_increase_parallelism" increase-parallelism) :void (opt :pointer) (total-threads :int)) 6.15-(defcfun ("rocksdb_options_optimize_level_style_compaction" optimize-level-style-compaction) :void (opt :pointer) (memtable_memory_budget :uint64)) 6.16-(defcfun ("rocksdb_options_set_create_if_missing" set-create-if-missing) :void (opt :pointer) (val :boolean)) 6.17- 6.18-(defcfun ("rocksdb_writeoptions_create" create-writeoptions) :pointer) 6.19-(defcfun ("rocksdb_writeoptions_destroy" destroy-writeoptions) :void (opt :pointer)) 6.20-(defcfun ("rocksdb_readoptions_create" create-readoptions) :pointer) 6.21-(defcfun ("rocksdb_readoptions_destroy" destroy-readoptions) :void (opt :pointer)) 6.22- 6.23-(defcfun ("rocksdb_open" open-db*) :pointer (opt :pointer) (name :string) (errptr :pointer)) 6.24-(defcfun ("rocksdb_close" close-db) :void (opt :pointer)) 6.25-(defcfun ("rocksdb_cancel_all_background_work" cancel-all-background-work) :void (db :pointer) (wait :boolean)) 6.26- 6.27-(defcfun ("rocksdb_put" put*) :void (db :pointer) (options :pointer) (key :pointer) (keylen :unsigned-int) (val :pointer) (vallen :unsigned-int) (errptr :pointer)) 6.28-(defcfun ("rocksdb_get" get*) :pointer (db :pointer) (options :pointer) (key :pointer) (keylen :unsigned-int) (vallen :pointer) (errptr :pointer)) 6.29- 6.30-(defcfun ("rocksdb_create_iterator" create-iter*) :pointer (db :pointer) (opt :pointer)) 6.31-(defcfun ("rocksdb_iter_destroy" destroy-iter) :void (iter :pointer)) 6.32-(defcfun ("rocksdb_iter_seek_to_first" move-iter-to-first) :void (iter :pointer)) 6.33-(defcfun ("rocksdb_iter_valid" valid-iter-p) :boolean (iter :pointer)) 6.34-(defcfun ("rocksdb_iter_next" move-iter-forward) :void (iter :pointer)) 6.35-(defcfun ("rocksdb_iter_prev" move-iter-backward) :void (iter :pointer)) 6.36-(defcfun ("rocksdb_iter_key" iter-key*) :pointer (iter :pointer) (klen-ptr :pointer)) 6.37-(defcfun ("rocksdb_iter_value" iter-value*) :pointer (iter :pointer) (vlen-ptr :pointer)) 6.38- 6.39-(define-condition unable-to-open-db (error) 6.40- ((db-path :initarg :db-path 6.41- :reader db-path) 6.42- (error-message :initarg :error-message 6.43- :reader error-message))) 6.44- 6.45-(defmethod print-object ((obj unable-to-open-db) stream) 6.46- (print-unreadable-object (obj stream :type t :identity t) 6.47- (format stream "error-message=~A" (error-message obj)))) 6.48- 6.49-(define-condition unable-to-put-key-value-to-db (error) 6.50- ((db :initarg :db 6.51- :reader db) 6.52- (key :initarg :key 6.53- :reader key) 6.54- (val :initarg :val 6.55- :reader val) 6.56- (error-message :initarg :error-message 6.57- :reader error-message))) 6.58- 6.59-(define-condition unable-to-get-value-to-db (error) 6.60- ((db :initarg :db 6.61- :reader db) 6.62- (key :initarg :key 6.63- :reader key) 6.64- (error-message :initarg :error-message 6.65- :reader error-message))) 6.66- 6.67-(defun open-db (db-path &optional opt) 6.68- (unless opt 6.69- (setq opt (create-options))) 6.70- (let ((errptr (foreign-alloc :pointer))) 6.71- (setf (mem-ref errptr :pointer) (null-pointer)) 6.72- (let* ((db-path (if (pathnamep db-path) 6.73- (namestring db-path) 6.74- db-path)) 6.75- (db (open-db* opt db-path errptr)) 6.76- (err (mem-ref errptr :pointer))) 6.77- (unless (null-pointer-p err) 6.78- (error 'unable-to-open-db 6.79- :db-path db-path 6.80- :error-message (foreign-string-to-lisp err))) 6.81- db))) 6.82- 6.83-(defmacro clone-octets-to-foreign (lisp-array foreign-array) 6.84- (let ((i (gensym))) 6.85- `(loop for ,i from 0 below (length ,lisp-array) 6.86- do (setf (mem-aref ,foreign-array :unsigned-char ,i) 6.87- (aref ,lisp-array ,i))))) 6.88- 6.89-(defmacro clone-octets-from-foreign (foreign-array lisp-array len) 6.90- (let ((i (gensym))) 6.91- `(loop for ,i from 0 below ,len 6.92- do (setf (aref ,lisp-array ,i) 6.93- (mem-aref ,foreign-array :unsigned-char ,i))))) 6.94- 6.95-(defun put-kv (db key val &optional opt) 6.96- (unless opt 6.97- (setq opt (create-writeoptions))) 6.98- (with-foreign-objects ((errptr :pointer) 6.99- (key* :unsigned-char (length key)) 6.100- (val* :unsigned-char (length val))) 6.101- (clone-octets-to-foreign key key*) 6.102- (clone-octets-to-foreign val val*) 6.103- (setf (mem-ref errptr :pointer) (null-pointer)) 6.104- (put* db 6.105- opt 6.106- key* 6.107- (length key) 6.108- val* 6.109- (length val) 6.110- errptr) 6.111- (let ((err (mem-ref errptr :pointer))) 6.112- (unless (null-pointer-p err) 6.113- (error 'unable-to-put-key-value-to-db 6.114- :db db 6.115- :key key 6.116- :val val 6.117- :error-message (foreign-string-to-lisp err)))))) 6.118- 6.119-(defun put-kv-str (db key val &optional opt) 6.120- (let ((key-octets (babel:string-to-octets key)) 6.121- (val-octets (babel:string-to-octets val))) 6.122- (put-kv db key-octets val-octets opt))) 6.123- 6.124-(defun get-kv (db key &optional opt) 6.125- (unless opt 6.126- (setq opt (create-readoptions))) 6.127- 6.128- (with-foreign-objects ((val-len-ptr :unsigned-int) 6.129- (errptr :pointer) 6.130- (key* :unsigned-char (length key))) 6.131- (clone-octets-to-foreign key key*) 6.132- (setf (mem-ref errptr :pointer) (null-pointer)) 6.133- (let ((val (get* db 6.134- opt 6.135- key* 6.136- (length key) 6.137- val-len-ptr 6.138- errptr))) 6.139- (let ((err (mem-ref errptr :pointer))) 6.140- (unless (null-pointer-p err) 6.141- (error 'unable-to-get-value-to-db 6.142- :db db 6.143- :key key 6.144- :error-message (foreign-string-to-lisp err))) 6.145- 6.146- (unless (null-pointer-p val) 6.147- (let* ((val-len (mem-ref val-len-ptr :unsigned-int)) 6.148- (val* (make-array val-len 6.149- :element-type '(unsigned-byte 8)))) 6.150- (clone-octets-from-foreign val val* val-len) 6.151- val*)))))) 6.152- 6.153-(defun get-kv-str (db key &optional opt) 6.154- (let ((key-octets (babel:string-to-octets key))) 6.155- (let ((#1=val-octets (get-kv db key-octets opt))) 6.156- (when #1# 6.157- (babel:octets-to-string #1#))))) 6.158- 6.159-(defun create-iter (db &optional opt) 6.160- (unless opt 6.161- (setq opt (create-readoptions))) 6.162- (create-iter* db opt)) 6.163- 6.164-(defun iter-key (iter) 6.165- (with-foreign-objects ((klen-ptr :unsigned-int)) 6.166- (setf (mem-ref klen-ptr :unsigned-int) 0) 6.167- (let* ((key-ptr (iter-key* iter klen-ptr)) 6.168- (klen (mem-ref klen-ptr :unsigned-int)) 6.169- (key (make-array klen :element-type '(unsigned-byte 8)))) 6.170- (clone-octets-from-foreign key-ptr key klen) 6.171- key))) 6.172- 6.173-(defun iter-key-str (iter) 6.174- (let ((#1=key-octets (iter-key iter))) 6.175- (when #1# 6.176- (babel:octets-to-string #1#)))) 6.177- 6.178-(defun iter-value (iter) 6.179- (with-foreign-objects ((len-ptr :unsigned-int)) 6.180- (setf (mem-ref len-ptr :unsigned-int) 0) 6.181- (let* ((value-ptr (iter-value* iter len-ptr)) 6.182- (vlen (mem-ref len-ptr :unsigned-int)) 6.183- (value* (make-array vlen :element-type '(unsigned-byte 8)))) 6.184- (clone-octets-from-foreign value-ptr value* vlen) 6.185- value*))) 6.186- 6.187-(defun iter-value-str (iter) 6.188- (let ((#1=val-octets (iter-value iter))) 6.189- (when #1# 6.190- (babel:octets-to-string #1#)))) 6.191- 6.192-(defmacro with-open-db ((db-var db-path &optional opt) &body body) 6.193- `(let ((,db-var (open-db ,db-path ,opt))) 6.194- (unwind-protect (progn ,@body) 6.195- (close-db ,db-var)))) 6.196- 6.197-(defmacro with-iter ((iter-var db &optional opt) &body body) 6.198- `(let ((,iter-var (create-iter ,db ,opt))) 6.199- (unwind-protect (progn ,@body) 6.200- (destroy-iter ,iter-var))))
7.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2+++ b/default.cfg Sat Jun 03 22:48:46 2023 -0400 7.3@@ -0,0 +1,11 @@ 7.4+;;; default-config.se --- Default demo configuration -*- mode: lisp-data -*- 7.5+ 7.6+;; The configuration for this demo is specified in S-Expressions. 7.7+;; Check 'docs/config.org' for available options. 7.8+(:service "weather" 7.9+ :host "localhost" 7.10+ :port 8888 7.11+ :client (:name "guest" 7.12+ :type "docker" 7.13+ :mode "release" 7.14+ :theme "dark"))
8.1--- a/demo.asd Sat Jun 03 19:57:46 2023 -0400 8.2+++ b/demo.asd Sat Jun 03 22:48:46 2023 -0400 8.3@@ -31,13 +31,8 @@ 8.4 :build-pathname "demo" 8.5 :entry-point "demo:main") 8.6 8.7-;; (asdf:defsystem "cl-demo:tests" 8.8- ;; :depends-on ("cl-demo" "fiveam") 8.9+;; (asdf:defsystem "demo.tests" 8.10+ ;; :depends-on ("demo" "fiveam") 8.11 ;; :components ((:file "tests")) 8.12- ;; :perform (test-op (o c) (symbol-call :fiveam '#:run! :cl-demo)) 8.13+ ;; :perform (test-op (o c) (symbol-call :fiveam '#:run! "demo:main")) 8.14 ;; ) 8.15- 8.16-;; (deploy:define-library cl+ssl::libssl 8.17-;; :path "/usr/local/Cellar/openssl@3/3.1.1/lib/libssl.dylib") 8.18-;; (deploy:define-library cl+ssl::libcrypto 8.19-;; :path "/usr/local/Cellar/openssl@3/3.1.1/lib/libcrypto.dylib")
9.1--- a/demo.lisp Sat Jun 03 19:57:46 2023 -0400 9.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 9.3@@ -1,45 +0,0 @@ 9.4-;; demo.lisp 9.5-(in-package :demo) 9.6- 9.7-(defparameter demo-path (merge-pathnames "cl-demo" (uiop:temporary-directory))) 9.8- 9.9-(defvar db-path (merge-pathnames "db" demo-path)) 9.10- 9.11-(defun cli-opts () 9.12- "Returns the top-level CLI options." 9.13- (list 9.14- (cli:make-option 9.15- :string 9.16- :description "demo app to run" 9.17- :short-name #\x 9.18- :long-name "app" 9.19- :initial-value "client" 9.20- :env-vars '("DEMO_APP") 9.21- :key :app) 9.22- (cli:make-option 9.23- :string 9.24- :description "path to config" 9.25- :short-name #\c 9.26- :long-name "config" 9.27- :initial-value "$DEMO_PATH/.fig" 9.28- :env-vars '("DEMO_CONFIG")))) 9.29- 9.30-(defun cli-handler (cmd) 9.31- "Handler for the `demo' command." 9.32- (let ((app (cli:getopt cmd :app))) 9.33- (format t "running: ~A!~%" app))) 9.34- 9.35-(defun cli-cmd () 9.36- "Our demo command." 9.37- (cli:make-command 9.38- :name "demo" 9.39- :description "A collection of demos" 9.40- :version "1.0.0" 9.41- :authors '("ellis <ellis@rwest.io>") 9.42- :license "WTFPL" 9.43- :options (cli-opts) 9.44- :handler #'cli-handler)) 9.45- 9.46-(defun main () 9.47- "A demo of some common-lisp functionality." 9.48- (cli:run (cli-cmd)))
10.1--- a/ffi.lisp Sat Jun 03 19:57:46 2023 -0400 10.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 10.3@@ -1,28 +0,0 @@ 10.4-(in-package :demo) 10.5-(defparameter quiche-lib-path #p"./ffi/libquiche.dylib") 10.6-;;(defparameter rocksdb-lib-path #p"./ffi/librocksdb.dylib") 10.7-(defparameter demo-lib-path (find-rs-cdylib "libdemo.dylib")) 10.8-(defmacro find-rs-cdylib (name &optional debug) 10.9- "Find the rust dll specified by NAME." 10.10- (cond 10.11- ((uiop:directory-exists-p (merge-pathnames *cargo-target* "release")) 10.12- `,(mkstr "./target/release/" name)) 10.13- ((uiop:directory-exists-p (merge-pathnames *cargo-target* "debug")) 10.14- `,(mkstr "./target/debug/" name)) 10.15- (t `(progn 10.16- ,(uiop:run-program '("cargo" "build" (unless debug "--release")) :output t) 10.17- (find-rs-cdylib ,name ,debug))))) 10.18- 10.19-(define-foreign-library demo 10.20- (:win32 (:default "demo")) 10.21- (t (:default "libdemo"))) 10.22-(define-foreign-library quiche 10.23- (:win32 (:default "quiche")) 10.24- (t (:default "libquiche"))) 10.25-;; (define-foreign-library rocksdb 10.26-;; (:win32 (:default "rocksdb")) 10.27-;; (t (:default "librocksdb"))) 10.28- 10.29-(defun load-libdemo () (load-foreign-library (find-rs-cdylib "libdemo.dylib"))) 10.30-(defun install-quiche-lib (&optional path) (load-foreign-library (or path quiche-lib-path))) 10.31-;; (defun install-rocksdb-lib (&optional path) (load-foreign-library (or path rocksdb-lib-path)))
11.1--- a/ffi/build.py Sat Jun 03 19:57:46 2023 -0400 11.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 11.3@@ -1,48 +0,0 @@ 11.4-try: 11.5- from cffi import FFI 11.6-except ImportError: 11.7- print("pip install cffi, included with PyPy") 11.8- 11.9-import os 11.10-import re 11.11-import pathlib 11.12- 11.13- 11.14-def parse_header(header): 11.15- h = open(header, "r").read().lstrip() 11.16- cdef = re.sub( 11.17- r"^(#|\s*\/*\*|extern).*[\r\n]|.*\"C\"$|^(?:[\t ]*(?:\r?\n|\r))+", 11.18- "", 11.19- h, 11.20- flags=re.MULTILINE, 11.21- ) 11.22- return cdef 11.23- 11.24- 11.25-def init_ffi(cdef): 11.26- ffi = FFI() 11.27- ffi.set_source( 11.28- "_demo", 11.29- """ 11.30- #include "demo.h" 11.31- """, 11.32-# libraries=["demo"], 11.33- library_dirs=["."], 11.34- include_dirs=["."], 11.35- ) 11.36- 11.37- ffi.cdef(cdef) 11.38- 11.39- return ffi 11.40- 11.41- 11.42-def compile(ffi, lib_dir, v): 11.43- os.environ["LD_RUN_PATH"] = os.path.abspath(lib_dir) 11.44- ffi.compile(verbose=v) 11.45- 11.46- 11.47-if __name__ == "__main__": 11.48- build_dir = pathlib.Path(__file__).parent 11.49- cdef = parse_header(build_dir / "demo.h") 11.50- print(cdef) 11.51- compile(init_ffi(cdef), build_dir, True)
12.1--- a/ffi/demo.h Sat Jun 03 19:57:46 2023 -0400 12.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 12.3@@ -1,66 +0,0 @@ 12.4-#ifndef demo_h 12.5-#define demo_h 12.6- 12.7-/* Generated with cbindgen:0.24.3 */ 12.8- 12.9-/* DO NOT TOUCH */ 12.10- 12.11-#include <stdarg.h> 12.12-#include <stdbool.h> 12.13-#include <stdint.h> 12.14-#include <stdlib.h> 12.15- 12.16-#define KEY_LEN 32 12.17- 12.18-#define OUT_LEN 32 12.19- 12.20-#define OUT_LEN_HEX (OUT_LEN * 2) 12.21- 12.22-typedef struct CustomService CustomService; 12.23- 12.24-/** 12.25- * APPLICATION TYPES 12.26- */ 12.27-typedef struct Service Service; 12.28- 12.29-#ifdef __cplusplus 12.30-extern "C" { 12.31-#endif // __cplusplus 12.32- 12.33-void free_service(struct Service *ptr); 12.34- 12.35-struct Service *service_from_string(const char *ptr); 12.36- 12.37-struct Service *service_from_json_string(const char *ptr); 12.38- 12.39-char *service_to_json_string(const struct Service *ptr); 12.40- 12.41-struct Service *service_from_ron_string(const char *ptr); 12.42- 12.43-char *service_to_ron_string(const struct Service *ptr); 12.44- 12.45-struct Service *service_decode(const uint8_t *ptr, size_t len); 12.46- 12.47-uint8_t *service_encode(const struct Service *ptr); 12.48- 12.49-void free_custom_service(struct CustomService *ptr); 12.50- 12.51-struct CustomService *custom_service_from_string(const char *ptr); 12.52- 12.53-struct CustomService *custom_service_from_json_string(const char *ptr); 12.54- 12.55-char *custom_service_to_json_string(const struct CustomService *ptr); 12.56- 12.57-struct CustomService *custom_service_from_ron_string(const char *ptr); 12.58- 12.59-char *custom_service_to_ron_string(const struct CustomService *ptr); 12.60- 12.61-struct CustomService *custom_service_decode(const uint8_t *ptr, size_t len); 12.62- 12.63-uint8_t *custom_service_encode(const struct CustomService *ptr); 12.64- 12.65-#ifdef __cplusplus 12.66-} // extern "C" 12.67-#endif // __cplusplus 12.68- 12.69-#endif /* demo_h */
13.1--- a/ffi/quiche.h Sat Jun 03 19:57:46 2023 -0400 13.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 13.3@@ -1,973 +0,0 @@ 13.4-// Copyright (C) 2018-2019, Cloudflare, Inc. 13.5-// All rights reserved. 13.6-// 13.7-// Redistribution and use in source and binary forms, with or without 13.8-// modification, are permitted provided that the following conditions are 13.9-// met: 13.10-// 13.11-// * Redistributions of source code must retain the above copyright 13.12-// notice, this list of conditions and the following disclaimer. 13.13-// 13.14-// * Redistributions in binary form must reproduce the above copyright 13.15-// notice, this list of conditions and the following disclaimer in the 13.16-// documentation and/or other materials provided with the distribution. 13.17-// 13.18-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 13.19-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 13.20-// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 13.21-// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 13.22-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 13.23-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 13.24-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 13.25-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 13.26-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 13.27-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 13.28-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13.29- 13.30-#ifndef QUICHE_H 13.31-#define QUICHE_H 13.32- 13.33-#if defined(__cplusplus) 13.34-extern "C" { 13.35-#endif 13.36- 13.37-#include <stdint.h> 13.38-#include <stdbool.h> 13.39-#include <stddef.h> 13.40- 13.41-#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) 13.42-#include <winsock2.h> 13.43-#include <ws2tcpip.h> 13.44-#include <time.h> 13.45-#else 13.46-#include <sys/socket.h> 13.47-#include <sys/time.h> 13.48-#endif 13.49- 13.50-#ifdef __unix__ 13.51-#include <sys/types.h> 13.52-#endif 13.53-#ifdef _MSC_VER 13.54-#include <BaseTsd.h> 13.55-#define ssize_t SSIZE_T 13.56-#endif 13.57- 13.58-// QUIC transport API. 13.59-// 13.60- 13.61-// The current QUIC wire version. 13.62-#define QUICHE_PROTOCOL_VERSION 0x00000001 13.63- 13.64-// The maximum length of a connection ID. 13.65-#define QUICHE_MAX_CONN_ID_LEN 20 13.66- 13.67-// The minimum length of Initial packets sent by a client. 13.68-#define QUICHE_MIN_CLIENT_INITIAL_LEN 1200 13.69- 13.70-enum quiche_error { 13.71- // There is no more work to do. 13.72- QUICHE_ERR_DONE = -1, 13.73- 13.74- // The provided buffer is too short. 13.75- QUICHE_ERR_BUFFER_TOO_SHORT = -2, 13.76- 13.77- // The provided packet cannot be parsed because its version is unknown. 13.78- QUICHE_ERR_UNKNOWN_VERSION = -3, 13.79- 13.80- // The provided packet cannot be parsed because it contains an invalid 13.81- // frame. 13.82- QUICHE_ERR_INVALID_FRAME = -4, 13.83- 13.84- // The provided packet cannot be parsed. 13.85- QUICHE_ERR_INVALID_PACKET = -5, 13.86- 13.87- // The operation cannot be completed because the connection is in an 13.88- // invalid state. 13.89- QUICHE_ERR_INVALID_STATE = -6, 13.90- 13.91- // The operation cannot be completed because the stream is in an 13.92- // invalid state. 13.93- QUICHE_ERR_INVALID_STREAM_STATE = -7, 13.94- 13.95- // The peer's transport params cannot be parsed. 13.96- QUICHE_ERR_INVALID_TRANSPORT_PARAM = -8, 13.97- 13.98- // A cryptographic operation failed. 13.99- QUICHE_ERR_CRYPTO_FAIL = -9, 13.100- 13.101- // The TLS handshake failed. 13.102- QUICHE_ERR_TLS_FAIL = -10, 13.103- 13.104- // The peer violated the local flow control limits. 13.105- QUICHE_ERR_FLOW_CONTROL = -11, 13.106- 13.107- // The peer violated the local stream limits. 13.108- QUICHE_ERR_STREAM_LIMIT = -12, 13.109- 13.110- // The specified stream was stopped by the peer. 13.111- QUICHE_ERR_STREAM_STOPPED = -15, 13.112- 13.113- // The specified stream was reset by the peer. 13.114- QUICHE_ERR_STREAM_RESET = -16, 13.115- 13.116- // The received data exceeds the stream's final size. 13.117- QUICHE_ERR_FINAL_SIZE = -13, 13.118- 13.119- // Error in congestion control. 13.120- QUICHE_ERR_CONGESTION_CONTROL = -14, 13.121- 13.122- // Too many identifiers were provided. 13.123- QUICHE_ERR_ID_LIMIT = -17, 13.124- 13.125- // Not enough available identifiers. 13.126- QUICHE_ERR_OUT_OF_IDENTIFIERS = -18, 13.127- 13.128- // Error in key update. 13.129- QUICHE_ERR_KEY_UPDATE = -19, 13.130-}; 13.131- 13.132-// Returns a human readable string with the quiche version number. 13.133-const char *quiche_version(void); 13.134- 13.135-// Enables logging. |cb| will be called with log messages 13.136-int quiche_enable_debug_logging(void (*cb)(const char *line, void *argp), 13.137- void *argp); 13.138- 13.139-// Stores configuration shared between multiple connections. 13.140-typedef struct quiche_config quiche_config; 13.141- 13.142-// Creates a config object with the given version. 13.143-quiche_config *quiche_config_new(uint32_t version); 13.144- 13.145-// Configures the given certificate chain. 13.146-int quiche_config_load_cert_chain_from_pem_file(quiche_config *config, 13.147- const char *path); 13.148- 13.149-// Configures the given private key. 13.150-int quiche_config_load_priv_key_from_pem_file(quiche_config *config, 13.151- const char *path); 13.152- 13.153-// Specifies a file where trusted CA certificates are stored for the purposes of certificate verification. 13.154-int quiche_config_load_verify_locations_from_file(quiche_config *config, 13.155- const char *path); 13.156- 13.157-// Specifies a directory where trusted CA certificates are stored for the purposes of certificate verification. 13.158-int quiche_config_load_verify_locations_from_directory(quiche_config *config, 13.159- const char *path); 13.160- 13.161-// Configures whether to verify the peer's certificate. 13.162-void quiche_config_verify_peer(quiche_config *config, bool v); 13.163- 13.164-// Configures whether to send GREASE. 13.165-void quiche_config_grease(quiche_config *config, bool v); 13.166- 13.167-// Enables logging of secrets. 13.168-void quiche_config_log_keys(quiche_config *config); 13.169- 13.170-// Enables sending or receiving early data. 13.171-void quiche_config_enable_early_data(quiche_config *config); 13.172- 13.173-// Configures the list of supported application protocols. 13.174-int quiche_config_set_application_protos(quiche_config *config, 13.175- const uint8_t *protos, 13.176- size_t protos_len); 13.177- 13.178-// Sets the `max_idle_timeout` transport parameter, in milliseconds, default is 13.179-// no timeout. 13.180-void quiche_config_set_max_idle_timeout(quiche_config *config, uint64_t v); 13.181- 13.182-// Sets the `max_udp_payload_size transport` parameter. 13.183-void quiche_config_set_max_recv_udp_payload_size(quiche_config *config, size_t v); 13.184- 13.185-// Sets the maximum outgoing UDP payload size. 13.186-void quiche_config_set_max_send_udp_payload_size(quiche_config *config, size_t v); 13.187- 13.188-// Sets the `initial_max_data` transport parameter. 13.189-void quiche_config_set_initial_max_data(quiche_config *config, uint64_t v); 13.190- 13.191-// Sets the `initial_max_stream_data_bidi_local` transport parameter. 13.192-void quiche_config_set_initial_max_stream_data_bidi_local(quiche_config *config, uint64_t v); 13.193- 13.194-// Sets the `initial_max_stream_data_bidi_remote` transport parameter. 13.195-void quiche_config_set_initial_max_stream_data_bidi_remote(quiche_config *config, uint64_t v); 13.196- 13.197-// Sets the `initial_max_stream_data_uni` transport parameter. 13.198-void quiche_config_set_initial_max_stream_data_uni(quiche_config *config, uint64_t v); 13.199- 13.200-// Sets the `initial_max_streams_bidi` transport parameter. 13.201-void quiche_config_set_initial_max_streams_bidi(quiche_config *config, uint64_t v); 13.202- 13.203-// Sets the `initial_max_streams_uni` transport parameter. 13.204-void quiche_config_set_initial_max_streams_uni(quiche_config *config, uint64_t v); 13.205- 13.206-// Sets the `ack_delay_exponent` transport parameter. 13.207-void quiche_config_set_ack_delay_exponent(quiche_config *config, uint64_t v); 13.208- 13.209-// Sets the `max_ack_delay` transport parameter. 13.210-void quiche_config_set_max_ack_delay(quiche_config *config, uint64_t v); 13.211- 13.212-// Sets the `disable_active_migration` transport parameter. 13.213-void quiche_config_set_disable_active_migration(quiche_config *config, bool v); 13.214- 13.215-enum quiche_cc_algorithm { 13.216- QUICHE_CC_RENO = 0, 13.217- QUICHE_CC_CUBIC = 1, 13.218- QUICHE_CC_BBR = 2, 13.219-}; 13.220- 13.221-// Sets the congestion control algorithm used. 13.222-void quiche_config_set_cc_algorithm(quiche_config *config, enum quiche_cc_algorithm algo); 13.223- 13.224-// Configures whether to use HyStart++. 13.225-void quiche_config_enable_hystart(quiche_config *config, bool v); 13.226- 13.227-// Configures whether to enable pacing (enabled by default). 13.228-void quiche_config_enable_pacing(quiche_config *config, bool v); 13.229- 13.230-// Configures max pacing rate to be used. 13.231-void quiche_config_set_max_pacing_rate(quiche_config *config, uint64_t v); 13.232- 13.233-// Configures whether to enable receiving DATAGRAM frames. 13.234-void quiche_config_enable_dgram(quiche_config *config, bool enabled, 13.235- size_t recv_queue_len, 13.236- size_t send_queue_len); 13.237- 13.238-// Sets the maximum connection window. 13.239-void quiche_config_set_max_connection_window(quiche_config *config, uint64_t v); 13.240- 13.241-// Sets the maximum stream window. 13.242-void quiche_config_set_max_stream_window(quiche_config *config, uint64_t v); 13.243- 13.244-// Sets the limit of active connection IDs. 13.245-void quiche_config_set_active_connection_id_limit(quiche_config *config, uint64_t v); 13.246- 13.247-// Sets the initial stateless reset token. |v| must contain 16 bytes, otherwise the behaviour is undefined. 13.248-void quiche_config_set_stateless_reset_token(quiche_config *config, const uint8_t *v); 13.249- 13.250-// Frees the config object. 13.251-void quiche_config_free(quiche_config *config); 13.252- 13.253-// Extracts version, type, source / destination connection ID and address 13.254-// verification token from the packet in |buf|. 13.255-int quiche_header_info(const uint8_t *buf, size_t buf_len, size_t dcil, 13.256- uint32_t *version, uint8_t *type, 13.257- uint8_t *scid, size_t *scid_len, 13.258- uint8_t *dcid, size_t *dcid_len, 13.259- uint8_t *token, size_t *token_len); 13.260- 13.261-// A QUIC connection. 13.262-typedef struct quiche_conn quiche_conn; 13.263- 13.264-// Creates a new server-side connection. 13.265-quiche_conn *quiche_accept(const uint8_t *scid, size_t scid_len, 13.266- const uint8_t *odcid, size_t odcid_len, 13.267- const struct sockaddr *local, size_t local_len, 13.268- const struct sockaddr *peer, size_t peer_len, 13.269- quiche_config *config); 13.270- 13.271-// Creates a new client-side connection. 13.272-quiche_conn *quiche_connect(const char *server_name, 13.273- const uint8_t *scid, size_t scid_len, 13.274- const struct sockaddr *local, size_t local_len, 13.275- const struct sockaddr *peer, size_t peer_len, 13.276- quiche_config *config); 13.277- 13.278-// Writes a version negotiation packet. 13.279-ssize_t quiche_negotiate_version(const uint8_t *scid, size_t scid_len, 13.280- const uint8_t *dcid, size_t dcid_len, 13.281- uint8_t *out, size_t out_len); 13.282- 13.283-// Writes a retry packet. 13.284-ssize_t quiche_retry(const uint8_t *scid, size_t scid_len, 13.285- const uint8_t *dcid, size_t dcid_len, 13.286- const uint8_t *new_scid, size_t new_scid_len, 13.287- const uint8_t *token, size_t token_len, 13.288- uint32_t version, uint8_t *out, size_t out_len); 13.289- 13.290-// Returns true if the given protocol version is supported. 13.291-bool quiche_version_is_supported(uint32_t version); 13.292- 13.293-quiche_conn *quiche_conn_new_with_tls(const uint8_t *scid, size_t scid_len, 13.294- const uint8_t *odcid, size_t odcid_len, 13.295- const struct sockaddr *local, size_t local_len, 13.296- const struct sockaddr *peer, size_t peer_len, 13.297- quiche_config *config, void *ssl, 13.298- bool is_server); 13.299- 13.300-// Enables keylog to the specified file path. Returns true on success. 13.301-bool quiche_conn_set_keylog_path(quiche_conn *conn, const char *path); 13.302- 13.303-// Enables keylog to the specified file descriptor. Unix only. 13.304-void quiche_conn_set_keylog_fd(quiche_conn *conn, int fd); 13.305- 13.306-// Enables qlog to the specified file path. Returns true on success. 13.307-bool quiche_conn_set_qlog_path(quiche_conn *conn, const char *path, 13.308- const char *log_title, const char *log_desc); 13.309- 13.310-// Enables qlog to the specified file descriptor. Unix only. 13.311-void quiche_conn_set_qlog_fd(quiche_conn *conn, int fd, const char *log_title, 13.312- const char *log_desc); 13.313- 13.314-// Configures the given session for resumption. 13.315-int quiche_conn_set_session(quiche_conn *conn, const uint8_t *buf, size_t buf_len); 13.316- 13.317-typedef struct { 13.318- // The remote address the packet was received from. 13.319- struct sockaddr *from; 13.320- socklen_t from_len; 13.321- 13.322- // The local address the packet was received on. 13.323- struct sockaddr *to; 13.324- socklen_t to_len; 13.325-} quiche_recv_info; 13.326- 13.327-// Processes QUIC packets received from the peer. 13.328-ssize_t quiche_conn_recv(quiche_conn *conn, uint8_t *buf, size_t buf_len, 13.329- const quiche_recv_info *info); 13.330- 13.331-typedef struct { 13.332- // The local address the packet should be sent from. 13.333- struct sockaddr_storage from; 13.334- socklen_t from_len; 13.335- 13.336- // The remote address the packet should be sent to. 13.337- struct sockaddr_storage to; 13.338- socklen_t to_len; 13.339- 13.340- // The time to send the packet out. 13.341- struct timespec at; 13.342-} quiche_send_info; 13.343- 13.344-// Writes a single QUIC packet to be sent to the peer. 13.345-ssize_t quiche_conn_send(quiche_conn *conn, uint8_t *out, size_t out_len, 13.346- quiche_send_info *out_info); 13.347- 13.348-// Returns the size of the send quantum, in bytes. 13.349-size_t quiche_conn_send_quantum(const quiche_conn *conn); 13.350- 13.351-// Reads contiguous data from a stream. 13.352-ssize_t quiche_conn_stream_recv(quiche_conn *conn, uint64_t stream_id, 13.353- uint8_t *out, size_t buf_len, bool *fin); 13.354- 13.355-// Writes data to a stream. 13.356-ssize_t quiche_conn_stream_send(quiche_conn *conn, uint64_t stream_id, 13.357- const uint8_t *buf, size_t buf_len, bool fin); 13.358- 13.359-// The side of the stream to be shut down. 13.360-enum quiche_shutdown { 13.361- QUICHE_SHUTDOWN_READ = 0, 13.362- QUICHE_SHUTDOWN_WRITE = 1, 13.363-}; 13.364- 13.365-// Sets the priority for a stream. 13.366-int quiche_conn_stream_priority(quiche_conn *conn, uint64_t stream_id, 13.367- uint8_t urgency, bool incremental); 13.368- 13.369-// Shuts down reading or writing from/to the specified stream. 13.370-int quiche_conn_stream_shutdown(quiche_conn *conn, uint64_t stream_id, 13.371- enum quiche_shutdown direction, uint64_t err); 13.372- 13.373-// Returns the stream's send capacity in bytes. 13.374-ssize_t quiche_conn_stream_capacity(const quiche_conn *conn, uint64_t stream_id); 13.375- 13.376-// Returns true if the stream has data that can be read. 13.377-bool quiche_conn_stream_readable(const quiche_conn *conn, uint64_t stream_id); 13.378- 13.379-// Returns the next stream that has data to read, or -1 if no such stream is 13.380-// available. 13.381-int64_t quiche_conn_stream_readable_next(quiche_conn *conn); 13.382- 13.383-// Returns true if the stream has enough send capacity. 13.384-// 13.385-// On error a value lower than 0 is returned. 13.386-int quiche_conn_stream_writable(quiche_conn *conn, uint64_t stream_id, size_t len); 13.387- 13.388-// Returns the next stream that can be written to, or -1 if no such stream is 13.389-// available. 13.390-int64_t quiche_conn_stream_writable_next(quiche_conn *conn); 13.391- 13.392-// Returns true if all the data has been read from the specified stream. 13.393-bool quiche_conn_stream_finished(const quiche_conn *conn, uint64_t stream_id); 13.394- 13.395-typedef struct quiche_stream_iter quiche_stream_iter; 13.396- 13.397-// Returns an iterator over streams that have outstanding data to read. 13.398-quiche_stream_iter *quiche_conn_readable(const quiche_conn *conn); 13.399- 13.400-// Returns an iterator over streams that can be written to. 13.401-quiche_stream_iter *quiche_conn_writable(const quiche_conn *conn); 13.402- 13.403-// Returns the maximum possible size of egress UDP payloads. 13.404-size_t quiche_conn_max_send_udp_payload_size(const quiche_conn *conn); 13.405- 13.406-// Returns the amount of time until the next timeout event, in nanoseconds. 13.407-uint64_t quiche_conn_timeout_as_nanos(const quiche_conn *conn); 13.408- 13.409-// Returns the amount of time until the next timeout event, in milliseconds. 13.410-uint64_t quiche_conn_timeout_as_millis(const quiche_conn *conn); 13.411- 13.412-// Processes a timeout event. 13.413-void quiche_conn_on_timeout(quiche_conn *conn); 13.414- 13.415-// Closes the connection with the given error and reason. 13.416-int quiche_conn_close(quiche_conn *conn, bool app, uint64_t err, 13.417- const uint8_t *reason, size_t reason_len); 13.418- 13.419-// Returns a string uniquely representing the connection. 13.420-void quiche_conn_trace_id(const quiche_conn *conn, const uint8_t **out, size_t *out_len); 13.421- 13.422-// Returns the source connection ID. 13.423-void quiche_conn_source_id(const quiche_conn *conn, const uint8_t **out, size_t *out_len); 13.424- 13.425-// Returns the destination connection ID. 13.426-void quiche_conn_destination_id(const quiche_conn *conn, const uint8_t **out, size_t *out_len); 13.427- 13.428-// Returns the negotiated ALPN protocol. 13.429-void quiche_conn_application_proto(const quiche_conn *conn, const uint8_t **out, 13.430- size_t *out_len); 13.431- 13.432-// Returns the peer's leaf certificate (if any) as a DER-encoded buffer. 13.433-void quiche_conn_peer_cert(const quiche_conn *conn, const uint8_t **out, size_t *out_len); 13.434- 13.435-// Returns the serialized cryptographic session for the connection. 13.436-void quiche_conn_session(const quiche_conn *conn, const uint8_t **out, size_t *out_len); 13.437- 13.438-// Returns true if the connection handshake is complete. 13.439-bool quiche_conn_is_established(const quiche_conn *conn); 13.440- 13.441-// Returns true if the connection has a pending handshake that has progressed 13.442-// enough to send or receive early data. 13.443-bool quiche_conn_is_in_early_data(const quiche_conn *conn); 13.444- 13.445-// Returns whether there is stream or DATAGRAM data available to read. 13.446-bool quiche_conn_is_readable(const quiche_conn *conn); 13.447- 13.448-// Returns true if the connection is draining. 13.449-bool quiche_conn_is_draining(const quiche_conn *conn); 13.450- 13.451-// Returns the number of bidirectional streams that can be created 13.452-// before the peer's stream count limit is reached. 13.453-uint64_t quiche_conn_peer_streams_left_bidi(const quiche_conn *conn); 13.454- 13.455-// Returns the number of unidirectional streams that can be created 13.456-// before the peer's stream count limit is reached. 13.457-uint64_t quiche_conn_peer_streams_left_uni(const quiche_conn *conn); 13.458- 13.459-// Returns true if the connection is closed. 13.460-bool quiche_conn_is_closed(const quiche_conn *conn); 13.461- 13.462-// Returns true if the connection was closed due to the idle timeout. 13.463-bool quiche_conn_is_timed_out(const quiche_conn *conn); 13.464- 13.465-// Returns true if a connection error was received, and updates the provided 13.466-// parameters accordingly. 13.467-bool quiche_conn_peer_error(const quiche_conn *conn, 13.468- bool *is_app, 13.469- uint64_t *error_code, 13.470- const uint8_t **reason, 13.471- size_t *reason_len); 13.472- 13.473-// Returns true if a connection error was queued or sent, and updates the provided 13.474-// parameters accordingly. 13.475-bool quiche_conn_local_error(const quiche_conn *conn, 13.476- bool *is_app, 13.477- uint64_t *error_code, 13.478- const uint8_t **reason, 13.479- size_t *reason_len); 13.480- 13.481-// Initializes the stream's application data. 13.482-// 13.483-// Stream data can only be initialized once. Additional calls to this method 13.484-// will fail. 13.485-// 13.486-// Note that the application is responsible for freeing the data. 13.487-int quiche_conn_stream_init_application_data(quiche_conn *conn, 13.488- uint64_t stream_id, 13.489- void *data); 13.490- 13.491-// Returns the stream's application data, if any was initialized. 13.492-void *quiche_conn_stream_application_data(quiche_conn *conn, uint64_t stream_id); 13.493- 13.494-// Fetches the next stream from the given iterator. Returns false if there are 13.495-// no more elements in the iterator. 13.496-bool quiche_stream_iter_next(quiche_stream_iter *iter, uint64_t *stream_id); 13.497- 13.498-// Frees the given stream iterator object. 13.499-void quiche_stream_iter_free(quiche_stream_iter *iter); 13.500- 13.501-typedef struct { 13.502- // The number of QUIC packets received on this connection. 13.503- size_t recv; 13.504- 13.505- // The number of QUIC packets sent on this connection. 13.506- size_t sent; 13.507- 13.508- // The number of QUIC packets that were lost. 13.509- size_t lost; 13.510- 13.511- // The number of sent QUIC packets with retransmitted data. 13.512- size_t retrans; 13.513- 13.514- // The number of sent bytes. 13.515- uint64_t sent_bytes; 13.516- 13.517- // The number of received bytes. 13.518- uint64_t recv_bytes; 13.519- 13.520- // The number of bytes lost. 13.521- uint64_t lost_bytes; 13.522- 13.523- // The number of stream bytes retransmitted. 13.524- uint64_t stream_retrans_bytes; 13.525- 13.526- // The number of known paths for the connection. 13.527- size_t paths_count; 13.528- 13.529- // The maximum idle timeout. 13.530- uint64_t peer_max_idle_timeout; 13.531- 13.532- // The maximum UDP payload size. 13.533- uint64_t peer_max_udp_payload_size; 13.534- 13.535- // The initial flow control maximum data for the connection. 13.536- uint64_t peer_initial_max_data; 13.537- 13.538- // The initial flow control maximum data for local bidirectional streams. 13.539- uint64_t peer_initial_max_stream_data_bidi_local; 13.540- 13.541- // The initial flow control maximum data for remote bidirectional streams. 13.542- uint64_t peer_initial_max_stream_data_bidi_remote; 13.543- 13.544- // The initial flow control maximum data for unidirectional streams. 13.545- uint64_t peer_initial_max_stream_data_uni; 13.546- 13.547- // The initial maximum bidirectional streams. 13.548- uint64_t peer_initial_max_streams_bidi; 13.549- 13.550- // The initial maximum unidirectional streams. 13.551- uint64_t peer_initial_max_streams_uni; 13.552- 13.553- // The ACK delay exponent. 13.554- uint64_t peer_ack_delay_exponent; 13.555- 13.556- // The max ACK delay. 13.557- uint64_t peer_max_ack_delay; 13.558- 13.559- // Whether active migration is disabled. 13.560- bool peer_disable_active_migration; 13.561- 13.562- // The active connection ID limit. 13.563- uint64_t peer_active_conn_id_limit; 13.564- 13.565- // DATAGRAM frame extension parameter, if any. 13.566- ssize_t peer_max_datagram_frame_size; 13.567-} quiche_stats; 13.568- 13.569-// Collects and returns statistics about the connection. 13.570-void quiche_conn_stats(const quiche_conn *conn, quiche_stats *out); 13.571- 13.572-typedef struct { 13.573- // The local address used by this path. 13.574- struct sockaddr_storage local_addr; 13.575- socklen_t local_addr_len; 13.576- 13.577- // The peer address seen by this path. 13.578- struct sockaddr_storage peer_addr; 13.579- socklen_t peer_addr_len; 13.580- 13.581- // The validation state of the path. 13.582- ssize_t validation_state; 13.583- 13.584- // Whether this path is active. 13.585- bool active; 13.586- 13.587- // The number of QUIC packets received on this path. 13.588- size_t recv; 13.589- 13.590- // The number of QUIC packets sent on this path. 13.591- size_t sent; 13.592- 13.593- // The number of QUIC packets that were lost on this path. 13.594- size_t lost; 13.595- 13.596- // The number of sent QUIC packets with retransmitted data on this path. 13.597- size_t retrans; 13.598- 13.599- // The estimated round-trip time of the path (in nanoseconds). 13.600- uint64_t rtt; 13.601- 13.602- // The size of the path's congestion window in bytes. 13.603- size_t cwnd; 13.604- 13.605- // The number of sent bytes on this path. 13.606- uint64_t sent_bytes; 13.607- 13.608- // The number of received bytes on this path. 13.609- uint64_t recv_bytes; 13.610- 13.611- // The number of bytes lost on this path. 13.612- uint64_t lost_bytes; 13.613- 13.614- // The number of stream bytes retransmitted on this path. 13.615- uint64_t stream_retrans_bytes; 13.616- 13.617- // The current PMTU for the path. 13.618- size_t pmtu; 13.619- 13.620- // The most recent data delivery rate estimate in bytes/s. 13.621- uint64_t delivery_rate; 13.622-} quiche_path_stats; 13.623- 13.624- 13.625-// Collects and returns statistics about the specified path for the connection. 13.626-// 13.627-// The `idx` argument represent the path's index (also see the `paths_count` 13.628-// field of `quiche_stats`). 13.629-int quiche_conn_path_stats(const quiche_conn *conn, size_t idx, quiche_path_stats *out); 13.630- 13.631-// Returns whether or not this is a server-side connection. 13.632-bool quiche_conn_is_server(const quiche_conn *conn); 13.633- 13.634-// Returns the maximum DATAGRAM payload that can be sent. 13.635-ssize_t quiche_conn_dgram_max_writable_len(const quiche_conn *conn); 13.636- 13.637-// Returns the length of the first stored DATAGRAM. 13.638-ssize_t quiche_conn_dgram_recv_front_len(const quiche_conn *conn); 13.639- 13.640-// Returns the number of items in the DATAGRAM receive queue. 13.641-ssize_t quiche_conn_dgram_recv_queue_len(const quiche_conn *conn); 13.642- 13.643-// Returns the total size of all items in the DATAGRAM receive queue. 13.644-ssize_t quiche_conn_dgram_recv_queue_byte_size(const quiche_conn *conn); 13.645- 13.646-// Returns the number of items in the DATAGRAM send queue. 13.647-ssize_t quiche_conn_dgram_send_queue_len(const quiche_conn *conn); 13.648- 13.649-// Returns the total size of all items in the DATAGRAM send queue. 13.650-ssize_t quiche_conn_dgram_send_queue_byte_size(const quiche_conn *conn); 13.651- 13.652-// Reads the first received DATAGRAM. 13.653-ssize_t quiche_conn_dgram_recv(quiche_conn *conn, uint8_t *buf, 13.654- size_t buf_len); 13.655- 13.656-// Sends data in a DATAGRAM frame. 13.657-ssize_t quiche_conn_dgram_send(quiche_conn *conn, const uint8_t *buf, 13.658- size_t buf_len); 13.659- 13.660-// Purges queued outgoing DATAGRAMs matching the predicate. 13.661-void quiche_conn_dgram_purge_outgoing(quiche_conn *conn, 13.662- bool (*f)(uint8_t *, size_t)); 13.663- 13.664-// Schedule an ack-eliciting packet on the active path. 13.665-ssize_t quiche_conn_send_ack_eliciting(quiche_conn *conn); 13.666- 13.667-// Schedule an ack-eliciting packet on the specified path. 13.668-ssize_t quiche_conn_send_ack_eliciting_on_path(quiche_conn *conn, 13.669- const struct sockaddr *local, size_t local_len, 13.670- const struct sockaddr *peer, size_t peer_len); 13.671- 13.672-// Frees the connection object. 13.673-void quiche_conn_free(quiche_conn *conn); 13.674- 13.675- 13.676-// HTTP/3 API 13.677-// 13.678- 13.679-// List of ALPN tokens of supported HTTP/3 versions. 13.680-#define QUICHE_H3_APPLICATION_PROTOCOL "\x02h3\x05h3-29\x05h3-28\x05h3-27" 13.681- 13.682-enum quiche_h3_error { 13.683- // There is no error or no work to do 13.684- QUICHE_H3_ERR_DONE = -1, 13.685- 13.686- // The provided buffer is too short. 13.687- QUICHE_H3_ERR_BUFFER_TOO_SHORT = -2, 13.688- 13.689- // Internal error in the HTTP/3 stack. 13.690- QUICHE_H3_ERR_INTERNAL_ERROR = -3, 13.691- 13.692- // Endpoint detected that the peer is exhibiting behavior that causes. 13.693- // excessive load. 13.694- QUICHE_H3_ERR_EXCESSIVE_LOAD = -4, 13.695- 13.696- // Stream ID or Push ID greater that current maximum was 13.697- // used incorrectly, such as exceeding a limit, reducing a limit, 13.698- // or being reused. 13.699- QUICHE_H3_ERR_ID_ERROR= -5, 13.700- 13.701- // The endpoint detected that its peer created a stream that it will not 13.702- // accept. 13.703- QUICHE_H3_ERR_STREAM_CREATION_ERROR = -6, 13.704- 13.705- // A required critical stream was closed. 13.706- QUICHE_H3_ERR_CLOSED_CRITICAL_STREAM = -7, 13.707- 13.708- // No SETTINGS frame at beginning of control stream. 13.709- QUICHE_H3_ERR_MISSING_SETTINGS = -8, 13.710- 13.711- // A frame was received which is not permitted in the current state. 13.712- QUICHE_H3_ERR_FRAME_UNEXPECTED = -9, 13.713- 13.714- // Frame violated layout or size rules. 13.715- QUICHE_H3_ERR_FRAME_ERROR = -10, 13.716- 13.717- // QPACK Header block decompression failure. 13.718- QUICHE_H3_ERR_QPACK_DECOMPRESSION_FAILED = -11, 13.719- 13.720- // -12 was previously used for TransportError, skip it 13.721- 13.722- // The underlying QUIC stream (or connection) doesn't have enough capacity 13.723- // for the operation to complete. The application should retry later on. 13.724- QUICHE_H3_ERR_STREAM_BLOCKED = -13, 13.725- 13.726- // Error in the payload of a SETTINGS frame. 13.727- QUICHE_H3_ERR_SETTINGS_ERROR = -14, 13.728- 13.729- // Server rejected request. 13.730- QUICHE_H3_ERR_REQUEST_REJECTED = -15, 13.731- 13.732- // Request or its response cancelled. 13.733- QUICHE_H3_ERR_REQUEST_CANCELLED = -16, 13.734- 13.735- // Client's request stream terminated without containing a full-formed 13.736- // request. 13.737- QUICHE_H3_ERR_REQUEST_INCOMPLETE = -17, 13.738- 13.739- // An HTTP message was malformed and cannot be processed. 13.740- QUICHE_H3_ERR_MESSAGE_ERROR = -18, 13.741- 13.742- // The TCP connection established in response to a CONNECT request was 13.743- // reset or abnormally closed. 13.744- QUICHE_H3_ERR_CONNECT_ERROR = -19, 13.745- 13.746- // The requested operation cannot be served over HTTP/3. Peer should retry 13.747- // over HTTP/1.1. 13.748- QUICHE_H3_ERR_VERSION_FALLBACK = -20, 13.749- 13.750- // The following QUICHE_H3_TRANSPORT_ERR_* errors are propagated 13.751- // from the QUIC transport layer. 13.752- 13.753- // See QUICHE_ERR_DONE. 13.754- QUICHE_H3_TRANSPORT_ERR_DONE = QUICHE_ERR_DONE - 1000, 13.755- 13.756- // See QUICHE_ERR_BUFFER_TOO_SHORT. 13.757- QUICHE_H3_TRANSPORT_ERR_BUFFER_TOO_SHORT = QUICHE_ERR_BUFFER_TOO_SHORT - 1000, 13.758- 13.759- // See QUICHE_ERR_UNKNOWN_VERSION. 13.760- QUICHE_H3_TRANSPORT_ERR_UNKNOWN_VERSION = QUICHE_ERR_UNKNOWN_VERSION - 1000, 13.761- 13.762- // See QUICHE_ERR_INVALID_FRAME. 13.763- QUICHE_H3_TRANSPORT_ERR_INVALID_FRAME = QUICHE_ERR_INVALID_FRAME - 1000, 13.764- 13.765- // See QUICHE_ERR_INVALID_PACKET. 13.766- QUICHE_H3_TRANSPORT_ERR_INVALID_PACKET = QUICHE_ERR_INVALID_PACKET - 1000, 13.767- 13.768- // See QUICHE_ERR_INVALID_STATE. 13.769- QUICHE_H3_TRANSPORT_ERR_INVALID_STATE = QUICHE_ERR_INVALID_STATE - 1000, 13.770- 13.771- // See QUICHE_ERR_INVALID_STREAM_STATE. 13.772- QUICHE_H3_TRANSPORT_ERR_INVALID_STREAM_STATE = QUICHE_ERR_INVALID_STREAM_STATE - 1000, 13.773- 13.774- // See QUICHE_ERR_INVALID_TRANSPORT_PARAM. 13.775- QUICHE_H3_TRANSPORT_ERR_INVALID_TRANSPORT_PARAM = QUICHE_ERR_INVALID_TRANSPORT_PARAM - 1000, 13.776- 13.777- // See QUICHE_ERR_CRYPTO_FAIL. 13.778- QUICHE_H3_TRANSPORT_ERR_CRYPTO_FAIL = QUICHE_ERR_CRYPTO_FAIL - 1000, 13.779- 13.780- // See QUICHE_ERR_TLS_FAIL. 13.781- QUICHE_H3_TRANSPORT_ERR_TLS_FAIL = QUICHE_ERR_TLS_FAIL - 1000, 13.782- 13.783- // See QUICHE_ERR_FLOW_CONTROL. 13.784- QUICHE_H3_TRANSPORT_ERR_FLOW_CONTROL = QUICHE_ERR_FLOW_CONTROL - 1000, 13.785- 13.786- // See QUICHE_ERR_STREAM_LIMIT. 13.787- QUICHE_H3_TRANSPORT_ERR_STREAM_LIMIT = QUICHE_ERR_STREAM_LIMIT - 1000, 13.788- 13.789- // See QUICHE_ERR_STREAM_STOPPED. 13.790- QUICHE_H3_TRANSPORT_ERR_STREAM_STOPPED = QUICHE_ERR_STREAM_STOPPED - 1000, 13.791- 13.792- // See QUICHE_ERR_STREAM_RESET. 13.793- QUICHE_H3_TRANSPORT_ERR_STREAM_RESET = QUICHE_ERR_STREAM_RESET - 1000, 13.794- 13.795- // See QUICHE_ERR_FINAL_SIZE. 13.796- QUICHE_H3_TRANSPORT_ERR_FINAL_SIZE = QUICHE_ERR_FINAL_SIZE - 1000, 13.797- 13.798- // See QUICHE_ERR_CONGESTION_CONTROL. 13.799- QUICHE_H3_TRANSPORT_ERR_CONGESTION_CONTROL = QUICHE_ERR_CONGESTION_CONTROL - 1000, 13.800- 13.801- // See QUICHE_ERR_ID_LIMIT. 13.802- QUICHE_H3_TRANSPORT_ERR_ID_LIMIT = QUICHE_ERR_ID_LIMIT - 1000, 13.803- 13.804- // See QUICHE_ERR_OUT_OF_IDENTIFIERS. 13.805- QUICHE_H3_TRANSPORT_ERR_OUT_OF_IDENTIFIERS = QUICHE_ERR_OUT_OF_IDENTIFIERS - 1000, 13.806- 13.807- // See QUICHE_ERR_KEY_UPDATE. 13.808- QUICHE_H3_TRANSPORT_ERR_KEY_UPDATE = QUICHE_ERR_KEY_UPDATE - 1000, 13.809-}; 13.810- 13.811-// Stores configuration shared between multiple connections. 13.812-typedef struct quiche_h3_config quiche_h3_config; 13.813- 13.814-// Creates an HTTP/3 config object with default settings values. 13.815-quiche_h3_config *quiche_h3_config_new(void); 13.816- 13.817-// Sets the `SETTINGS_MAX_FIELD_SECTION_SIZE` setting. 13.818-void quiche_h3_config_set_max_field_section_size(quiche_h3_config *config, uint64_t v); 13.819- 13.820-// Sets the `SETTINGS_QPACK_MAX_TABLE_CAPACITY` setting. 13.821-void quiche_h3_config_set_qpack_max_table_capacity(quiche_h3_config *config, uint64_t v); 13.822- 13.823-// Sets the `SETTINGS_QPACK_BLOCKED_STREAMS` setting. 13.824-void quiche_h3_config_set_qpack_blocked_streams(quiche_h3_config *config, uint64_t v); 13.825- 13.826-// Sets the `SETTINGS_ENABLE_CONNECT_PROTOCOL` setting. 13.827-void quiche_h3_config_enable_extended_connect(quiche_h3_config *config, bool enabled); 13.828- 13.829-// Frees the HTTP/3 config object. 13.830-void quiche_h3_config_free(quiche_h3_config *config); 13.831- 13.832-// An HTTP/3 connection. 13.833-typedef struct quiche_h3_conn quiche_h3_conn; 13.834- 13.835-// Creates a new server-side connection. 13.836-quiche_h3_conn *quiche_h3_accept(quiche_conn *quiche_conn, 13.837- quiche_h3_config *config); 13.838- 13.839-// Creates a new HTTP/3 connection using the provided QUIC connection. 13.840-quiche_h3_conn *quiche_h3_conn_new_with_transport(quiche_conn *quiche_conn, 13.841- quiche_h3_config *config); 13.842- 13.843-enum quiche_h3_event_type { 13.844- QUICHE_H3_EVENT_HEADERS, 13.845- QUICHE_H3_EVENT_DATA, 13.846- QUICHE_H3_EVENT_FINISHED, 13.847- QUICHE_H3_EVENT_DATAGRAM, 13.848- QUICHE_H3_EVENT_GOAWAY, 13.849- QUICHE_H3_EVENT_RESET, 13.850- QUICHE_H3_EVENT_PRIORITY_UPDATE, 13.851-}; 13.852- 13.853-typedef struct quiche_h3_event quiche_h3_event; 13.854- 13.855-// Processes HTTP/3 data received from the peer. 13.856-int64_t quiche_h3_conn_poll(quiche_h3_conn *conn, quiche_conn *quic_conn, 13.857- quiche_h3_event **ev); 13.858- 13.859-// Returns the type of the event. 13.860-enum quiche_h3_event_type quiche_h3_event_type(quiche_h3_event *ev); 13.861- 13.862-// Iterates over the headers in the event. 13.863-// 13.864-// The `cb` callback will be called for each header in `ev`. `cb` should check 13.865-// the validity of pseudo-headers and headers. If `cb` returns any value other 13.866-// than `0`, processing will be interrupted and the value is returned to the 13.867-// caller. 13.868-int quiche_h3_event_for_each_header(quiche_h3_event *ev, 13.869- int (*cb)(uint8_t *name, size_t name_len, 13.870- uint8_t *value, size_t value_len, 13.871- void *argp), 13.872- void *argp); 13.873- 13.874-// Iterates over the peer's HTTP/3 settings. 13.875-// 13.876-// The `cb` callback will be called for each setting in `conn`. 13.877-// If `cb` returns any value other than `0`, processing will be interrupted and 13.878-// the value is returned to the caller. 13.879-int quiche_h3_for_each_setting(quiche_h3_conn *conn, 13.880- int (*cb)(uint64_t identifier, 13.881- uint64_t value, void *argp), 13.882- void *argp); 13.883- 13.884-// Check whether data will follow the headers on the stream. 13.885-bool quiche_h3_event_headers_has_body(quiche_h3_event *ev); 13.886- 13.887-// Check whether or not extended connection is enabled by the peer 13.888-bool quiche_h3_extended_connect_enabled_by_peer(quiche_h3_conn *conn); 13.889- 13.890-// Frees the HTTP/3 event object. 13.891-void quiche_h3_event_free(quiche_h3_event *ev); 13.892- 13.893-typedef struct { 13.894- const uint8_t *name; 13.895- size_t name_len; 13.896- 13.897- const uint8_t *value; 13.898- size_t value_len; 13.899-} quiche_h3_header; 13.900- 13.901-// Extensible Priorities parameters. 13.902-typedef struct { 13.903- uint8_t urgency; 13.904- bool incremental; 13.905-} quiche_h3_priority; 13.906- 13.907-// Sends an HTTP/3 request. 13.908-int64_t quiche_h3_send_request(quiche_h3_conn *conn, quiche_conn *quic_conn, 13.909- quiche_h3_header *headers, size_t headers_len, 13.910- bool fin); 13.911- 13.912-// Sends an HTTP/3 response on the specified stream with default priority. 13.913-int quiche_h3_send_response(quiche_h3_conn *conn, quiche_conn *quic_conn, 13.914- uint64_t stream_id, quiche_h3_header *headers, 13.915- size_t headers_len, bool fin); 13.916- 13.917-// Sends an HTTP/3 response on the specified stream with specified priority. 13.918-int quiche_h3_send_response_with_priority(quiche_h3_conn *conn, 13.919- quiche_conn *quic_conn, uint64_t stream_id, 13.920- quiche_h3_header *headers, size_t headers_len, 13.921- quiche_h3_priority *priority, bool fin); 13.922- 13.923-// Sends an HTTP/3 body chunk on the given stream. 13.924-ssize_t quiche_h3_send_body(quiche_h3_conn *conn, quiche_conn *quic_conn, 13.925- uint64_t stream_id, uint8_t *body, size_t body_len, 13.926- bool fin); 13.927- 13.928-// Reads request or response body data into the provided buffer. 13.929-ssize_t quiche_h3_recv_body(quiche_h3_conn *conn, quiche_conn *quic_conn, 13.930- uint64_t stream_id, uint8_t *out, size_t out_len); 13.931- 13.932-// Try to parse an Extensible Priority field value. 13.933-int quiche_h3_parse_extensible_priority(uint8_t *priority, 13.934- size_t priority_len, 13.935- quiche_h3_priority *parsed); 13.936- 13.937-/// Sends a PRIORITY_UPDATE frame on the control stream with specified 13.938-/// request stream ID and priority. 13.939-int quiche_h3_send_priority_update_for_request(quiche_h3_conn *conn, 13.940- quiche_conn *quic_conn, 13.941- uint64_t stream_id, 13.942- quiche_h3_priority *priority); 13.943- 13.944-// Take the last received PRIORITY_UPDATE frame for a stream. 13.945-// 13.946-// The `cb` callback will be called once. `cb` should check the validity of 13.947-// priority field value contents. If `cb` returns any value other than `0`, 13.948-// processing will be interrupted and the value is returned to the caller. 13.949-int quiche_h3_take_last_priority_update(quiche_h3_conn *conn, 13.950- uint64_t prioritized_element_id, 13.951- int (*cb)(uint8_t *priority_field_value, 13.952- uint64_t priority_field_value_len, 13.953- void *argp), 13.954- void *argp); 13.955- 13.956-// Returns whether the peer enabled HTTP/3 DATAGRAM frame support. 13.957-bool quiche_h3_dgram_enabled_by_peer(quiche_h3_conn *conn, 13.958- quiche_conn *quic_conn); 13.959- 13.960-// Writes data to the DATAGRAM send queue. 13.961-ssize_t quiche_h3_send_dgram(quiche_h3_conn *conn, quiche_conn *quic_conn, 13.962- uint64_t flow_id, uint8_t *data, size_t data_len); 13.963- 13.964-// Reads data from the DATAGRAM receive queue. 13.965-ssize_t quiche_h3_recv_dgram(quiche_h3_conn *conn, quiche_conn *quic_conn, 13.966- uint64_t *flow_id, size_t *flow_id_len, 13.967- uint8_t *out, size_t out_len); 13.968- 13.969-// Frees the HTTP/3 connection object. 13.970-void quiche_h3_conn_free(quiche_h3_conn *conn); 13.971- 13.972-#if defined(__cplusplus) 13.973-} // extern C 13.974-#endif 13.975- 13.976-#endif // QUICHE_H
14.1--- a/gen.rs Sat Jun 03 19:57:46 2023 -0400 14.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 14.3@@ -1,84 +0,0 @@ 14.4-//! demo 14.5-pub use fig::*; 14.6-pub use obj::*; 14.7-use std::ffi::{CStr, CString}; //OsStr,Path 14.8- //use std::os::unix::ffi::OsStrExt; 14.9-use std::slice; 14.10-use libc::{c_char,size_t}; 14.11- 14.12-#[macro_export] 14.13-macro_rules! cdefn { 14.14- (free $t:tt $n:tt) => { 14.15- #[no_mangle] 14.16- pub unsafe extern "C" fn $n(ptr: *mut $t) { 14.17- if ptr.is_null() { 14.18- return; 14.19- } 14.20- let _ = Box::from_raw(ptr); 14.21- } 14.22- }; 14.23- (from_string $t:tt $n:tt) => { 14.24- #[no_mangle] 14.25- pub unsafe extern "C" fn $n(ptr: *const c_char) -> *mut $t { 14.26- assert!(!ptr.is_null()); 14.27- let p = CStr::from_ptr(ptr).to_str().unwrap(); 14.28- Box::into_raw(Box::new(p.into())) 14.29- } 14.30- }; 14.31- (json_string $t:tt $r:tt $w:tt) => { 14.32- #[no_mangle] 14.33- pub unsafe extern "C" fn $r(ptr: *const c_char) -> *mut $t { 14.34- assert!(!ptr.is_null()); 14.35- let s = CStr::from_ptr(ptr); 14.36- Box::into_raw(Box::new($t::from_json_str(&s.to_str().unwrap()).unwrap())) 14.37- } 14.38- 14.39- #[no_mangle] 14.40- pub unsafe extern "C" fn $w(ptr: *const $t) -> *mut c_char { 14.41- let p = &*ptr; 14.42- let x = p.to_json_string().unwrap(); 14.43- CString::new(x.as_str().as_bytes()).unwrap().into_raw() 14.44- } 14.45- }; 14.46- (ron_string $t:tt $r:tt $w:tt) => { 14.47- #[no_mangle] 14.48- pub unsafe extern "C" fn $r(ptr: *const c_char) -> *mut $t { 14.49- assert!(!ptr.is_null()); 14.50- let s = CStr::from_ptr(ptr); 14.51- Box::into_raw(Box::new($t::from_ron_str(&s.to_str().unwrap()).unwrap())) 14.52- } 14.53- 14.54- #[no_mangle] 14.55- pub unsafe extern "C" fn $w(ptr: *const $t) -> *mut c_char { 14.56- let p = &*ptr; 14.57- let x = p.to_ron_string().unwrap(); 14.58- CString::new(x.as_str().as_bytes()).unwrap().into_raw() 14.59- } 14.60- }; 14.61- (bytes $t:tt $r:tt $w:tt) => { 14.62- #[no_mangle] 14.63- pub unsafe extern "C" fn $r(ptr: *const u8, len: size_t) -> *mut $t { 14.64- Box::into_raw(Box::new($t::decode(slice::from_raw_parts(ptr,len)).unwrap())) 14.65- } 14.66- 14.67- #[no_mangle] 14.68- pub unsafe extern "C" fn $w(ptr: *const $t) -> *mut u8 { 14.69- let p = &*ptr; 14.70- let mut x = p.encode().unwrap(); 14.71- let r = x.as_mut_ptr(); 14.72- std::mem::forget(x); 14.73- r 14.74- } 14.75- } 14.76-} 14.77- 14.78-cdefn!(free Service free_service); 14.79-cdefn!(from_string Service service_from_string); 14.80-cdefn!(json_string Service service_from_json_string service_to_json_string); 14.81-cdefn!(ron_string Service service_from_ron_string service_to_ron_string); 14.82-cdefn!(bytes Service service_decode service_encode); 14.83-cdefn!(free CustomService free_custom_service); 14.84-cdefn!(from_string CustomService custom_service_from_string); 14.85-cdefn!(json_string CustomService custom_service_from_json_string custom_service_to_json_string); 14.86-cdefn!(ron_string CustomService custom_service_from_ron_string custom_service_to_ron_string); 14.87-cdefn!(bytes CustomService custom_service_decode custom_service_encode);
15.1--- a/install.lisp Sat Jun 03 19:57:46 2023 -0400 15.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 15.3@@ -1,12 +0,0 @@ 15.4-#!/usr/local/bin/sbcl --script 15.5-(in-package :cl-user) 15.6-#-quicklisp 15.7-(let ((quicklisp-init (merge-pathnames "quicklisp/setup.lisp" (user-homedir-pathname)))) 15.8- (when (probe-file quicklisp-init) 15.9- (load quicklisp-init))) 15.10- 15.11-(asdf:load-asd "cl-demo.asd") 15.12-(asdf:loadload "demo.asd") 15.13-(ql:quickload :demo) 15.14-;; (asdf:make :demo) 15.15-(sb-ext:save-lisp-and-die "out/demo" :toplevel #'demo:main :executable t)
16.1--- a/lib.rs Sat Jun 03 19:57:46 2023 -0400 16.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 16.3@@ -1,117 +0,0 @@ 16.4-//! demo/lib.rs --- generated by DEMO:RS-MACROEXPAND 16.5-extern crate libc; 16.6-extern crate obj; 16.7-use libc::{c_char, size_t}; 16.8-use obj::{CustomService, Objective, Service}; 16.9-use std::ffi::{CStr, CString}; 16.10-use std::slice; 16.11-#[no_mangle] 16.12-pub unsafe extern "C" fn free_service(ptr: *mut Service) { 16.13- if ptr.is_null() { 16.14- return; 16.15- } 16.16- let _ = Box::from_raw(ptr); 16.17-} 16.18-#[no_mangle] 16.19-pub unsafe extern "C" fn service_from_string(ptr: *const c_char) -> *mut Service { 16.20- assert!(!ptr.is_null()); 16.21- let p = CStr::from_ptr(ptr).to_str().unwrap(); 16.22- Box::into_raw(Box::new(p.into())) 16.23-} 16.24-#[no_mangle] 16.25-pub unsafe extern "C" fn service_from_json_string(ptr: *const c_char) -> *mut Service { 16.26- assert!(!ptr.is_null()); 16.27- let s = CStr::from_ptr(ptr); 16.28- Box::into_raw(Box::new( 16.29- Service::from_json_str(&s.to_str().unwrap()).unwrap(), 16.30- )) 16.31-} 16.32-#[no_mangle] 16.33-pub unsafe extern "C" fn service_to_json_string(ptr: *const Service) -> *mut c_char { 16.34- let p = &*ptr; 16.35- let x = p.to_json_string().unwrap(); 16.36- CString::new(x.as_str().as_bytes()).unwrap().into_raw() 16.37-} 16.38-#[no_mangle] 16.39-pub unsafe extern "C" fn service_from_ron_string(ptr: *const c_char) -> *mut Service { 16.40- assert!(!ptr.is_null()); 16.41- let s = CStr::from_ptr(ptr); 16.42- Box::into_raw(Box::new( 16.43- Service::from_ron_str(&s.to_str().unwrap()).unwrap(), 16.44- )) 16.45-} 16.46-#[no_mangle] 16.47-pub unsafe extern "C" fn service_to_ron_string(ptr: *const Service) -> *mut c_char { 16.48- let p = &*ptr; 16.49- let x = p.to_ron_string().unwrap(); 16.50- CString::new(x.as_str().as_bytes()).unwrap().into_raw() 16.51-} 16.52-#[no_mangle] 16.53-pub unsafe extern "C" fn service_decode(ptr: *const u8, len: size_t) -> *mut Service { 16.54- Box::into_raw(Box::new( 16.55- Service::decode(slice::from_raw_parts(ptr, len)).unwrap(), 16.56- )) 16.57-} 16.58-#[no_mangle] 16.59-pub unsafe extern "C" fn service_encode(ptr: *const Service) -> *mut u8 { 16.60- let p = &*ptr; 16.61- let mut x = p.encode().unwrap(); 16.62- let r = x.as_mut_ptr(); 16.63- std::mem::forget(x); 16.64- r 16.65-} 16.66-#[no_mangle] 16.67-pub unsafe extern "C" fn free_custom_service(ptr: *mut CustomService) { 16.68- if ptr.is_null() { 16.69- return; 16.70- } 16.71- let _ = Box::from_raw(ptr); 16.72-} 16.73-#[no_mangle] 16.74-pub unsafe extern "C" fn custom_service_from_string(ptr: *const c_char) -> *mut CustomService { 16.75- assert!(!ptr.is_null()); 16.76- let p = CStr::from_ptr(ptr).to_str().unwrap(); 16.77- Box::into_raw(Box::new(p.into())) 16.78-} 16.79-#[no_mangle] 16.80-pub unsafe extern "C" fn custom_service_from_json_string(ptr: *const c_char) -> *mut CustomService { 16.81- assert!(!ptr.is_null()); 16.82- let s = CStr::from_ptr(ptr); 16.83- Box::into_raw(Box::new( 16.84- CustomService::from_json_str(&s.to_str().unwrap()).unwrap(), 16.85- )) 16.86-} 16.87-#[no_mangle] 16.88-pub unsafe extern "C" fn custom_service_to_json_string(ptr: *const CustomService) -> *mut c_char { 16.89- let p = &*ptr; 16.90- let x = p.to_json_string().unwrap(); 16.91- CString::new(x.as_str().as_bytes()).unwrap().into_raw() 16.92-} 16.93-#[no_mangle] 16.94-pub unsafe extern "C" fn custom_service_from_ron_string(ptr: *const c_char) -> *mut CustomService { 16.95- assert!(!ptr.is_null()); 16.96- let s = CStr::from_ptr(ptr); 16.97- Box::into_raw(Box::new( 16.98- CustomService::from_ron_str(&s.to_str().unwrap()).unwrap(), 16.99- )) 16.100-} 16.101-#[no_mangle] 16.102-pub unsafe extern "C" fn custom_service_to_ron_string(ptr: *const CustomService) -> *mut c_char { 16.103- let p = &*ptr; 16.104- let x = p.to_ron_string().unwrap(); 16.105- CString::new(x.as_str().as_bytes()).unwrap().into_raw() 16.106-} 16.107-#[no_mangle] 16.108-pub unsafe extern "C" fn custom_service_decode(ptr: *const u8, len: size_t) -> *mut CustomService { 16.109- Box::into_raw(Box::new( 16.110- CustomService::decode(slice::from_raw_parts(ptr, len)).unwrap(), 16.111- )) 16.112-} 16.113-#[no_mangle] 16.114-pub unsafe extern "C" fn custom_service_encode(ptr: *const CustomService) -> *mut u8 { 16.115- let p = &*ptr; 16.116- let mut x = p.encode().unwrap(); 16.117- let r = x.as_mut_ptr(); 16.118- std::mem::forget(x); 16.119- r 16.120-}
17.1--- a/makefile Sat Jun 03 19:57:46 2023 -0400 17.2+++ b/makefile Sat Jun 03 22:48:46 2023 -0400 17.3@@ -1,23 +1,22 @@ 17.4 M?=release 17.5 L?=sbcl 17.6+C?=default.cfg 17.7 L_C=$(L) --no-userinit 17.8+L_D=$(L) --load demo.asd --eval '(ql:quickload "demo")' 17.9 L_S=$(L) --script 17.10-P?=python3 17.11 ARCH?= 17.12 A_C=ifeq ($(ARCH),x86_64) A_C=arch -$(ARCH) endif 17.13-.PHONY: 17.14-RS:Cargo.toml build.rs lib.rs obj 17.15-CL:*.asd *.lisp 17.16+.PHONY:build 17.17+RS:Cargo.toml rustfmt.toml src/crates/* 17.18+CL:*/*.asd */*.lisp 17.19 deps:; 17.20 clean:;rm -rf *.fasl;cargo clean 17.21 fmt:$(RS);cargo fmt 17.22-build:$(RS) $(CL);cargo build --$(M);$L --load demo.asd \ 17.23- --eval '(ql:quickload :demo)' \ 17.24- --eval '(asdf:make :demo)' \ 17.25+build:$(RS) $(CL);cargo build --$(M);$(L_D) 17.26+ --eval '(asdf:make "demo")' \ 17.27 --eval '(quit)' 17.28-ffi:build;cp target/$(M)/libdemo.dylib ffi;cd ffi;$(P) ffi/build.py 17.29 docs:$(RS);cargo doc 17.30-test:$(RS) $(CL);cargo test;$L tests.lisp 17.31+test:$(RS) $(CL);cargo test;$(L_D) --eval '(asdf:test "demo")' --eval '(quit)' 17.32 #pack:;scripts/pack.ros 17.33 #check:;scripts/check.ros 17.34-ci:clean fmt build ffi docs test; 17.35+ci:clean fmt build docs test;
18.1--- a/obj/Cargo.toml Sat Jun 03 19:57:46 2023 -0400 18.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 18.3@@ -1,27 +0,0 @@ 18.4-[package] 18.5-name = "obj" 18.6-version = "0.1.0" 18.7-edition = "2021" 18.8-[features] 18.9-oauth = ["yup-oauth2"] 18.10- 18.11-[dependencies] 18.12-ron = "0.7.0" 18.13-bincode = "1.3.3" 18.14-serde_json = "1.0.68" 18.15-serde = { version = "1.0.130", features = ["derive"] } 18.16-chrono = { version = "0.4.19", features = ["serde"] } 18.17-mime = "0.3.16" 18.18-regex = "1.5.4" 18.19-rusty_ulid = "0.11.0" 18.20-uuid = { version = "0.8", features = ["serde"] } 18.21-yup-oauth2 = { version = "5.1.0", optional = true } 18.22-blake3 = "1.0.0" 18.23-hashbrown = "0.11.2" 18.24-rand = "0.8.0" 18.25-sha2 = "0.9.5" 18.26-hex = "0.4.3" 18.27-ulid = "1.0.0" 18.28- 18.29-[target.'cfg(target_arch = "wasm32")'.dependencies] 18.30-uuid = { version = "0.8", features = ["wasm-bindgen"] }
19.1--- a/obj/proc_macros/Cargo.toml Sat Jun 03 19:57:46 2023 -0400 19.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 19.3@@ -1,10 +0,0 @@ 19.4-[package] 19.5-name = "proc_macros" 19.6-version = "0.1.0" 19.7-edition = "2021" 19.8-[lib] 19.9-proc-macro = true 19.10-[dependencies] 19.11-quote = "1.0" 19.12-proc-macro2 = "1.0" 19.13-syn = "1.0" 19.14\ No newline at end of file
20.1--- a/obj/proc_macros/src/derive.rs Sat Jun 03 19:57:46 2023 -0400 20.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 20.3@@ -1,5 +0,0 @@ 20.4-mod derive; 20.5-use proc_macro::TokenStream; 20.6-pub fn derive_static_type(input: TokenStream) -> TokenStream { 20.7- derive::derive_static_type(input) 20.8-}
21.1--- a/obj/proc_macros/src/lib.rs Sat Jun 03 19:57:46 2023 -0400 21.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 21.3@@ -1,1 +0,0 @@ 21.4-
22.1--- a/obj/src/auth.rs Sat Jun 03 19:57:46 2023 -0400 22.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 22.3@@ -1,72 +0,0 @@ 22.4-//! Auth Configs 22.5-use serde::{Deserialize, Serialize}; 22.6- 22.7-#[cfg(feature = "oauth")] 22.8-use yup_oauth2::ApplicationSecret; 22.9- 22.10-#[derive(Serialize, Deserialize, Debug, Default, Hash)] 22.11-pub struct AuthConfig { 22.12- pub provider: String, 22.13- #[cfg(feature = "oauth")] 22.14- pub oauth: Option<Oauth2Config>, 22.15- pub ssh: Option<SshConfig>, 22.16- pub pw: Option<PasswordConfig>, 22.17-} 22.18- 22.19-#[derive(Serialize, Deserialize, Default, Debug, Hash)] 22.20-pub struct PasswordConfig(String, String); 22.21- 22.22-#[cfg(feature = "oauth")] 22.23-#[derive(Serialize, Deserialize, Hash, Debug, PartialEq, Clone, Default)] 22.24-pub struct Oauth2Config { 22.25- pub client_id: String, 22.26- pub client_secret: String, 22.27- pub redirect_uris: Vec<String>, 22.28- pub auth_uri: String, 22.29- pub token_uri: String, 22.30- pub project_id: Option<String>, //for apptoken 22.31- pub client_email: Option<String>, 22.32- /// The URL of the public x509 certificate, used to verify the signature on 22.33- /// JWTs, such as ID tokens, signed by the authentication provider. 22.34- pub auth_provider_x509_cert_url: Option<String>, 22.35- /// The URL of the public x509 certificate, used to verify JWTs signed by the 22.36- /// client. 22.37- pub client_x509_cert_url: Option<String>, 22.38-} 22.39- 22.40-#[cfg(feature = "oauth")] 22.41-impl From<ApplicationSecret> for Oauth2Config { 22.42- fn from(shh: ApplicationSecret) -> Self { 22.43- Oauth2Config { 22.44- client_id: shh.client_id, 22.45- client_secret: shh.client_secret, 22.46- redirect_uris: shh.redirect_uris, 22.47- auth_uri: shh.auth_uri, 22.48- token_uri: shh.token_uri, 22.49- project_id: shh.project_id, 22.50- client_email: shh.client_email, 22.51- auth_provider_x509_cert_url: shh.auth_provider_x509_cert_url, 22.52- client_x509_cert_url: shh.client_x509_cert_url, 22.53- } 22.54- } 22.55-} 22.56- 22.57-#[cfg(feature = "oauth")] 22.58-impl From<Oauth2Config> for ApplicationSecret { 22.59- fn from(cfg: Oauth2Config) -> Self { 22.60- ApplicationSecret { 22.61- client_id: cfg.client_id, 22.62- client_secret: cfg.client_secret, 22.63- redirect_uris: cfg.redirect_uris, 22.64- auth_uri: cfg.auth_uri, 22.65- token_uri: cfg.token_uri, 22.66- project_id: cfg.project_id, 22.67- client_email: cfg.client_email, 22.68- auth_provider_x509_cert_url: cfg.auth_provider_x509_cert_url, 22.69- client_x509_cert_url: cfg.client_x509_cert_url, 22.70- } 22.71- } 22.72-} 22.73- 22.74-#[derive(Serialize, Deserialize, Hash, Debug, PartialEq, Clone, Default)] 22.75-pub struct SshConfig {}
23.1--- a/obj/src/cfg.rs Sat Jun 03 19:57:46 2023 -0400 23.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 23.3@@ -1,51 +0,0 @@ 23.4-/// common trait for all config modules. This trait provides functions 23.5-/// for de/serializing to/from RON, updating fields, and formatting. 23.6-use serde::{Serialize, Deserialize}; 23.7-use crate::Objective; 23.8-use std::collections::HashMap as M; 23.9-use std::path::PathBuf; 23.10-use std::string::String as S; 23.11-use std::error::Error as E; 23.12-use std::boxed::Box as B; 23.13-type R<X> = std::result::Result<X,B<dyn E>>; 23.14- 23.15-pub trait Configure: Objective { 23.16- fn update(&self) -> R<()> { 23.17- Ok(()) 23.18- } 23.19-} 23.20- 23.21-#[derive(Serialize, Deserialize, Debug, Default)] 23.22-pub struct ShellConfig { 23.23- pub env: M<S,S>, 23.24- pub cmds: M<S,S>, 23.25- pub shell: ShellType, 23.26-} 23.27- 23.28-impl Objective for ShellConfig {} 23.29- 23.30-#[derive(Serialize, Deserialize, Debug, Hash, Default)] 23.31-pub enum ShellType { 23.32- #[default] 23.33- Bash, 23.34- Zsh, 23.35- Sh, 23.36-} 23.37- 23.38-#[derive(Serialize, Deserialize, Debug, Default)] 23.39-pub enum EditorType { 23.40- #[default] 23.41- Emacs, 23.42- Vi, 23.43- Nano, 23.44-} 23.45- 23.46-#[derive(Serialize, Deserialize, Debug, Default)] 23.47-pub struct EditorConfig { 23.48- pub editor: EditorType, 23.49- pub cmds: M<S,S>, 23.50- pub init_file: PathBuf, 23.51-} 23.52- 23.53-#[cfg(test)] 23.54-mod tests;
24.1--- a/obj/src/database.rs Sat Jun 03 19:57:46 2023 -0400 24.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 24.3@@ -1,18 +0,0 @@ 24.4-//! cfg::config::database 24.5-//! 24.6-//! Database configuration primitives 24.7-use serde::{Deserialize, Serialize}; 24.8- 24.9-#[derive(Serialize, Deserialize, Debug, Hash, PartialEq, Eq)] 24.10-pub struct DatabaseConfig { 24.11- engine: DatabaseType, 24.12- path: String, 24.13- cfs: Vec<String>, 24.14-} 24.15- 24.16-#[derive(Serialize, Deserialize, Debug, Hash, PartialEq, Eq)] 24.17-pub enum DatabaseType { 24.18- RocksDB, 24.19- Postgres, 24.20- Alch, 24.21-}
25.1--- a/obj/src/err.rs Sat Jun 03 19:57:46 2023 -0400 25.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 25.3@@ -1,81 +0,0 @@ 25.4-//! obj errors 25.5-use std::{fmt, io}; 25.6- 25.7-/// obj Result wrapper 25.8-pub type Result<T> = std::result::Result<T, Error>; 25.9- 25.10-/// obj Error type 25.11-#[derive(Debug)] 25.12-pub enum Error { 25.13- Message(String), 25.14- Ron(ron::error::Error), 25.15- Json(serde_json::error::Error), 25.16- Io(io::Error), 25.17- Bincode(bincode::Error), 25.18- Utf8(std::string::FromUtf8Error), 25.19- Parse(std::string::ParseError), 25.20-} 25.21- 25.22-impl serde::ser::Error for Error { 25.23- fn custom<T: fmt::Display>(msg: T) -> Self { 25.24- Error::Message(msg.to_string()) 25.25- } 25.26-} 25.27- 25.28-impl serde::de::Error for Error { 25.29- fn custom<T: fmt::Display>(msg: T) -> Self { 25.30- Error::Message(msg.to_string()) 25.31- } 25.32-} 25.33- 25.34-impl fmt::Display for Error { 25.35- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 25.36- match self { 25.37- Error::Message(msg) => f.write_str(msg), 25.38- Error::Io(ref err) => write!(f, "obj IO error: {}", err), 25.39- Error::Ron(ref err) => write!(f, "obj Ron error: {}", err), 25.40- Error::Json(ref err) => write!(f, "obj Json error: {}", err), 25.41- Error::Bincode(ref err) => write!(f, "obj Bincode error: {}", err), 25.42- Error::Utf8(ref err) => write!(f, "obj Utf8 error: {}", err), 25.43- Error::Parse(ref err) => write!(f, "obj Parse error: {}", err), 25.44- } 25.45- } 25.46-} 25.47- 25.48-impl From<io::Error> for Error { 25.49- fn from(e: io::Error) -> Self { 25.50- Error::Io(e) 25.51- } 25.52-} 25.53- 25.54-impl From<std::string::ParseError> for Error { 25.55- fn from(e: std::string::ParseError) -> Self { 25.56- Error::Parse(e) 25.57- } 25.58-} 25.59- 25.60-impl From<std::string::FromUtf8Error> for Error { 25.61- fn from(err: std::string::FromUtf8Error) -> Self { 25.62- Error::Utf8(err) 25.63- } 25.64-} 25.65- 25.66-impl From<ron::Error> for Error { 25.67- fn from(e: ron::Error) -> Self { 25.68- Error::Ron(e) 25.69- } 25.70-} 25.71- 25.72-impl From<serde_json::Error> for Error { 25.73- fn from(e: serde_json::Error) -> Self { 25.74- Error::Json(e) 25.75- } 25.76-} 25.77- 25.78-impl From<bincode::Error> for Error { 25.79- fn from(e: bincode::Error) -> Self { 25.80- Error::Bincode(e) 25.81- } 25.82-} 25.83- 25.84-impl std::error::Error for Error {}
26.1--- a/obj/src/hash.rs Sat Jun 03 19:57:46 2023 -0400 26.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 26.3@@ -1,51 +0,0 @@ 26.4-//! hash - wrapper for hash algorithms and types 26.5- 26.6-pub use blake3::{derive_key, hash, keyed_hash, Hash as B3Hash, Hasher as B3Hasher, OutputReader}; 26.7-pub use hex; 26.8-pub use sha2::Sha512; 26.9- 26.10-pub use std::hash::{Hash, Hasher}; 26.11- 26.12-pub const KEY_LEN: usize = 32; 26.13-pub const OUT_LEN: usize = 32; 26.14-pub const OUT_LEN_HEX: usize = OUT_LEN * 2; 26.15- 26.16-#[cfg(test)] 26.17-mod tests { 26.18- use crate::*; 26.19- use super::*; 26.20- #[test] 26.21- fn id_state_hash() { 26.22- let id = id::Id(vec![0; KEY_LEN]); 26.23- let hash = id.state_hash(&mut B3Hasher::new()); 26.24- assert_eq!(hash, id.state_hash(&mut B3Hasher::new())); 26.25- } 26.26- 26.27- #[test] 26.28- fn id_hex() { 26.29- let id = id::Id(vec![255; KEY_LEN]); 26.30- 26.31- assert_eq!( 26.32- hex::decode("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(), 26.33- id.0 26.34- ); 26.35- } 26.36- 26.37- #[test] 26.38- fn rand_id() { 26.39- let id = id::Id::rand(); 26.40- let hash = id.state_hash(&mut B3Hasher::new()); 26.41- assert_eq!(hash, id.state_hash(&mut B3Hasher::new())); 26.42- } 26.43- 26.44- #[test] 26.45- fn random_demon_id_is_valid() { 26.46- use id::PeerId; 26.47- for _ in 0..5000 { 26.48- let did = PeerId::rand(); 26.49- let did2 = PeerId::rand(); 26.50- assert_eq!(did, did); 26.51- assert_ne!(did, did2); 26.52- } 26.53- } 26.54-}
27.1--- a/obj/src/id.rs Sat Jun 03 19:57:46 2023 -0400 27.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 27.3@@ -1,120 +0,0 @@ 27.4-use std::{fmt, str::FromStr}; 27.5-use serde::{Serialize, Deserialize}; 27.6-pub use uuid::Uuid; 27.7-pub use ulid::Ulid; 27.8-use rand::Rng; 27.9-use crate::hash::{KEY_LEN,OUT_LEN,B3Hasher}; 27.10-/// a simple Id abstraction 27.11-#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Serialize, Deserialize, Hash)] 27.12-pub struct Id(pub Vec<u8>); 27.13- 27.14-impl Id { 27.15- pub fn rand() -> Self { 27.16- let mut rng = rand::thread_rng(); 27.17- let vals: Vec<u8> = (0..KEY_LEN).map(|_| rng.gen_range(0..u8::MAX)).collect(); 27.18- Id(vals) 27.19- } 27.20- 27.21- pub fn state_hash(&self, state: &mut B3Hasher) -> Self { 27.22- let mut output = vec![0; OUT_LEN]; 27.23- state.update(&self.0); 27.24- let mut res = state.finalize_xof(); 27.25- res.fill(&mut output); 27.26- Id(output) 27.27- } 27.28- 27.29- pub fn to_hex(&self) -> String { 27.30- hex::encode(&self.0) 27.31- } 27.32-} 27.33- 27.34-/// PeerId 27.35-/// 27.36-/// identifies a unique Peer 27.37-#[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd, Debug)] 27.38-pub struct PeerId { 27.39- id: [u8; 32], 27.40-} 27.41- 27.42-impl PeerId { 27.43- pub fn new() -> Self { 27.44- Self::default() 27.45- } 27.46- 27.47- pub fn rand() -> Self { 27.48- let pd = rand::thread_rng().gen::<[u8; 32]>(); 27.49- Self { id: pd } 27.50- } 27.51- 27.52- pub fn from_bytes(data: &[u8]) -> Self { 27.53- let pd = blake3::hash(data); 27.54- let hash = pd.as_bytes(); 27.55- Self { id: *hash } 27.56- } 27.57-} 27.58- 27.59-impl Default for PeerId { 27.60- fn default() -> Self { 27.61- PeerId { id: [0; 32] } 27.62- } 27.63-} 27.64- 27.65-/// Identity trait 27.66-/// 27.67-/// Defines Identity-related behaviors 27.68-pub trait Identity: Sized { 27.69- /// return the hashed bytes of an ObjectId 27.70- fn id(&self) -> Id; 27.71-} 27.72- 27.73-#[derive(Debug, Copy, Clone, Eq, PartialEq)] 27.74-pub struct ObjectId(u128); 27.75- 27.76-pub struct NameSpace { 27.77- pub prefix: Option<String>, 27.78- pub capacity: u64, 27.79- pub route: Vec<Id>, 27.80- pub key: Option<Id>, 27.81-} 27.82- 27.83-pub struct Domain { 27.84- pub ns: NameSpace, 27.85- pub id: Id, 27.86-} 27.87- 27.88-impl From<Uuid> for ObjectId { 27.89- fn from(uuid: Uuid) -> Self { 27.90- ObjectId(uuid.as_u128()) 27.91- } 27.92-} 27.93- 27.94-impl From<Ulid> for ObjectId { 27.95- fn from(ulid: Ulid) -> Self { 27.96- ObjectId(u128::from(ulid)) 27.97- } 27.98-} 27.99- 27.100-impl From<u128> for ObjectId { 27.101- fn from(src: u128) -> Self { 27.102- ObjectId(src) 27.103- } 27.104-} 27.105- 27.106-impl FromStr for ObjectId { 27.107- type Err = (); 27.108- fn from_str(input: &str) -> std::result::Result<ObjectId, Self::Err> { 27.109- match input { 27.110- i => Ok(ObjectId(u128::from(Ulid::from_str(i).unwrap()))), 27.111- } 27.112- } 27.113-} 27.114- 27.115-impl fmt::Display for ObjectId { 27.116- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 27.117- match *self { 27.118- ObjectId(i) => { 27.119- write!(f, "{}", Ulid::from(i)) 27.120- } 27.121- } 27.122- } 27.123-}
28.1--- a/obj/src/lib.rs Sat Jun 03 19:57:46 2023 -0400 28.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 28.3@@ -1,149 +0,0 @@ 28.4-//! obj/src/lib.rs --- Objective type library 28.5-#![feature(associated_type_bounds)] 28.6-mod err; 28.7-pub use err::{Error, Result}; 28.8-mod types; 28.9-pub use types::*; 28.10-pub mod id; 28.11-pub mod auth; 28.12-pub mod hash; 28.13-pub mod network; 28.14-pub mod database; 28.15-pub use bincode; 28.16-pub use ron; 28.17-use ron::extensions::Extensions; 28.18-use serde::{de::DeserializeOwned, Deserialize, Serialize}; 28.19-pub use serde_json; 28.20-use std::collections::{BTreeMap, HashMap}; 28.21-use std::io; 28.22- 28.23-/// Objective trait 28.24-/// Define Object behaviors, implemented by Objects 28.25-pub trait Objective { 28.26- fn encode(&self) -> Result<Vec<u8>> 28.27- where 28.28- Self: Serialize, 28.29- { 28.30- Ok(bincode::serialize(self)?) 28.31- } 28.32- 28.33- fn encode_into<W>(&self, writer: W) -> Result<()> 28.34- where 28.35- W: io::Write, 28.36- Self: Serialize, 28.37- { 28.38- Ok(bincode::serialize_into(writer, self)?) 28.39- } 28.40- 28.41- fn decode<'a>(bytes: &'a [u8]) -> Result<Self> 28.42- where 28.43- Self: Deserialize<'a>, 28.44- { 28.45- Ok(bincode::deserialize(bytes)?) 28.46- } 28.47- 28.48- fn decode_from<R>(&self, rdr: R) -> Result<Self> 28.49- where 28.50- R: io::Read, 28.51- Self: DeserializeOwned, 28.52- { 28.53- Ok(bincode::deserialize_from(rdr)?) 28.54- } 28.55- 28.56- fn to_ron_writer<W>(&self, writer: W) -> Result<()> 28.57- where 28.58- W: io::Write, 28.59- Self: Serialize, 28.60- { 28.61- Ok(ron::ser::to_writer_pretty( 28.62- writer, 28.63- &self, 28.64- ron::ser::PrettyConfig::new() 28.65- .indentor(" ".to_owned()) 28.66- .extensions(Extensions::all()), 28.67- )?) 28.68- } 28.69- 28.70- fn to_ron_string(&self) -> Result<String> 28.71- where 28.72- Self: Serialize, 28.73- { 28.74- Ok(ron::ser::to_string_pretty( 28.75- &self, 28.76- ron::ser::PrettyConfig::new().indentor(" ".to_owned()), 28.77- )?) 28.78- } 28.79- 28.80- fn from_ron_reader<R>(&self, mut rdr: R) -> Result<Self> 28.81- where 28.82- R: io::Read, 28.83- Self: DeserializeOwned, 28.84- { 28.85- let mut bytes = Vec::new(); 28.86- rdr.read_to_end(&mut bytes)?; 28.87- Ok(ron::de::from_bytes(&bytes)?) 28.88- } 28.89- 28.90- fn from_ron_str<'a>(s: &'a str) -> Result<Self> 28.91- where 28.92- Self: Deserialize<'a>, 28.93- { 28.94- Ok(ron::de::from_bytes(s.as_bytes())?) 28.95- } 28.96- 28.97- fn to_json_writer<W>(&self, writer: W) -> Result<()> 28.98- where 28.99- W: io::Write, 28.100- Self: Serialize, 28.101- { 28.102- // let formatter = serde_json::ser::PrettyFormatter::with_indent(b" "); 28.103- Ok(serde_json::ser::to_writer_pretty(writer, &self)?) 28.104- } 28.105- 28.106- fn to_json_string(&self) -> Result<String> 28.107- where 28.108- Self: Serialize, 28.109- { 28.110- Ok(serde_json::ser::to_string_pretty(&self)?) 28.111- } 28.112- 28.113- fn from_json_reader<R>(&self, mut rdr: R) -> Result<Self> 28.114- where 28.115- R: io::Read, 28.116- Self: DeserializeOwned, 28.117- { 28.118- let mut bytes = Vec::new(); 28.119- rdr.read_to_end(&mut bytes)?; 28.120- Ok(serde_json::de::from_slice(&bytes)?) 28.121- } 28.122- 28.123- fn from_json_str<'a>(s: &'a str) -> Result<Self> 28.124- where 28.125- Self: Deserialize<'a>, 28.126- { 28.127- Ok(serde_json::de::from_slice(s.as_bytes())?) 28.128- } 28.129-} 28.130- 28.131-impl<T> Objective for Vec<T> {} 28.132-impl<K, V> Objective for HashMap<K, V> {} 28.133-impl<K, V> Objective for BTreeMap<K, V> {} 28.134-impl Objective for std::path::PathBuf {} 28.135-impl Objective for std::path::Path {} 28.136-impl Objective for std::string::String {} 28.137-impl Objective for std::any::TypeId {} 28.138-impl Objective for u8 {} 28.139-impl Objective for u16 {} 28.140-impl Objective for u32 {} 28.141-impl Objective for u64 {} 28.142-impl Objective for u128 {} 28.143-impl Objective for i8 {} 28.144-impl Objective for i16 {} 28.145-impl Objective for i32 {} 28.146-impl Objective for i64 {} 28.147-impl Objective for i128 {} 28.148-impl Objective for isize {} 28.149-impl Objective for usize {} 28.150-impl Objective for f32 {} 28.151-impl Objective for f64 {} 28.152-
29.1--- a/obj/src/network.rs Sat Jun 03 19:57:46 2023 -0400 29.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 29.3@@ -1,59 +0,0 @@ 29.4-//! cfg::config::network 29.5-//! 29.6-//! Network configuration primitives 29.7-use serde::{Deserialize, Serialize}; 29.8-use std::{fmt, net::SocketAddr}; 29.9- 29.10-/// Network configuration 29.11-#[derive(Serialize, Deserialize, Hash, Debug, PartialEq, Clone)] 29.12-pub struct NetworkConfig { 29.13- /// a socket to bind 29.14- pub socket: SocketAddr, 29.15- /// a proxy to forward packets from 29.16- pub proxy: Option<SocketAddr>, 29.17- /// tunnel to use 29.18- pub tunnel: Option<String>, 29.19- /// network engine to attach 29.20- pub engine: EngineType, 29.21- /// peers to register AOT 29.22- pub peers: Option<Vec<SocketAddr>>, 29.23-} 29.24- 29.25-impl Default for NetworkConfig { 29.26- fn default() -> Self { 29.27- NetworkConfig { 29.28- socket: "127.0.0.1:0".parse().unwrap(), 29.29- proxy: None, 29.30- tunnel: None, 29.31- engine: EngineType::default(), 29.32- peers: None, 29.33- } 29.34- } 29.35-} 29.36- 29.37-#[derive(Serialize, Deserialize, Hash, Debug, PartialEq, Clone)] 29.38-pub enum EngineType { 29.39- Quic, 29.40- Http, 29.41- Dns, 29.42- Ssh, 29.43- Uds, 29.44-} 29.45- 29.46-impl Default for EngineType { 29.47- fn default() -> Self { 29.48- Self::Http 29.49- } 29.50-} 29.51- 29.52-impl std::fmt::Display for EngineType { 29.53- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 29.54- match self { 29.55- EngineType::Quic => write!(f, "quic"), 29.56- EngineType::Http => write!(f, "http"), 29.57- EngineType::Dns => write!(f, "dns"), 29.58- EngineType::Ssh => write!(f, "ssh"), 29.59- EngineType::Uds => write!(f, "uds"), 29.60- } 29.61- } 29.62-}
30.1--- a/obj/src/types.rs Sat Jun 03 19:57:46 2023 -0400 30.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 30.3@@ -1,70 +0,0 @@ 30.4-//! obj/src/types.rs --- OBJ type descriptions used by our demo 30.5-use crate::{Deserialize, Objective, Result, Serialize}; 30.6-use std::collections::HashMap; 30.7- 30.8-/// APPLICATION TYPES 30.9-#[derive(Serialize,Deserialize,Default)] 30.10-pub enum Service { 30.11- Weather, 30.12- Stocks, 30.13- Dynamic(Vec<Service>), 30.14- Custom(CustomService), 30.15- #[default] 30.16- Bench, 30.17-} 30.18- 30.19-impl Objective for Service {} 30.20- 30.21-impl From<&str> for Service { 30.22- fn from(value: &str) -> Self { 30.23- match value { 30.24- "weather" => Service::Weather, 30.25- "stocks" => Service::Stocks, 30.26- "bench" => Service::Bench, 30.27- s => { 30.28- if s.contains(",") { 30.29- let x = s.split(","); 30.30- Service::Dynamic( 30.31- x.map(|y| Service::Custom(y.into())) 30.32- .collect::<Vec<Service>>(), 30.33- ) 30.34- } else { 30.35- Service::Custom(s.into()) 30.36- } 30.37- } 30.38- } 30.39- } 30.40-} 30.41- 30.42-#[derive(Serialize,Deserialize,Default)] 30.43-pub struct CustomService { 30.44- name: String, 30.45- registry: HashMap<String,Vec<u8>>, 30.46-} 30.47- 30.48-impl Objective for CustomService {} 30.49-impl From<CustomService> for Service { 30.50- fn from(value: CustomService) -> Self { 30.51- Service::Custom(value) 30.52- } 30.53-} 30.54-impl From<&str> for CustomService { 30.55- fn from(value: &str) -> Self { 30.56- let name = value.to_owned(); 30.57- let registry = HashMap::new(); 30.58- CustomService { name, registry } 30.59- } 30.60-} 30.61- 30.62-#[derive(Serialize, Deserialize,Default)] 30.63-pub struct Complex<X: Objective> { 30.64- data: X, 30.65- stack: Vec<u8>, 30.66- registry: HashMap<String,Vec<u8>>, 30.67-} 30.68- 30.69-impl Objective for Complex<Service> {} 30.70- 30.71-pub fn generate_complex() -> Result<Complex<Service>> { 30.72- Ok(Complex::<Service>::from_json_str("hi")?) 30.73-}
31.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 31.2+++ b/package.lisp Sat Jun 03 22:48:46 2023 -0400 31.3@@ -0,0 +1,75 @@ 31.4+;; demo package.lisp 31.5+(defpackage :demo 31.6+ (:use #:cl #:cffi) 31.7+ (:local-nicknames 31.8+ ;; (#:rdb #:cl-rocksdb) 31.9+ (#:v #:org.shirakumo.verbose) 31.10+ (#:bt #:bordeaux-threads) 31.11+ (#:cli #:clingon)) 31.12+ ;; db.lisp 31.13+ ;; (:export 31.14+ ;; #:create-options 31.15+ ;; #:destroy-options 31.16+ ;; #:increase-parallelism 31.17+ ;; #:optimize-level-style-compaction 31.18+ ;; #:set-create-if-missing 31.19+ ;; #:create-writeoptions 31.20+ ;; #:destroy-writeoptions 31.21+ ;; #:create-readoptions 31.22+ ;; #:destroy-readoptions 31.23+ ;; #:open-db 31.24+ ;; #:close-db 31.25+ ;; #:cancel-all-background-work 31.26+ ;; #:put-kv 31.27+ ;; #:put-kv-str 31.28+ ;; #:get-kv 31.29+ ;; #:get-kv-str 31.30+ ;; #:create-iter 31.31+ ;; #:destroy-iter 31.32+ ;; #:move-iter-to-first 31.33+ ;; #:move-iter-forward 31.34+ ;; #:move-iter-backword 31.35+ ;; #:valid-iter-p 31.36+ ;; #:iter-key 31.37+ ;; #:iter-key-str 31.38+ ;; #:iter-value 31.39+ ;; #:iter-value-str 31.40+ ;; #:with-open-db 31.41+ ;; #:with-iter) 31.42+ ;; demo.lisp 31.43+ (:export 31.44+ #:main 31.45+ #:demo-path 31.46+ #:db-path 31.47+ #:cli-opts 31.48+ #:cli-handler 31.49+ #:cli-cmd) 31.50+ ;; ui.lisp 31.51+ (:export 31.52+ #:on-new-window 31.53+ #:start-ui) 31.54+ ;; tk.lisp 31.55+ (:export 31.56+ #:source-dir 31.57+ #:random-id 31.58+ #:scan-dir 31.59+ #:mkstr 31.60+ #:symb 31.61+ #:sbq-reader) 31.62+ ;; rs.lisp 31.63+ (:export 31.64+ #:*cargo-target* 31.65+ #:*rs-macros* 31.66+ #:rs-defmacro 31.67+ #:rs-macroexpand-1 31.68+ #:rs-macroexpand) 31.69+ ;; ffi.lisp 31.70+ ;; (:export 31.71+ ;; #:quiche-lib-path 31.72+ ;; #:rocksdb-lib-path 31.73+ ;; #:demo-lib-path 31.74+ ;; #:find-rs-cdylib 31.75+ ;; #:install-demo-lib 31.76+ ;; #:install-quiche-lib 31.77+ ;; #:install-rocksdb-lib) 31.78+)
32.1--- a/pkg.lisp Sat Jun 03 19:57:46 2023 -0400 32.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 32.3@@ -1,78 +0,0 @@ 32.4-#| 32.5-demo 32.6-> (demo:main) 32.7-|# 32.8-(defpackage :demo 32.9- (:use #:cl #:cffi) 32.10- (:local-nicknames 32.11- ;; (#:rdb #:cl-rocksdb) 32.12- (#:v #:org.shirakumo.verbose) 32.13- (#:bt #:bordeaux-threads) 32.14- (#:cli #:clingon)) 32.15- ;; db.lisp 32.16- ;; (:export 32.17- ;; #:create-options 32.18- ;; #:destroy-options 32.19- ;; #:increase-parallelism 32.20- ;; #:optimize-level-style-compaction 32.21- ;; #:set-create-if-missing 32.22- ;; #:create-writeoptions 32.23- ;; #:destroy-writeoptions 32.24- ;; #:create-readoptions 32.25- ;; #:destroy-readoptions 32.26- ;; #:open-db 32.27- ;; #:close-db 32.28- ;; #:cancel-all-background-work 32.29- ;; #:put-kv 32.30- ;; #:put-kv-str 32.31- ;; #:get-kv 32.32- ;; #:get-kv-str 32.33- ;; #:create-iter 32.34- ;; #:destroy-iter 32.35- ;; #:move-iter-to-first 32.36- ;; #:move-iter-forward 32.37- ;; #:move-iter-backword 32.38- ;; #:valid-iter-p 32.39- ;; #:iter-key 32.40- ;; #:iter-key-str 32.41- ;; #:iter-value 32.42- ;; #:iter-value-str 32.43- ;; #:with-open-db 32.44- ;; #:with-iter) 32.45- ;; demo.lisp 32.46- (:export 32.47- #:main 32.48- #:demo-path 32.49- #:db-path 32.50- #:cli-opts 32.51- #:cli-handler 32.52- #:cli-cmd) 32.53- ;; ui.lisp 32.54- (:export 32.55- #:on-new-window 32.56- #:start-ui) 32.57- ;; tk.lisp 32.58- (:export 32.59- #:source-dir 32.60- #:random-id 32.61- #:scan-dir 32.62- #:mkstr 32.63- #:symb 32.64- #:sbq-reader) 32.65- ;; rs.lisp 32.66- (:export 32.67- #:*cargo-target* 32.68- #:*rs-macros* 32.69- #:rs-defmacro 32.70- #:rs-macroexpand-1 32.71- #:rs-macroexpand) 32.72- ;; ffi.lisp 32.73- ;; (:export 32.74- ;; #:quiche-lib-path 32.75- ;; #:rocksdb-lib-path 32.76- ;; #:demo-lib-path 32.77- ;; #:find-rs-cdylib 32.78- ;; #:install-demo-lib 32.79- ;; #:install-quiche-lib 32.80- ;; #:install-rocksdb-lib) 32.81- )
33.1--- a/readme.org Sat Jun 03 19:57:46 2023 -0400 33.2+++ b/readme.org Sat Jun 03 22:48:46 2023 -0400 33.3@@ -1,5 +1,22 @@ 33.4-#+TITTLE: cl-demo 33.5-This is a demo software suite which showcases the power of Common Lisp and Rust. 33.6+#+TITTLE: Demo 33.7+Welcome to our first demo system. What you will find here is a modular 33.8+client-server software stack which can be extended and customized by 33.9+the user at runtime. 33.10+ 33.11+* How it works 33.12+The backend services are written in Rust and controlled by a simple 33.13+messaging protocol. Services provide common runtime capabilities known 33.14+as the /core protocol/ but are specialized on a unique /service type/ 33.15+which may in turn register their own /custom protocols/ (via core). 33.16+ 33.17+Services are capable of dispatching data directly to clients, or 33.18+storing data in the /database/ (TBD). 33.19+ 33.20+The frontend clients are pre-dominantly written in Common Lisp and 33.21+come in many shapes and sizes. There is a cli-client, web-client 33.22+(CLOG), docker-client (archlinux, stumpwm, McCLIM), and native-client 33.23+which also compiles to WASM (slint-rs). 33.24+ 33.25 * Guide 33.26 ** Build 33.27 - *install dependencies* 33.28@@ -11,21 +28,19 @@ 33.29 - on MacOS :: =brew install sbcl= 33.30 - on Windows :: download from 33.31 <https://www.sbcl.org/platform-table.html> and figure it out. 33.32- - Quiche 33.33- - RocksDB 33.34 - *make executables* \\ 33.35 Simply run =make build=. Read the ~makefile~ and change the options 33.36 as needed. 33.37 - M :: Mode (debug, release) 33.38 - L :: Lisp (sbcl, cmucl, ccl) 33.39-- P :: Python (python3, python2) 33.40+- C :: Config (default.cfg) 33.41 ** Run 33.42 #+begin_src shell 33.43- make build 33.44- ./out/demo 33.45+ ./demo -i 33.46 #+end_src 33.47 ** Config 33.48-Configs can be specified in JSON, TOML, RON, or of course SEXP. 33.49+Configs can be specified in JSON, TOML, RON, or of course SEXP. See 33.50+=default.cfg= for an example. 33.51 ** Play 33.52 The high-level user interface is presented as a multi-modal GUI 33.53 application which adapts to the specific application /instances/
34.1--- a/rs.lisp Sat Jun 03 19:57:46 2023 -0400 34.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 34.3@@ -1,78 +0,0 @@ 34.4-;;; RUST DSL 34.5- 34.6-;; So basically, this was born out of personal frustration with how 34.7-;; cbindgen and Rust macros work (they don't). Rust macros in general 34.8-;; are something of a pain in my opinion, so I thought why not just 34.9-;; generate Rust code from Lisp instead? 34.10- 34.11-(in-package :demo) 34.12- 34.13-(defvar *cargo-target* #p"/Users/ellis/dev/otom8/demo/target/") 34.14-(defvar *rs-macros* nil) 34.15- 34.16-;; TODO gensyms 34.17-(defmacro rs-defmacro (name args &body body) 34.18- "Define a macro which can be used within the body of a 'with-rs' form." 34.19- `(prog1 34.20- (defmacro ,name ,@(mapcar #`(,a1) args) ,@body) 34.21- (push ',name *rs-macros*))) 34.22- 34.23-(defun rs-mod-form (crate &optional mods pub) 34.24- "Generate a basic mod form (CRATE . [MODS] [PUB])" 34.25- `(,crate ,mods ,pub)) 34.26- 34.27-(defmacro with-rs-env (imports &body body) 34.28- "Generate an environment for use within a Rust generator macro." 34.29- `(let ((imports ,(mapcar #'rs-mod-form imports))) 34.30- (format nil "~A~&~A" imports ',body))) 34.31- 34.32-(defun rs-use (crate &optional mods pub) 34.33- "Generate a single Rust use statement." 34.34- (concatenate 34.35- 'string 34.36- (if pub "pub " "") 34.37- "use " crate "::{" 34.38- (cond 34.39- ((consp mods) 34.40- (reduce 34.41- (lambda (x y) (format nil "~A,~A" x y)) 34.42- mods)) 34.43- (t mods)) 34.44- "};")) 34.45- 34.46-(defun rs-mod (mod &optional pub) 34.47- "Generate a single Rust mod statement." 34.48- (concatenate 34.49- 'string 34.50- (if pub "pub " "") 34.51- "mod " mod ";")) 34.52- 34.53-(defun rs-imports (&rest imports) 34.54- "Generate a string of Rust 'use' statements." 34.55- (cond 34.56- ((consp imports) 34.57- (mapcar (lambda (x) (apply #'rs-use (apply #'rs-mod-form x))) imports)) 34.58- (t imports))) 34.59- 34.60-(defmacro rs-extern-c-fn (name args &optional pub unsafe no-mangle &body body) 34.61- "Generate a Rust extern 'C' fn." 34.62- `(concatenate 34.63- 'string 34.64- ,(when no-mangle (format nil "#[no_mangle]~&")) 34.65- ,(when pub "pub ") 34.66- ,(when unsafe "unsafe ") 34.67- "extern \"C\" fn " ,name "(" 34.68- ,(cond 34.69- ((consp args) (reduce (lambda (x y) (format nil "~A,~A" x y)) args)) 34.70- (t args)) 34.71- ")" "{" ,@body "}")) 34.72- 34.73-(defun rs-obj-impl (obj) 34.74- "Implement Objective for give OBJ." 34.75- (format nil "impl Objective for ~A {};" obj)) 34.76- 34.77-;; (defun rs-macroexpand-1 (form &optional env)) 34.78- 34.79-;; (defun rs-macroexpand (env &rest body) 34.80- 34.81-;;;
35.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 35.2+++ b/src/build.rs Sat Jun 03 22:48:46 2023 -0400 35.3@@ -0,0 +1,17 @@ 35.4+use std::env; 35.5+use std::fs::create_dir; 35.6+use std::path::PathBuf; 35.7+fn main() { 35.8+ let crate_dir: PathBuf = env::var("CARGO_MANIFEST_DIR") 35.9+ .expect("CARGO_MANIFEST_DIR env var is not defined") 35.10+ .into(); 35.11+ // let mpk_py = "build.py"; 35.12+ let build_dir = crate_dir.join("ffi/"); 35.13+ if !build_dir.exists() { 35.14+ create_dir(&build_dir).unwrap(); 35.15+ } 35.16+ cbindgen::generate(crate_dir) 35.17+ .expect("Unable to find cbindgen.toml configuration file") 35.18+ .write_to_file(build_dir.join("demo.h")); 35.19+ 35.20+}
36.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 36.2+++ b/src/cbindgen.toml Sat Jun 03 22:48:46 2023 -0400 36.3@@ -0,0 +1,14 @@ 36.4+include_guard = "demo_h" 36.5+autogen_warning = "/* DO NOT TOUCH */" 36.6+include_version = true 36.7+language = "C" 36.8+cpp_compat = true 36.9+line_length = 88 36.10+documentation = true 36.11+[parse] 36.12+parse_deps = true 36.13+include = ["obj","fig","libc"] 36.14+extra_bindings = ["obj","fig","libc"] 36.15+#expand = ["demo","obj"] 36.16+#[parse.expand] 36.17+#crates = ["demo"] 36.18\ No newline at end of file
38.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 38.2+++ b/src/crates/obj/Cargo.toml Sat Jun 03 22:48:46 2023 -0400 38.3@@ -0,0 +1,27 @@ 38.4+[package] 38.5+name = "obj" 38.6+version = "0.1.0" 38.7+edition = "2021" 38.8+[features] 38.9+oauth = ["yup-oauth2"] 38.10+ 38.11+[dependencies] 38.12+ron = "0.7.0" 38.13+bincode = "1.3.3" 38.14+serde_json = "1.0.68" 38.15+serde = { version = "1.0.130", features = ["derive"] } 38.16+chrono = { version = "0.4.19", features = ["serde"] } 38.17+mime = "0.3.16" 38.18+regex = "1.5.4" 38.19+rusty_ulid = "0.11.0" 38.20+uuid = { version = "0.8", features = ["serde"] } 38.21+yup-oauth2 = { version = "5.1.0", optional = true } 38.22+blake3 = "1.0.0" 38.23+hashbrown = "0.11.2" 38.24+rand = "0.8.0" 38.25+sha2 = "0.9.5" 38.26+hex = "0.4.3" 38.27+ulid = "1.0.0" 38.28+ 38.29+[target.'cfg(target_arch = "wasm32")'.dependencies] 38.30+uuid = { version = "0.8", features = ["wasm-bindgen"] }
39.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 39.2+++ b/src/crates/obj/proc_macros/Cargo.toml Sat Jun 03 22:48:46 2023 -0400 39.3@@ -0,0 +1,10 @@ 39.4+[package] 39.5+name = "proc_macros" 39.6+version = "0.1.0" 39.7+edition = "2021" 39.8+[lib] 39.9+proc-macro = true 39.10+[dependencies] 39.11+quote = "1.0" 39.12+proc-macro2 = "1.0" 39.13+syn = "1.0" 39.14\ No newline at end of file
40.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 40.2+++ b/src/crates/obj/proc_macros/src/derive.rs Sat Jun 03 22:48:46 2023 -0400 40.3@@ -0,0 +1,5 @@ 40.4+mod derive; 40.5+use proc_macro::TokenStream; 40.6+pub fn derive_static_type(input: TokenStream) -> TokenStream { 40.7+ derive::derive_static_type(input) 40.8+}
41.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 41.2+++ b/src/crates/obj/proc_macros/src/lib.rs Sat Jun 03 22:48:46 2023 -0400 41.3@@ -0,0 +1,1 @@ 41.4+
42.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 42.2+++ b/src/crates/obj/src/auth.rs Sat Jun 03 22:48:46 2023 -0400 42.3@@ -0,0 +1,72 @@ 42.4+//! Auth Configs 42.5+use serde::{Deserialize, Serialize}; 42.6+ 42.7+#[cfg(feature = "oauth")] 42.8+use yup_oauth2::ApplicationSecret; 42.9+ 42.10+#[derive(Serialize, Deserialize, Debug, Default, Hash)] 42.11+pub struct AuthConfig { 42.12+ pub provider: String, 42.13+ #[cfg(feature = "oauth")] 42.14+ pub oauth: Option<Oauth2Config>, 42.15+ pub ssh: Option<SshConfig>, 42.16+ pub pw: Option<PasswordConfig>, 42.17+} 42.18+ 42.19+#[derive(Serialize, Deserialize, Default, Debug, Hash)] 42.20+pub struct PasswordConfig(String, String); 42.21+ 42.22+#[cfg(feature = "oauth")] 42.23+#[derive(Serialize, Deserialize, Hash, Debug, PartialEq, Clone, Default)] 42.24+pub struct Oauth2Config { 42.25+ pub client_id: String, 42.26+ pub client_secret: String, 42.27+ pub redirect_uris: Vec<String>, 42.28+ pub auth_uri: String, 42.29+ pub token_uri: String, 42.30+ pub project_id: Option<String>, //for apptoken 42.31+ pub client_email: Option<String>, 42.32+ /// The URL of the public x509 certificate, used to verify the signature on 42.33+ /// JWTs, such as ID tokens, signed by the authentication provider. 42.34+ pub auth_provider_x509_cert_url: Option<String>, 42.35+ /// The URL of the public x509 certificate, used to verify JWTs signed by the 42.36+ /// client. 42.37+ pub client_x509_cert_url: Option<String>, 42.38+} 42.39+ 42.40+#[cfg(feature = "oauth")] 42.41+impl From<ApplicationSecret> for Oauth2Config { 42.42+ fn from(shh: ApplicationSecret) -> Self { 42.43+ Oauth2Config { 42.44+ client_id: shh.client_id, 42.45+ client_secret: shh.client_secret, 42.46+ redirect_uris: shh.redirect_uris, 42.47+ auth_uri: shh.auth_uri, 42.48+ token_uri: shh.token_uri, 42.49+ project_id: shh.project_id, 42.50+ client_email: shh.client_email, 42.51+ auth_provider_x509_cert_url: shh.auth_provider_x509_cert_url, 42.52+ client_x509_cert_url: shh.client_x509_cert_url, 42.53+ } 42.54+ } 42.55+} 42.56+ 42.57+#[cfg(feature = "oauth")] 42.58+impl From<Oauth2Config> for ApplicationSecret { 42.59+ fn from(cfg: Oauth2Config) -> Self { 42.60+ ApplicationSecret { 42.61+ client_id: cfg.client_id, 42.62+ client_secret: cfg.client_secret, 42.63+ redirect_uris: cfg.redirect_uris, 42.64+ auth_uri: cfg.auth_uri, 42.65+ token_uri: cfg.token_uri, 42.66+ project_id: cfg.project_id, 42.67+ client_email: cfg.client_email, 42.68+ auth_provider_x509_cert_url: cfg.auth_provider_x509_cert_url, 42.69+ client_x509_cert_url: cfg.client_x509_cert_url, 42.70+ } 42.71+ } 42.72+} 42.73+ 42.74+#[derive(Serialize, Deserialize, Hash, Debug, PartialEq, Clone, Default)] 42.75+pub struct SshConfig {}
43.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 43.2+++ b/src/crates/obj/src/cfg.rs Sat Jun 03 22:48:46 2023 -0400 43.3@@ -0,0 +1,51 @@ 43.4+/// common trait for all config modules. This trait provides functions 43.5+/// for de/serializing to/from RON, updating fields, and formatting. 43.6+use serde::{Serialize, Deserialize}; 43.7+use crate::Objective; 43.8+use std::collections::HashMap as M; 43.9+use std::path::PathBuf; 43.10+use std::string::String as S; 43.11+use std::error::Error as E; 43.12+use std::boxed::Box as B; 43.13+type R<X> = std::result::Result<X,B<dyn E>>; 43.14+ 43.15+pub trait Configure: Objective { 43.16+ fn update(&self) -> R<()> { 43.17+ Ok(()) 43.18+ } 43.19+} 43.20+ 43.21+#[derive(Serialize, Deserialize, Debug, Default)] 43.22+pub struct ShellConfig { 43.23+ pub env: M<S,S>, 43.24+ pub cmds: M<S,S>, 43.25+ pub shell: ShellType, 43.26+} 43.27+ 43.28+impl Objective for ShellConfig {} 43.29+ 43.30+#[derive(Serialize, Deserialize, Debug, Hash, Default)] 43.31+pub enum ShellType { 43.32+ #[default] 43.33+ Bash, 43.34+ Zsh, 43.35+ Sh, 43.36+} 43.37+ 43.38+#[derive(Serialize, Deserialize, Debug, Default)] 43.39+pub enum EditorType { 43.40+ #[default] 43.41+ Emacs, 43.42+ Vi, 43.43+ Nano, 43.44+} 43.45+ 43.46+#[derive(Serialize, Deserialize, Debug, Default)] 43.47+pub struct EditorConfig { 43.48+ pub editor: EditorType, 43.49+ pub cmds: M<S,S>, 43.50+ pub init_file: PathBuf, 43.51+} 43.52+ 43.53+#[cfg(test)] 43.54+mod tests;
44.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 44.2+++ b/src/crates/obj/src/database.rs Sat Jun 03 22:48:46 2023 -0400 44.3@@ -0,0 +1,18 @@ 44.4+//! cfg::config::database 44.5+//! 44.6+//! Database configuration primitives 44.7+use serde::{Deserialize, Serialize}; 44.8+ 44.9+#[derive(Serialize, Deserialize, Debug, Hash, PartialEq, Eq)] 44.10+pub struct DatabaseConfig { 44.11+ engine: DatabaseType, 44.12+ path: String, 44.13+ cfs: Vec<String>, 44.14+} 44.15+ 44.16+#[derive(Serialize, Deserialize, Debug, Hash, PartialEq, Eq)] 44.17+pub enum DatabaseType { 44.18+ RocksDB, 44.19+ Postgres, 44.20+ Alch, 44.21+}
45.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 45.2+++ b/src/crates/obj/src/err.rs Sat Jun 03 22:48:46 2023 -0400 45.3@@ -0,0 +1,81 @@ 45.4+//! obj errors 45.5+use std::{fmt, io}; 45.6+ 45.7+/// obj Result wrapper 45.8+pub type Result<T> = std::result::Result<T, Error>; 45.9+ 45.10+/// obj Error type 45.11+#[derive(Debug)] 45.12+pub enum Error { 45.13+ Message(String), 45.14+ Ron(ron::error::Error), 45.15+ Json(serde_json::error::Error), 45.16+ Io(io::Error), 45.17+ Bincode(bincode::Error), 45.18+ Utf8(std::string::FromUtf8Error), 45.19+ Parse(std::string::ParseError), 45.20+} 45.21+ 45.22+impl serde::ser::Error for Error { 45.23+ fn custom<T: fmt::Display>(msg: T) -> Self { 45.24+ Error::Message(msg.to_string()) 45.25+ } 45.26+} 45.27+ 45.28+impl serde::de::Error for Error { 45.29+ fn custom<T: fmt::Display>(msg: T) -> Self { 45.30+ Error::Message(msg.to_string()) 45.31+ } 45.32+} 45.33+ 45.34+impl fmt::Display for Error { 45.35+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 45.36+ match self { 45.37+ Error::Message(msg) => f.write_str(msg), 45.38+ Error::Io(ref err) => write!(f, "obj IO error: {}", err), 45.39+ Error::Ron(ref err) => write!(f, "obj Ron error: {}", err), 45.40+ Error::Json(ref err) => write!(f, "obj Json error: {}", err), 45.41+ Error::Bincode(ref err) => write!(f, "obj Bincode error: {}", err), 45.42+ Error::Utf8(ref err) => write!(f, "obj Utf8 error: {}", err), 45.43+ Error::Parse(ref err) => write!(f, "obj Parse error: {}", err), 45.44+ } 45.45+ } 45.46+} 45.47+ 45.48+impl From<io::Error> for Error { 45.49+ fn from(e: io::Error) -> Self { 45.50+ Error::Io(e) 45.51+ } 45.52+} 45.53+ 45.54+impl From<std::string::ParseError> for Error { 45.55+ fn from(e: std::string::ParseError) -> Self { 45.56+ Error::Parse(e) 45.57+ } 45.58+} 45.59+ 45.60+impl From<std::string::FromUtf8Error> for Error { 45.61+ fn from(err: std::string::FromUtf8Error) -> Self { 45.62+ Error::Utf8(err) 45.63+ } 45.64+} 45.65+ 45.66+impl From<ron::Error> for Error { 45.67+ fn from(e: ron::Error) -> Self { 45.68+ Error::Ron(e) 45.69+ } 45.70+} 45.71+ 45.72+impl From<serde_json::Error> for Error { 45.73+ fn from(e: serde_json::Error) -> Self { 45.74+ Error::Json(e) 45.75+ } 45.76+} 45.77+ 45.78+impl From<bincode::Error> for Error { 45.79+ fn from(e: bincode::Error) -> Self { 45.80+ Error::Bincode(e) 45.81+ } 45.82+} 45.83+ 45.84+impl std::error::Error for Error {}
46.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 46.2+++ b/src/crates/obj/src/hash.rs Sat Jun 03 22:48:46 2023 -0400 46.3@@ -0,0 +1,51 @@ 46.4+//! hash - wrapper for hash algorithms and types 46.5+ 46.6+pub use blake3::{derive_key, hash, keyed_hash, Hash as B3Hash, Hasher as B3Hasher, OutputReader}; 46.7+pub use hex; 46.8+pub use sha2::Sha512; 46.9+ 46.10+pub use std::hash::{Hash, Hasher}; 46.11+ 46.12+pub const KEY_LEN: usize = 32; 46.13+pub const OUT_LEN: usize = 32; 46.14+pub const OUT_LEN_HEX: usize = OUT_LEN * 2; 46.15+ 46.16+#[cfg(test)] 46.17+mod tests { 46.18+ use crate::*; 46.19+ use super::*; 46.20+ #[test] 46.21+ fn id_state_hash() { 46.22+ let id = id::Id(vec![0; KEY_LEN]); 46.23+ let hash = id.state_hash(&mut B3Hasher::new()); 46.24+ assert_eq!(hash, id.state_hash(&mut B3Hasher::new())); 46.25+ } 46.26+ 46.27+ #[test] 46.28+ fn id_hex() { 46.29+ let id = id::Id(vec![255; KEY_LEN]); 46.30+ 46.31+ assert_eq!( 46.32+ hex::decode("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(), 46.33+ id.0 46.34+ ); 46.35+ } 46.36+ 46.37+ #[test] 46.38+ fn rand_id() { 46.39+ let id = id::Id::rand(); 46.40+ let hash = id.state_hash(&mut B3Hasher::new()); 46.41+ assert_eq!(hash, id.state_hash(&mut B3Hasher::new())); 46.42+ } 46.43+ 46.44+ #[test] 46.45+ fn random_demon_id_is_valid() { 46.46+ use id::PeerId; 46.47+ for _ in 0..5000 { 46.48+ let did = PeerId::rand(); 46.49+ let did2 = PeerId::rand(); 46.50+ assert_eq!(did, did); 46.51+ assert_ne!(did, did2); 46.52+ } 46.53+ } 46.54+}
47.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 47.2+++ b/src/crates/obj/src/id.rs Sat Jun 03 22:48:46 2023 -0400 47.3@@ -0,0 +1,120 @@ 47.4+use std::{fmt, str::FromStr}; 47.5+use serde::{Serialize, Deserialize}; 47.6+pub use uuid::Uuid; 47.7+pub use ulid::Ulid; 47.8+use rand::Rng; 47.9+use crate::hash::{KEY_LEN,OUT_LEN,B3Hasher}; 47.10+/// a simple Id abstraction 47.11+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Serialize, Deserialize, Hash)] 47.12+pub struct Id(pub Vec<u8>); 47.13+ 47.14+impl Id { 47.15+ pub fn rand() -> Self { 47.16+ let mut rng = rand::thread_rng(); 47.17+ let vals: Vec<u8> = (0..KEY_LEN).map(|_| rng.gen_range(0..u8::MAX)).collect(); 47.18+ Id(vals) 47.19+ } 47.20+ 47.21+ pub fn state_hash(&self, state: &mut B3Hasher) -> Self { 47.22+ let mut output = vec![0; OUT_LEN]; 47.23+ state.update(&self.0); 47.24+ let mut res = state.finalize_xof(); 47.25+ res.fill(&mut output); 47.26+ Id(output) 47.27+ } 47.28+ 47.29+ pub fn to_hex(&self) -> String { 47.30+ hex::encode(&self.0) 47.31+ } 47.32+} 47.33+ 47.34+/// PeerId 47.35+/// 47.36+/// identifies a unique Peer 47.37+#[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd, Debug)] 47.38+pub struct PeerId { 47.39+ id: [u8; 32], 47.40+} 47.41+ 47.42+impl PeerId { 47.43+ pub fn new() -> Self { 47.44+ Self::default() 47.45+ } 47.46+ 47.47+ pub fn rand() -> Self { 47.48+ let pd = rand::thread_rng().gen::<[u8; 32]>(); 47.49+ Self { id: pd } 47.50+ } 47.51+ 47.52+ pub fn from_bytes(data: &[u8]) -> Self { 47.53+ let pd = blake3::hash(data); 47.54+ let hash = pd.as_bytes(); 47.55+ Self { id: *hash } 47.56+ } 47.57+} 47.58+ 47.59+impl Default for PeerId { 47.60+ fn default() -> Self { 47.61+ PeerId { id: [0; 32] } 47.62+ } 47.63+} 47.64+ 47.65+/// Identity trait 47.66+/// 47.67+/// Defines Identity-related behaviors 47.68+pub trait Identity: Sized { 47.69+ /// return the hashed bytes of an ObjectId 47.70+ fn id(&self) -> Id; 47.71+} 47.72+ 47.73+#[derive(Debug, Copy, Clone, Eq, PartialEq)] 47.74+pub struct ObjectId(u128); 47.75+ 47.76+pub struct NameSpace { 47.77+ pub prefix: Option<String>, 47.78+ pub capacity: u64, 47.79+ pub route: Vec<Id>, 47.80+ pub key: Option<Id>, 47.81+} 47.82+ 47.83+pub struct Domain { 47.84+ pub ns: NameSpace, 47.85+ pub id: Id, 47.86+} 47.87+ 47.88+impl From<Uuid> for ObjectId { 47.89+ fn from(uuid: Uuid) -> Self { 47.90+ ObjectId(uuid.as_u128()) 47.91+ } 47.92+} 47.93+ 47.94+impl From<Ulid> for ObjectId { 47.95+ fn from(ulid: Ulid) -> Self { 47.96+ ObjectId(u128::from(ulid)) 47.97+ } 47.98+} 47.99+ 47.100+impl From<u128> for ObjectId { 47.101+ fn from(src: u128) -> Self { 47.102+ ObjectId(src) 47.103+ } 47.104+} 47.105+ 47.106+impl FromStr for ObjectId { 47.107+ type Err = (); 47.108+ fn from_str(input: &str) -> std::result::Result<ObjectId, Self::Err> { 47.109+ match input { 47.110+ i => Ok(ObjectId(u128::from(Ulid::from_str(i).unwrap()))), 47.111+ } 47.112+ } 47.113+} 47.114+ 47.115+impl fmt::Display for ObjectId { 47.116+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 47.117+ match *self { 47.118+ ObjectId(i) => { 47.119+ write!(f, "{}", Ulid::from(i)) 47.120+ } 47.121+ } 47.122+ } 47.123+}
48.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 48.2+++ b/src/crates/obj/src/lib.rs Sat Jun 03 22:48:46 2023 -0400 48.3@@ -0,0 +1,149 @@ 48.4+//! obj/src/lib.rs --- Objective type library 48.5+#![feature(associated_type_bounds)] 48.6+mod err; 48.7+pub use err::{Error, Result}; 48.8+mod types; 48.9+pub use types::*; 48.10+pub mod id; 48.11+pub mod auth; 48.12+pub mod hash; 48.13+pub mod network; 48.14+pub mod database; 48.15+pub use bincode; 48.16+pub use ron; 48.17+use ron::extensions::Extensions; 48.18+use serde::{de::DeserializeOwned, Deserialize, Serialize}; 48.19+pub use serde_json; 48.20+use std::collections::{BTreeMap, HashMap}; 48.21+use std::io; 48.22+ 48.23+/// Objective trait 48.24+/// Define Object behaviors, implemented by Objects 48.25+pub trait Objective { 48.26+ fn encode(&self) -> Result<Vec<u8>> 48.27+ where 48.28+ Self: Serialize, 48.29+ { 48.30+ Ok(bincode::serialize(self)?) 48.31+ } 48.32+ 48.33+ fn encode_into<W>(&self, writer: W) -> Result<()> 48.34+ where 48.35+ W: io::Write, 48.36+ Self: Serialize, 48.37+ { 48.38+ Ok(bincode::serialize_into(writer, self)?) 48.39+ } 48.40+ 48.41+ fn decode<'a>(bytes: &'a [u8]) -> Result<Self> 48.42+ where 48.43+ Self: Deserialize<'a>, 48.44+ { 48.45+ Ok(bincode::deserialize(bytes)?) 48.46+ } 48.47+ 48.48+ fn decode_from<R>(&self, rdr: R) -> Result<Self> 48.49+ where 48.50+ R: io::Read, 48.51+ Self: DeserializeOwned, 48.52+ { 48.53+ Ok(bincode::deserialize_from(rdr)?) 48.54+ } 48.55+ 48.56+ fn to_ron_writer<W>(&self, writer: W) -> Result<()> 48.57+ where 48.58+ W: io::Write, 48.59+ Self: Serialize, 48.60+ { 48.61+ Ok(ron::ser::to_writer_pretty( 48.62+ writer, 48.63+ &self, 48.64+ ron::ser::PrettyConfig::new() 48.65+ .indentor(" ".to_owned()) 48.66+ .extensions(Extensions::all()), 48.67+ )?) 48.68+ } 48.69+ 48.70+ fn to_ron_string(&self) -> Result<String> 48.71+ where 48.72+ Self: Serialize, 48.73+ { 48.74+ Ok(ron::ser::to_string_pretty( 48.75+ &self, 48.76+ ron::ser::PrettyConfig::new().indentor(" ".to_owned()), 48.77+ )?) 48.78+ } 48.79+ 48.80+ fn from_ron_reader<R>(&self, mut rdr: R) -> Result<Self> 48.81+ where 48.82+ R: io::Read, 48.83+ Self: DeserializeOwned, 48.84+ { 48.85+ let mut bytes = Vec::new(); 48.86+ rdr.read_to_end(&mut bytes)?; 48.87+ Ok(ron::de::from_bytes(&bytes)?) 48.88+ } 48.89+ 48.90+ fn from_ron_str<'a>(s: &'a str) -> Result<Self> 48.91+ where 48.92+ Self: Deserialize<'a>, 48.93+ { 48.94+ Ok(ron::de::from_bytes(s.as_bytes())?) 48.95+ } 48.96+ 48.97+ fn to_json_writer<W>(&self, writer: W) -> Result<()> 48.98+ where 48.99+ W: io::Write, 48.100+ Self: Serialize, 48.101+ { 48.102+ // let formatter = serde_json::ser::PrettyFormatter::with_indent(b" "); 48.103+ Ok(serde_json::ser::to_writer_pretty(writer, &self)?) 48.104+ } 48.105+ 48.106+ fn to_json_string(&self) -> Result<String> 48.107+ where 48.108+ Self: Serialize, 48.109+ { 48.110+ Ok(serde_json::ser::to_string_pretty(&self)?) 48.111+ } 48.112+ 48.113+ fn from_json_reader<R>(&self, mut rdr: R) -> Result<Self> 48.114+ where 48.115+ R: io::Read, 48.116+ Self: DeserializeOwned, 48.117+ { 48.118+ let mut bytes = Vec::new(); 48.119+ rdr.read_to_end(&mut bytes)?; 48.120+ Ok(serde_json::de::from_slice(&bytes)?) 48.121+ } 48.122+ 48.123+ fn from_json_str<'a>(s: &'a str) -> Result<Self> 48.124+ where 48.125+ Self: Deserialize<'a>, 48.126+ { 48.127+ Ok(serde_json::de::from_slice(s.as_bytes())?) 48.128+ } 48.129+} 48.130+ 48.131+impl<T> Objective for Vec<T> {} 48.132+impl<K, V> Objective for HashMap<K, V> {} 48.133+impl<K, V> Objective for BTreeMap<K, V> {} 48.134+impl Objective for std::path::PathBuf {} 48.135+impl Objective for std::path::Path {} 48.136+impl Objective for std::string::String {} 48.137+impl Objective for std::any::TypeId {} 48.138+impl Objective for u8 {} 48.139+impl Objective for u16 {} 48.140+impl Objective for u32 {} 48.141+impl Objective for u64 {} 48.142+impl Objective for u128 {} 48.143+impl Objective for i8 {} 48.144+impl Objective for i16 {} 48.145+impl Objective for i32 {} 48.146+impl Objective for i64 {} 48.147+impl Objective for i128 {} 48.148+impl Objective for isize {} 48.149+impl Objective for usize {} 48.150+impl Objective for f32 {} 48.151+impl Objective for f64 {} 48.152+
49.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 49.2+++ b/src/crates/obj/src/network.rs Sat Jun 03 22:48:46 2023 -0400 49.3@@ -0,0 +1,59 @@ 49.4+//! cfg::config::network 49.5+//! 49.6+//! Network configuration primitives 49.7+use serde::{Deserialize, Serialize}; 49.8+use std::{fmt, net::SocketAddr}; 49.9+ 49.10+/// Network configuration 49.11+#[derive(Serialize, Deserialize, Hash, Debug, PartialEq, Clone)] 49.12+pub struct NetworkConfig { 49.13+ /// a socket to bind 49.14+ pub socket: SocketAddr, 49.15+ /// a proxy to forward packets from 49.16+ pub proxy: Option<SocketAddr>, 49.17+ /// tunnel to use 49.18+ pub tunnel: Option<String>, 49.19+ /// network engine to attach 49.20+ pub engine: EngineType, 49.21+ /// peers to register AOT 49.22+ pub peers: Option<Vec<SocketAddr>>, 49.23+} 49.24+ 49.25+impl Default for NetworkConfig { 49.26+ fn default() -> Self { 49.27+ NetworkConfig { 49.28+ socket: "127.0.0.1:0".parse().unwrap(), 49.29+ proxy: None, 49.30+ tunnel: None, 49.31+ engine: EngineType::default(), 49.32+ peers: None, 49.33+ } 49.34+ } 49.35+} 49.36+ 49.37+#[derive(Serialize, Deserialize, Hash, Debug, PartialEq, Clone)] 49.38+pub enum EngineType { 49.39+ Quic, 49.40+ Http, 49.41+ Dns, 49.42+ Ssh, 49.43+ Uds, 49.44+} 49.45+ 49.46+impl Default for EngineType { 49.47+ fn default() -> Self { 49.48+ Self::Http 49.49+ } 49.50+} 49.51+ 49.52+impl std::fmt::Display for EngineType { 49.53+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 49.54+ match self { 49.55+ EngineType::Quic => write!(f, "quic"), 49.56+ EngineType::Http => write!(f, "http"), 49.57+ EngineType::Dns => write!(f, "dns"), 49.58+ EngineType::Ssh => write!(f, "ssh"), 49.59+ EngineType::Uds => write!(f, "uds"), 49.60+ } 49.61+ } 49.62+}
50.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 50.2+++ b/src/crates/obj/src/types.rs Sat Jun 03 22:48:46 2023 -0400 50.3@@ -0,0 +1,70 @@ 50.4+//! obj/src/types.rs --- OBJ type descriptions used by our demo 50.5+use crate::{Deserialize, Objective, Result, Serialize}; 50.6+use std::collections::HashMap; 50.7+ 50.8+/// APPLICATION TYPES 50.9+#[derive(Serialize,Deserialize,Default)] 50.10+pub enum Service { 50.11+ Weather, 50.12+ Stocks, 50.13+ Dynamic(Vec<Service>), 50.14+ Custom(CustomService), 50.15+ #[default] 50.16+ Bench, 50.17+} 50.18+ 50.19+impl Objective for Service {} 50.20+ 50.21+impl From<&str> for Service { 50.22+ fn from(value: &str) -> Self { 50.23+ match value { 50.24+ "weather" => Service::Weather, 50.25+ "stocks" => Service::Stocks, 50.26+ "bench" => Service::Bench, 50.27+ s => { 50.28+ if s.contains(",") { 50.29+ let x = s.split(","); 50.30+ Service::Dynamic( 50.31+ x.map(|y| Service::Custom(y.into())) 50.32+ .collect::<Vec<Service>>(), 50.33+ ) 50.34+ } else { 50.35+ Service::Custom(s.into()) 50.36+ } 50.37+ } 50.38+ } 50.39+ } 50.40+} 50.41+ 50.42+#[derive(Serialize,Deserialize,Default)] 50.43+pub struct CustomService { 50.44+ name: String, 50.45+ registry: HashMap<String,Vec<u8>>, 50.46+} 50.47+ 50.48+impl Objective for CustomService {} 50.49+impl From<CustomService> for Service { 50.50+ fn from(value: CustomService) -> Self { 50.51+ Service::Custom(value) 50.52+ } 50.53+} 50.54+impl From<&str> for CustomService { 50.55+ fn from(value: &str) -> Self { 50.56+ let name = value.to_owned(); 50.57+ let registry = HashMap::new(); 50.58+ CustomService { name, registry } 50.59+ } 50.60+} 50.61+ 50.62+#[derive(Serialize, Deserialize,Default)] 50.63+pub struct Complex<X: Objective> { 50.64+ data: X, 50.65+ stack: Vec<u8>, 50.66+ registry: HashMap<String,Vec<u8>>, 50.67+} 50.68+ 50.69+impl Objective for Complex<Service> {} 50.70+ 50.71+pub fn generate_complex() -> Result<Complex<Service>> { 50.72+ Ok(Complex::<Service>::from_json_str("hi")?) 50.73+}
51.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 51.2+++ b/src/crates/ui/Cargo.toml Sat Jun 03 22:48:46 2023 -0400 51.3@@ -0,0 +1,22 @@ 51.4+[package] 51.5+name = "ui" 51.6+version = "0.1.0" 51.7+edition = "2021" 51.8+build = "build.rs" 51.9+[lib] 51.10+path = "lib.rs" 51.11+crate-type = ["rlib","cdylib"] 51.12+[[bin]] 51.13+name = "demo-ui" 51.14+path = "main.rs" 51.15+[build-dependencies] 51.16+slint-build = "1.0.2" 51.17+[dependencies] 51.18+obj = {version = "0.1.0",path = "../obj"} 51.19+env_logger = "0.10.0" 51.20+log = "0.4.17" 51.21+slint = "1.0.2" 51.22+[target.'cfg(target_arch = "wasm32")'.dependencies] 51.23+wasm-bindgen = { version = "0.2" } 51.24+web-sys = { version = "0.3", features=["console"] } 51.25+console_error_panic_hook = "0.1.5"
52.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 52.2+++ b/src/crates/ui/build.rs Sat Jun 03 22:48:46 2023 -0400 52.3@@ -0,0 +1,3 @@ 52.4+fn main() { 52.5+ slint_build::compile("ui.slint").unwrap(); 52.6+}
53.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 53.2+++ b/src/crates/ui/config.slint Sat Jun 03 22:48:46 2023 -0400 53.3@@ -0,0 +1,3 @@ 53.4+export global UiConfig { 53.5+ in property<bool> widgets-disabled: false; 53.6+} 53.7\ No newline at end of file
54.1Binary file src/crates/ui/img/ayo.jpeg has changed
55.1Binary file src/crates/ui/img/treez.png has changed
56.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 56.2+++ b/src/crates/ui/index.html Sat Jun 03 22:48:46 2023 -0400 56.3@@ -0,0 +1,9 @@ 56.4+<html> 56.5+ <body> 56.6+ <canvas id="canvas">>/canvas> 56.7+ <script type="module"> 56.8+ import init from './pkg/ui.js'; 56.9+ init(); 56.10+ </script> 56.11+ </body> 56.12+</html>
57.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 57.2+++ b/src/crates/ui/lib.rs Sat Jun 03 22:48:46 2023 -0400 57.3@@ -0,0 +1,69 @@ 57.4+#![deny(unsafe_code)] 57.5+ 57.6+#[cfg(target_arch = "wasm32")] 57.7+use wasm_bindgen::prelude::*; 57.8+ 57.9+slint::include_modules!(); 57.10+ 57.11+use std::rc::Rc; 57.12+ 57.13+use slint::{Model, StandardListViewItem, VecModel}; 57.14+ 57.15+#[cfg_attr(target_arch = "wasm32", wasm_bindgen(start))] 57.16+pub fn run() { 57.17+ // This provides better error messages in debug mode. 57.18+ // It's disabled in release mode so it doesn't bloat up the file size. 57.19+ #[cfg(all(debug_assertions, target_arch = "wasm32"))] 57.20+ console_error_panic_hook::set_once(); 57.21+ 57.22+ let app = App::new().unwrap(); 57.23+ 57.24+ let row_data: Rc<VecModel<slint::ModelRc<StandardListViewItem>>> = Rc::new(VecModel::default()); 57.25+ 57.26+ for r in 1..101 { 57.27+ let items = Rc::new(VecModel::default()); 57.28+ 57.29+ for c in 1..5 { 57.30+ items.push(slint::format!("Item {r}.{c}").into()); 57.31+ } 57.32+ 57.33+ row_data.push(items.into()); 57.34+ } 57.35+ 57.36+ app.global::<TableViewPageAdapter>().set_row_data(row_data.clone().into()); 57.37+ 57.38+ app.global::<TableViewPageAdapter>().on_sort_ascending({ 57.39+ let app_weak = app.as_weak(); 57.40+ let row_data = row_data.clone(); 57.41+ move |index| { 57.42+ let row_data = row_data.clone(); 57.43+ 57.44+ let sort_model = Rc::new(row_data.sort_by(move |r_a, r_b| { 57.45+ let c_a = r_a.row_data(index as usize).unwrap(); 57.46+ let c_b = r_b.row_data(index as usize).unwrap(); 57.47+ 57.48+ c_a.text.cmp(&c_b.text) 57.49+ })); 57.50+ 57.51+ app_weak.unwrap().global::<TableViewPageAdapter>().set_row_data(sort_model.into()); 57.52+ } 57.53+ }); 57.54+ 57.55+ app.global::<TableViewPageAdapter>().on_sort_descending({ 57.56+ let app_weak = app.as_weak(); 57.57+ move |index| { 57.58+ let row_data = row_data.clone(); 57.59+ 57.60+ let sort_model = Rc::new(row_data.sort_by(move |r_a, r_b| { 57.61+ let c_a = r_a.row_data(index as usize).unwrap(); 57.62+ let c_b = r_b.row_data(index as usize).unwrap(); 57.63+ 57.64+ c_b.text.cmp(&c_a.text) 57.65+ })); 57.66+ 57.67+ app_weak.unwrap().global::<TableViewPageAdapter>().set_row_data(sort_model.into()); 57.68+ } 57.69+ }); 57.70+ 57.71+ app.run().unwrap(); 57.72+}
58.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 58.2+++ b/src/crates/ui/main.rs Sat Jun 03 22:48:46 2023 -0400 58.3@@ -0,0 +1,4 @@ 58.4+use ui::run; 58.5+fn main() { 58.6+ run(); 58.7+}
59.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 59.2+++ b/src/crates/ui/pages.slint Sat Jun 03 22:48:46 2023 -0400 59.3@@ -0,0 +1,7 @@ 59.4+import { AboutPage } from "pages/about.slint"; 59.5+import { ControlsPage } from "pages/controls.slint"; 59.6+import { ListViewPage } from "pages/list_view.slint"; 59.7+import { TableViewPage, TableViewPageAdapter } from "pages/table_view.slint"; 59.8+import { TextEditPage } from "pages/text_edit.slint"; 59.9+ 59.10+export { AboutPage, ControlsPage, ListViewPage, TextEditPage, TableViewPage, TableViewPageAdapter } 59.11\ No newline at end of file
60.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 60.2+++ b/src/crates/ui/pages/about.slint Sat Jun 03 22:48:46 2023 -0400 60.3@@ -0,0 +1,10 @@ 60.4+import { AboutSlint } from "std-widgets.slint"; 60.5+import { UiConfig } from "../config.slint"; 60.6+import { Page } from "page.slint"; 60.7+ 60.8+export component AboutPage inherits Page { 60.9+ title: "About"; 60.10+ description: "Are you curious now? Check out the docs and gettings start from the Github repository and the website https://slint-ui.com and try it yourself."; 60.11+ 60.12+ AboutSlint {} 60.13+} 60.14\ No newline at end of file
61.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 61.2+++ b/src/crates/ui/pages/controls.slint Sat Jun 03 22:48:46 2023 -0400 61.3@@ -0,0 +1,145 @@ 61.4+import { Button, GroupBox, SpinBox, ComboBox, CheckBox, LineEdit, TabWidget, VerticalBox, HorizontalBox, 61.5+ Slider, SpinBox } from "std-widgets.slint"; 61.6+import { UiConfig } from "../config.slint"; 61.7+import { Page } from "page.slint"; 61.8+ 61.9+export component ControlsPage inherits Page { 61.10+ title: "Controls"; 61.11+ description: "This page gives an overview of the default widget set provided by Slint. The widgets are available in different styles native, fluent-(dark/light) and material-(dark/light). The widgets can be imported from \"std-widgets.slint\"."; 61.12+ 61.13+ GroupBox { 61.14+ vertical-stretch: 0; 61.15+ title: "Buttons"; 61.16+ 61.17+ HorizontalLayout { 61.18+ spacing: 8px; 61.19+ alignment: start; 61.20+ 61.21+ Button { 61.22+ text: "Regular Button"; 61.23+ enabled: !UiConfig.widgets-disabled; 61.24+ } 61.25+ 61.26+ Button { 61.27+ text: "Button with Icon"; 61.28+ icon: @image-url("../img/treez.png"); 61.29+ enabled: !UiConfig.widgets-disabled; 61.30+ } 61.31+ 61.32+ Button { 61.33+ checkable: true; 61.34+ text: self.checked ? "ON" : "OFF"; 61.35+ enabled: !UiConfig.widgets-disabled; 61.36+ } 61.37+ } 61.38+ } 61.39+ 61.40+ GroupBox { 61.41+ title: "CheckBox - SpinBox - ComboBox"; 61.42+ vertical-stretch: 0; 61.43+ 61.44+ HorizontalBox { 61.45+ alignment: start; 61.46+ checkbox := CheckBox { 61.47+ text: checkbox.checked ? "(checked)" : "(unchecked)"; 61.48+ checked: true; 61.49+ enabled: !UiConfig.widgets-disabled; 61.50+ } 61.51+ 61.52+ 61.53+ SpinBox { 61.54+ vertical-stretch: 0; 61.55+ value: 42; 61.56+ enabled: !UiConfig.widgets-disabled; 61.57+ } 61.58+ 61.59+ ComboBox { 61.60+ model: ["Select Something", "From this", "Combobox"]; 61.61+ enabled: !UiConfig.widgets-disabled; 61.62+ } 61.63+ } 61.64+ 61.65+ 61.66+ } 61.67+ 61.68+ GroupBox { 61.69+ title: "LineEdit"; 61.70+ vertical-stretch: 0; 61.71+ 61.72+ LineEdit { 61.73+ placeholder-text: "Enter some text"; 61.74+ enabled: !UiConfig.widgets-disabled; 61.75+ } 61.76+ } 61.77+ 61.78+ GroupBox { 61.79+ title: "Slider"; 61.80+ vertical-stretch: 0; 61.81+ 61.82+ Slider { 61.83+ min-width: 160px; 61.84+ minimum: -100; 61.85+ maximum: 100; 61.86+ value: 42; 61.87+ enabled: !UiConfig.widgets-disabled; 61.88+ } 61.89+ } 61.90+ 61.91+ GroupBox { 61.92+ title: "TabWidget"; 61.93+ 61.94+ TabWidget { 61.95+ Tab { 61.96+ title: "Tab 1"; 61.97+ 61.98+ VerticalBox { 61.99+ alignment: start; 61.100+ 61.101+ GroupBox { 61.102+ title: "Content of tab 1"; 61.103+ 61.104+ HorizontalBox { 61.105+ alignment: start; 61.106+ 61.107+ Button { 61.108+ text: "Click me"; 61.109+ enabled: !UiConfig.widgets-disabled; 61.110+ } 61.111+ } 61.112+ } 61.113+ } 61.114+ } 61.115+ 61.116+ Tab { 61.117+ title: "Tab 2"; 61.118+ 61.119+ VerticalBox { 61.120+ alignment: start; 61.121+ 61.122+ GroupBox { 61.123+ title: "Content of tab 2"; 61.124+ 61.125+ VerticalBox { 61.126+ alignment: start; 61.127+ 61.128+ CheckBox { 61.129+ text: "Check me"; 61.130+ enabled: !UiConfig.widgets-disabled; 61.131+ } 61.132+ } 61.133+ } 61.134+ } 61.135+ } 61.136+ 61.137+ Tab { 61.138+ title: "Tab 3"; 61.139+ 61.140+ VerticalBox { 61.141+ Text { 61.142+ text: "Content of tab 3"; 61.143+ } 61.144+ } 61.145+ } 61.146+ } 61.147+ } 61.148+} 61.149\ No newline at end of file
62.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 62.2+++ b/src/crates/ui/pages/list_view.slint Sat Jun 03 22:48:46 2023 -0400 62.3@@ -0,0 +1,45 @@ 62.4+import { HorizontalBox, VerticalBox, ListView, StandardListView, GroupBox } from "std-widgets.slint"; 62.5+import { UiConfig } from "../config.slint"; 62.6+import { Page } from "page.slint"; 62.7+ 62.8+export component ListViewPage inherits Page { 62.9+ title: "ListView"; 62.10+ description: "ListViews can be used to display a list of elements. The StandardListBox is like the default ListView just with a default text based definition of the visual items. Both can be imported from \"std-widgets.slint\""; 62.11+ 62.12+ HorizontalBox { 62.13+ vertical-stretch: 1; 62.14+ GroupBox { 62.15+ title: "ListView"; 62.16+ 62.17+ ListView { 62.18+ vertical-stretch: 0; 62.19+ for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] : HorizontalBox { 62.20+ Image { 62.21+ width: 24px; 62.22+ source: @image-url("../img/ayo.jpeg"); 62.23+ } 62.24+ Text { 62.25+ text: "Item " + i; 62.26+ } 62.27+ } 62.28+ } 62.29+ } 62.30+ 62.31+ GroupBox { 62.32+ title: "StandardListView"; 62.33+ vertical-stretch: 0; 62.34+ 62.35+ StandardListView { 62.36+ model: [ 62.37+ {text: "Lorem"}, {text: "ipsum"},{text: "dolor"},{text: "sit"},{text: "amet"},{text: "consetetur"}, 62.38+ {text: "Lorem"}, {text: "ipsum"},{text: "dolor"},{text: "sit"},{text: "amet"},{text: "consetetur"}, 62.39+ {text: "Lorem"}, {text: "ipsum"},{text: "dolor"},{text: "sit"},{text: "amet"},{text: "consetetur"}, 62.40+ {text: "Lorem"}, {text: "ipsum"},{text: "dolor"},{text: "sit"},{text: "amet"},{text: "consetetur"}, 62.41+ {text: "Lorem"}, {text: "ipsum"},{text: "dolor"},{text: "sit"},{text: "amet"},{text: "consetetur"}, 62.42+ {text: "Lorem"}, {text: "ipsum"},{text: "dolor"},{text: "sit"},{text: "amet"},{text: "consetetur"}, 62.43+ {text: "Lorem"}, {text: "ipsum"},{text: "dolor"},{text: "sit"},{text: "amet"},{text: "consetetur"}, 62.44+ ]; 62.45+ } 62.46+ } 62.47+ } 62.48+} 62.49\ No newline at end of file
63.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 63.2+++ b/src/crates/ui/pages/page.slint Sat Jun 03 22:48:46 2023 -0400 63.3@@ -0,0 +1,27 @@ 63.4+import { CheckBox, GridBox, ListView, ScrollView, VerticalBox } from "std-widgets.slint"; 63.5+ 63.6+import { UiConfig } from "../config.slint"; 63.7+ 63.8+export component Page inherits VerticalBox { 63.9+ in property<string> title: "title"; 63.10+ in property<string> description: "description"; 63.11+ 63.12+ HorizontalLayout { 63.13+ height: 24px; 63.14+ Text { 63.15+ font-size: 20px; 63.16+ text <=> root.title; 63.17+ } 63.18+ 63.19+ // Spacer 63.20+ Rectangle {} 63.21+ 63.22+ CheckBox { 63.23+ horizontal-stretch: 0; 63.24+ text: "Disable widgets"; 63.25+ checked <=> UiConfig.widgets-disabled; 63.26+ } 63.27+ } 63.28+ 63.29+ @children 63.30+} 63.31\ No newline at end of file
64.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 64.2+++ b/src/crates/ui/pages/table_view.slint Sat Jun 03 22:48:46 2023 -0400 64.3@@ -0,0 +1,48 @@ 64.4+import { HorizontalBox, VerticalBox, StandardTableView, GroupBox} from "std-widgets.slint"; 64.5+import { UiConfig } from "../config.slint"; 64.6+import { Page } from "page.slint"; 64.7+ 64.8+export global TableViewPageAdapter { 64.9+ callback sort_ascending(int); 64.10+ callback sort_descending(int); 64.11+ in property <[[StandardListViewItem]]> row_data: [ 64.12+ [ { text: "Item 1.1" }, { text: "Item 1.2" }, { text: "Item 1.3" }, { text: "Item 1.4" }, ], 64.13+ [ { text: "Item 2.1" }, { text: "Item 2.2" }, { text: "Item 2.3" }, { text: "Item 2.4" }, ], 64.14+ [ { text: "Item 3.1" }, { text: "Item 3.2" }, { text: "Item 3.3" }, { text: "Item 3.4" }, ], 64.15+ [ { text: "Item 4.1" }, { text: "Item 4.2" }, { text: "Item 4.3" }, { text: "Item 4.4" }, ], 64.16+ [ { text: "Item 5.1" }, { text: "Item 5.2" }, { text: "Item 5.3" }, { text: "Item 5.4" }, ], 64.17+ [ { text: "Item 6.1" }, { text: "Item 6.2" }, { text: "Item 6.3" }, { text: "Item 6.4" }, ], 64.18+ ]; 64.19+} 64.20+ 64.21+export component TableViewPage inherits Page { 64.22+ title: "TableView"; 64.23+ description: "StandardTableView can be used to display a list of text elements in columns and rows. It can be imported from \"std-widgets.slint\""; 64.24+ 64.25+ HorizontalBox { 64.26+ vertical-stretch: 1; 64.27+ 64.28+ GroupBox { 64.29+ title: "StandardTableView"; 64.30+ vertical-stretch: 0; 64.31+ 64.32+ StandardTableView { 64.33+ sort-ascending(index) => { 64.34+ TableViewPageAdapter.sort_ascending(index); 64.35+ } 64.36+ 64.37+ sort-descending(index) => { 64.38+ TableViewPageAdapter.sort-descending(index); 64.39+ } 64.40+ 64.41+ columns: [ 64.42+ { title: "Header 1" }, 64.43+ { title: "Header 2" }, 64.44+ { title: "Header 3" }, 64.45+ { title: "Header 4" }, 64.46+ ]; 64.47+ rows: TableViewPageAdapter.row_data; 64.48+ } 64.49+ } 64.50+ } 64.51+} 64.52\ No newline at end of file
65.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 65.2+++ b/src/crates/ui/pages/text_edit.slint Sat Jun 03 22:48:46 2023 -0400 65.3@@ -0,0 +1,32 @@ 65.4+import { HorizontalBox, GroupBox, TextEdit } from "std-widgets.slint"; 65.5+import { UiConfig } from "../config.slint"; 65.6+import { Page } from "page.slint"; 65.7+ 65.8+export component TextEditPage inherits Page { 65.9+ title: "TextEdit"; 65.10+ description: "Similar to LineEdit, but can be used to enter several lines of text. The widget can be imported from \"std-widgets.slint\"."; 65.11+ 65.12+ HorizontalBox { 65.13+ GroupBox { 65.14+ vertical-stretch: 0; 65.15+ title: "Word-Wrap"; 65.16+ te1 := TextEdit { 65.17+ min-width: 200px; 65.18+ text: "This is our TextEdit widget, which allows for editing text that spans over multiple paragraphs.\nFor example this line starts in a new paragraph.\n\nWhen the amount of lines - due to wrapping and number of paragraphs - exceeds the available vertical height, a vertical scrollbar is shown that allows scrolling.\nYou may want to enter a bit of text here then in order to make them visible."; 65.19+ wrap: word-wrap; 65.20+ enabled: !UiConfig.widgets-disabled; 65.21+ } 65.22+ } 65.23+ 65.24+ GroupBox { 65.25+ title: "No-Wrap"; 65.26+ vertical-stretch: 0; 65.27+ te2 := TextEdit { 65.28+ min-width: 200px; 65.29+ text <=> te1.text; 65.30+ wrap: no-wrap; 65.31+ enabled: !UiConfig.widgets-disabled; 65.32+ } 65.33+ } 65.34+ } 65.35+} 65.36\ No newline at end of file
66.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 66.2+++ b/src/crates/ui/sidebar.slint Sat Jun 03 22:48:46 2023 -0400 66.3@@ -0,0 +1,127 @@ 66.4+import { StyleMetrics } from "std-widgets.slint"; 66.5+ 66.6+component SideBarItem inherits Rectangle { 66.7+ callback clicked <=> touch.clicked; 66.8+ in-out property<string> text <=> label.text; 66.9+ in property<bool> selected; 66.10+ in property<bool> has-focus; 66.11+ 66.12+ min-height: l.preferred-height; 66.13+ 66.14+ state := Rectangle { 66.15+ opacity: 0; 66.16+ background: StyleMetrics.window-background; 66.17+ 66.18+ animate opacity { duration: 150ms; } 66.19+ } 66.20+ 66.21+ l := HorizontalLayout { 66.22+ y: (parent.height - self.height) / 2; 66.23+ padding: StyleMetrics.layout-padding; 66.24+ spacing: 0px; 66.25+ 66.26+ label := Text { 66.27+ color: StyleMetrics.default-text-color; 66.28+ vertical-alignment: center; 66.29+ } 66.30+ } 66.31+ 66.32+ touch := TouchArea { 66.33+ width: 100%; 66.34+ height: 100%; 66.35+ } 66.36+ 66.37+ states [ 66.38+ pressed when touch.pressed : { 66.39+ state.opacity: 0.8; 66.40+ } 66.41+ hover when touch.has-hover : { 66.42+ state.opacity: 0.6; 66.43+ } 66.44+ selected when root.selected : { 66.45+ state.opacity: 1; 66.46+ } 66.47+ focused when root.has-focus : { 66.48+ state.opacity: 0.8; 66.49+ } 66.50+ ] 66.51+} 66.52+ 66.53+export component SideBar inherits Rectangle { 66.54+ in property<[string]> model: []; 66.55+ out property<int> current-item: 0; 66.56+ in property<string> title <=> label.text; 66.57+ out property<int> current-focused: fs.has-focus ? fs.focused-tab : -1; // The currently focused tab 66.58+ width: 180px; 66.59+ 66.60+ forward-focus: fs; 66.61+ 66.62+ accessible-role: tab; 66.63+ accessible-delegate-focus: root.current-focused >= 0 ? root.current-focused : root.current-item; 66.64+ 66.65+ Rectangle { 66.66+ background: StyleMetrics.window-background.darker(0.2); 66.67+ 66.68+ fs := FocusScope { 66.69+ x:0; 66.70+ width: 0px; // Do not react on clicks 66.71+ property<int> focused-tab: 0; 66.72+ 66.73+ key-pressed(event) => { 66.74+ if (event.text == "\n") { 66.75+ root.current-item = root.current-focused; 66.76+ return accept; 66.77+ } 66.78+ if (event.text == Key.UpArrow) { 66.79+ self.focused-tab = Math.max(self.focused-tab - 1, 0); 66.80+ return accept; 66.81+ } 66.82+ if (event.text == Key.DownArrow) { 66.83+ self.focused-tab = Math.min(self.focused-tab + 1, root.model.length - 1); 66.84+ return accept; 66.85+ } 66.86+ return reject; 66.87+ } 66.88+ 66.89+ key-released(event) => { 66.90+ if (event.text == " ") { 66.91+ root.current-item = root.current-focused; 66.92+ return accept; 66.93+ } 66.94+ return reject; 66.95+ } 66.96+ } 66.97+ } 66.98+ 66.99+ VerticalLayout { 66.100+ padding-top: StyleMetrics.layout-padding; 66.101+ padding-bottom: StyleMetrics.layout-padding; 66.102+ spacing: StyleMetrics.layout-spacing; 66.103+ alignment: start; 66.104+ 66.105+ label := Text { 66.106+ font-size: 16px; 66.107+ horizontal-alignment: center; 66.108+ } 66.109+ 66.110+ navigation := VerticalLayout { 66.111+ alignment: start; 66.112+ vertical-stretch: 0; 66.113+ for item[index] in root.model : SideBarItem { 66.114+ has-focus: index == root.current-focused; 66.115+ text: item; 66.116+ selected: index == root.current-item; 66.117+ clicked => { root.current-item = index; } 66.118+ } 66.119+ } 66.120+ 66.121+ VerticalLayout { 66.122+ bottom := VerticalLayout { 66.123+ padding-left: StyleMetrics.layout-padding; 66.124+ padding-right: StyleMetrics.layout-padding; 66.125+ 66.126+ @children 66.127+ } 66.128+ } 66.129+ } 66.130+} 66.131\ No newline at end of file
67.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 67.2+++ b/src/crates/ui/ui.slint Sat Jun 03 22:48:46 2023 -0400 67.3@@ -0,0 +1,20 @@ 67.4+import {CheckBox, StandardListView, StyleMetrics} from "std-widgets.slint"; 67.5+import {AboutPage, ControlsPage, ListViewPage, TableViewPage, TableViewPageAdapter, TextEditPage} from "pages.slint"; 67.6+import {UiConfig} from "config.slint"; 67.7+import {SideBar} from "sidebar.slint"; 67.8+export {TableViewPageAdapter} 67.9+export component App inherits Window { 67.10+ title: "Demo"; 67.11+ icon: @image-url("img/treez.png"); 67.12+ HorizontalLayout { 67.13+ side-bar := SideBar { 67.14+ title: "Demo"; 67.15+ model: ["Controls", "ListView", "TableView", "TextEdit", "About"]; 67.16+ } 67.17+ if(side-bar.current-item == 0) : ControlsPage {} 67.18+ if(side-bar.current-item == 1) : ListViewPage {} 67.19+ if(side-bar.current-item == 2) : TableViewPage {} 67.20+ if(side-bar.current-item == 3) : TextEditPage {} 67.21+ if(side-bar.current-item == 4) : AboutPage {} 67.22+ } 67.23+} 67.24\ No newline at end of file
68.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 68.2+++ b/src/db.lisp Sat Jun 03 22:48:46 2023 -0400 68.3@@ -0,0 +1,197 @@ 68.4+(in-package :demo) 68.5+ 68.6+(define-foreign-library rocksdb 68.7+ (:win32 "rocksdb") 68.8+ (t (:default "librocksdb"))) 68.9+ 68.10+(use-foreign-library rocksdb) 68.11+ 68.12+(defcfun ("rocksdb_options_create" create-options) :pointer) 68.13+(defcfun ("rocksdb_options_destroy" destroy-options) :void (options :pointer)) 68.14+(defcfun ("rocksdb_options_increase_parallelism" increase-parallelism) :void (opt :pointer) (total-threads :int)) 68.15+(defcfun ("rocksdb_options_optimize_level_style_compaction" optimize-level-style-compaction) :void (opt :pointer) (memtable_memory_budget :uint64)) 68.16+(defcfun ("rocksdb_options_set_create_if_missing" set-create-if-missing) :void (opt :pointer) (val :boolean)) 68.17+ 68.18+(defcfun ("rocksdb_writeoptions_create" create-writeoptions) :pointer) 68.19+(defcfun ("rocksdb_writeoptions_destroy" destroy-writeoptions) :void (opt :pointer)) 68.20+(defcfun ("rocksdb_readoptions_create" create-readoptions) :pointer) 68.21+(defcfun ("rocksdb_readoptions_destroy" destroy-readoptions) :void (opt :pointer)) 68.22+ 68.23+(defcfun ("rocksdb_open" open-db*) :pointer (opt :pointer) (name :string) (errptr :pointer)) 68.24+(defcfun ("rocksdb_close" close-db) :void (opt :pointer)) 68.25+(defcfun ("rocksdb_cancel_all_background_work" cancel-all-background-work) :void (db :pointer) (wait :boolean)) 68.26+ 68.27+(defcfun ("rocksdb_put" put*) :void (db :pointer) (options :pointer) (key :pointer) (keylen :unsigned-int) (val :pointer) (vallen :unsigned-int) (errptr :pointer)) 68.28+(defcfun ("rocksdb_get" get*) :pointer (db :pointer) (options :pointer) (key :pointer) (keylen :unsigned-int) (vallen :pointer) (errptr :pointer)) 68.29+ 68.30+(defcfun ("rocksdb_create_iterator" create-iter*) :pointer (db :pointer) (opt :pointer)) 68.31+(defcfun ("rocksdb_iter_destroy" destroy-iter) :void (iter :pointer)) 68.32+(defcfun ("rocksdb_iter_seek_to_first" move-iter-to-first) :void (iter :pointer)) 68.33+(defcfun ("rocksdb_iter_valid" valid-iter-p) :boolean (iter :pointer)) 68.34+(defcfun ("rocksdb_iter_next" move-iter-forward) :void (iter :pointer)) 68.35+(defcfun ("rocksdb_iter_prev" move-iter-backward) :void (iter :pointer)) 68.36+(defcfun ("rocksdb_iter_key" iter-key*) :pointer (iter :pointer) (klen-ptr :pointer)) 68.37+(defcfun ("rocksdb_iter_value" iter-value*) :pointer (iter :pointer) (vlen-ptr :pointer)) 68.38+ 68.39+(define-condition unable-to-open-db (error) 68.40+ ((db-path :initarg :db-path 68.41+ :reader db-path) 68.42+ (error-message :initarg :error-message 68.43+ :reader error-message))) 68.44+ 68.45+(defmethod print-object ((obj unable-to-open-db) stream) 68.46+ (print-unreadable-object (obj stream :type t :identity t) 68.47+ (format stream "error-message=~A" (error-message obj)))) 68.48+ 68.49+(define-condition unable-to-put-key-value-to-db (error) 68.50+ ((db :initarg :db 68.51+ :reader db) 68.52+ (key :initarg :key 68.53+ :reader key) 68.54+ (val :initarg :val 68.55+ :reader val) 68.56+ (error-message :initarg :error-message 68.57+ :reader error-message))) 68.58+ 68.59+(define-condition unable-to-get-value-to-db (error) 68.60+ ((db :initarg :db 68.61+ :reader db) 68.62+ (key :initarg :key 68.63+ :reader key) 68.64+ (error-message :initarg :error-message 68.65+ :reader error-message))) 68.66+ 68.67+(defun open-db (db-path &optional opt) 68.68+ (unless opt 68.69+ (setq opt (create-options))) 68.70+ (let ((errptr (foreign-alloc :pointer))) 68.71+ (setf (mem-ref errptr :pointer) (null-pointer)) 68.72+ (let* ((db-path (if (pathnamep db-path) 68.73+ (namestring db-path) 68.74+ db-path)) 68.75+ (db (open-db* opt db-path errptr)) 68.76+ (err (mem-ref errptr :pointer))) 68.77+ (unless (null-pointer-p err) 68.78+ (error 'unable-to-open-db 68.79+ :db-path db-path 68.80+ :error-message (foreign-string-to-lisp err))) 68.81+ db))) 68.82+ 68.83+(defmacro clone-octets-to-foreign (lisp-array foreign-array) 68.84+ (let ((i (gensym))) 68.85+ `(loop for ,i from 0 below (length ,lisp-array) 68.86+ do (setf (mem-aref ,foreign-array :unsigned-char ,i) 68.87+ (aref ,lisp-array ,i))))) 68.88+ 68.89+(defmacro clone-octets-from-foreign (foreign-array lisp-array len) 68.90+ (let ((i (gensym))) 68.91+ `(loop for ,i from 0 below ,len 68.92+ do (setf (aref ,lisp-array ,i) 68.93+ (mem-aref ,foreign-array :unsigned-char ,i))))) 68.94+ 68.95+(defun put-kv (db key val &optional opt) 68.96+ (unless opt 68.97+ (setq opt (create-writeoptions))) 68.98+ (with-foreign-objects ((errptr :pointer) 68.99+ (key* :unsigned-char (length key)) 68.100+ (val* :unsigned-char (length val))) 68.101+ (clone-octets-to-foreign key key*) 68.102+ (clone-octets-to-foreign val val*) 68.103+ (setf (mem-ref errptr :pointer) (null-pointer)) 68.104+ (put* db 68.105+ opt 68.106+ key* 68.107+ (length key) 68.108+ val* 68.109+ (length val) 68.110+ errptr) 68.111+ (let ((err (mem-ref errptr :pointer))) 68.112+ (unless (null-pointer-p err) 68.113+ (error 'unable-to-put-key-value-to-db 68.114+ :db db 68.115+ :key key 68.116+ :val val 68.117+ :error-message (foreign-string-to-lisp err)))))) 68.118+ 68.119+(defun put-kv-str (db key val &optional opt) 68.120+ (let ((key-octets (babel:string-to-octets key)) 68.121+ (val-octets (babel:string-to-octets val))) 68.122+ (put-kv db key-octets val-octets opt))) 68.123+ 68.124+(defun get-kv (db key &optional opt) 68.125+ (unless opt 68.126+ (setq opt (create-readoptions))) 68.127+ 68.128+ (with-foreign-objects ((val-len-ptr :unsigned-int) 68.129+ (errptr :pointer) 68.130+ (key* :unsigned-char (length key))) 68.131+ (clone-octets-to-foreign key key*) 68.132+ (setf (mem-ref errptr :pointer) (null-pointer)) 68.133+ (let ((val (get* db 68.134+ opt 68.135+ key* 68.136+ (length key) 68.137+ val-len-ptr 68.138+ errptr))) 68.139+ (let ((err (mem-ref errptr :pointer))) 68.140+ (unless (null-pointer-p err) 68.141+ (error 'unable-to-get-value-to-db 68.142+ :db db 68.143+ :key key 68.144+ :error-message (foreign-string-to-lisp err))) 68.145+ 68.146+ (unless (null-pointer-p val) 68.147+ (let* ((val-len (mem-ref val-len-ptr :unsigned-int)) 68.148+ (val* (make-array val-len 68.149+ :element-type '(unsigned-byte 8)))) 68.150+ (clone-octets-from-foreign val val* val-len) 68.151+ val*)))))) 68.152+ 68.153+(defun get-kv-str (db key &optional opt) 68.154+ (let ((key-octets (babel:string-to-octets key))) 68.155+ (let ((#1=val-octets (get-kv db key-octets opt))) 68.156+ (when #1# 68.157+ (babel:octets-to-string #1#))))) 68.158+ 68.159+(defun create-iter (db &optional opt) 68.160+ (unless opt 68.161+ (setq opt (create-readoptions))) 68.162+ (create-iter* db opt)) 68.163+ 68.164+(defun iter-key (iter) 68.165+ (with-foreign-objects ((klen-ptr :unsigned-int)) 68.166+ (setf (mem-ref klen-ptr :unsigned-int) 0) 68.167+ (let* ((key-ptr (iter-key* iter klen-ptr)) 68.168+ (klen (mem-ref klen-ptr :unsigned-int)) 68.169+ (key (make-array klen :element-type '(unsigned-byte 8)))) 68.170+ (clone-octets-from-foreign key-ptr key klen) 68.171+ key))) 68.172+ 68.173+(defun iter-key-str (iter) 68.174+ (let ((#1=key-octets (iter-key iter))) 68.175+ (when #1# 68.176+ (babel:octets-to-string #1#)))) 68.177+ 68.178+(defun iter-value (iter) 68.179+ (with-foreign-objects ((len-ptr :unsigned-int)) 68.180+ (setf (mem-ref len-ptr :unsigned-int) 0) 68.181+ (let* ((value-ptr (iter-value* iter len-ptr)) 68.182+ (vlen (mem-ref len-ptr :unsigned-int)) 68.183+ (value* (make-array vlen :element-type '(unsigned-byte 8)))) 68.184+ (clone-octets-from-foreign value-ptr value* vlen) 68.185+ value*))) 68.186+ 68.187+(defun iter-value-str (iter) 68.188+ (let ((#1=val-octets (iter-value iter))) 68.189+ (when #1# 68.190+ (babel:octets-to-string #1#)))) 68.191+ 68.192+(defmacro with-open-db ((db-var db-path &optional opt) &body body) 68.193+ `(let ((,db-var (open-db ,db-path ,opt))) 68.194+ (unwind-protect (progn ,@body) 68.195+ (close-db ,db-var)))) 68.196+ 68.197+(defmacro with-iter ((iter-var db &optional opt) &body body) 68.198+ `(let ((,iter-var (create-iter ,db ,opt))) 68.199+ (unwind-protect (progn ,@body) 68.200+ (destroy-iter ,iter-var))))
69.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 69.2+++ b/src/demo.lisp Sat Jun 03 22:48:46 2023 -0400 69.3@@ -0,0 +1,45 @@ 69.4+;; demo.lisp 69.5+(in-package :demo) 69.6+ 69.7+(defparameter demo-path (merge-pathnames "cl-demo" (uiop:temporary-directory))) 69.8+ 69.9+(defvar db-path (merge-pathnames "db" demo-path)) 69.10+ 69.11+(defun cli-opts () 69.12+ "Returns the top-level CLI options." 69.13+ (list 69.14+ (cli:make-option 69.15+ :string 69.16+ :description "demo app to run" 69.17+ :short-name #\x 69.18+ :long-name "app" 69.19+ :initial-value "client" 69.20+ :env-vars '("DEMO_APP") 69.21+ :key :app) 69.22+ (cli:make-option 69.23+ :string 69.24+ :description "path to config" 69.25+ :short-name #\c 69.26+ :long-name "config" 69.27+ :initial-value "$DEMO_PATH/.fig" 69.28+ :env-vars '("DEMO_CONFIG")))) 69.29+ 69.30+(defun cli-handler (cmd) 69.31+ "Handler for the `demo' command." 69.32+ (let ((app (cli:getopt cmd :app))) 69.33+ (format t "running: ~A!~%" app))) 69.34+ 69.35+(defun cli-cmd () 69.36+ "Our demo command." 69.37+ (cli:make-command 69.38+ :name "demo" 69.39+ :description "A collection of demos" 69.40+ :version "1.0.0" 69.41+ :authors '("ellis <ellis@rwest.io>") 69.42+ :license "WTFPL" 69.43+ :options (cli-opts) 69.44+ :handler #'cli-handler)) 69.45+ 69.46+(defun main () 69.47+ "A demo of some common-lisp functionality." 69.48+ (cli:run (cli-cmd)))
70.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 70.2+++ b/src/ffi.lisp Sat Jun 03 22:48:46 2023 -0400 70.3@@ -0,0 +1,28 @@ 70.4+(in-package :demo) 70.5+(defparameter quiche-lib-path #p"./ffi/libquiche.dylib") 70.6+;;(defparameter rocksdb-lib-path #p"./ffi/librocksdb.dylib") 70.7+(defparameter demo-lib-path (find-rs-cdylib "libdemo.dylib")) 70.8+(defmacro find-rs-cdylib (name &optional debug) 70.9+ "Find the rust dll specified by NAME." 70.10+ (cond 70.11+ ((uiop:directory-exists-p (merge-pathnames *cargo-target* "release")) 70.12+ `,(mkstr "./target/release/" name)) 70.13+ ((uiop:directory-exists-p (merge-pathnames *cargo-target* "debug")) 70.14+ `,(mkstr "./target/debug/" name)) 70.15+ (t `(progn 70.16+ ,(uiop:run-program '("cargo" "build" (unless debug "--release")) :output t) 70.17+ (find-rs-cdylib ,name ,debug))))) 70.18+ 70.19+(define-foreign-library demo 70.20+ (:win32 (:default "demo")) 70.21+ (t (:default "libdemo"))) 70.22+(define-foreign-library quiche 70.23+ (:win32 (:default "quiche")) 70.24+ (t (:default "libquiche"))) 70.25+;; (define-foreign-library rocksdb 70.26+;; (:win32 (:default "rocksdb")) 70.27+;; (t (:default "librocksdb"))) 70.28+ 70.29+(defun load-libdemo () (load-foreign-library (find-rs-cdylib "libdemo.dylib"))) 70.30+(defun install-quiche-lib (&optional path) (load-foreign-library (or path quiche-lib-path))) 70.31+;; (defun install-rocksdb-lib (&optional path) (load-foreign-library (or path rocksdb-lib-path)))
71.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 71.2+++ b/src/gen.rs Sat Jun 03 22:48:46 2023 -0400 71.3@@ -0,0 +1,84 @@ 71.4+//! demo 71.5+pub use fig::*; 71.6+pub use obj::*; 71.7+use std::ffi::{CStr, CString}; //OsStr,Path 71.8+ //use std::os::unix::ffi::OsStrExt; 71.9+use std::slice; 71.10+use libc::{c_char,size_t}; 71.11+ 71.12+#[macro_export] 71.13+macro_rules! cdefn { 71.14+ (free $t:tt $n:tt) => { 71.15+ #[no_mangle] 71.16+ pub unsafe extern "C" fn $n(ptr: *mut $t) { 71.17+ if ptr.is_null() { 71.18+ return; 71.19+ } 71.20+ let _ = Box::from_raw(ptr); 71.21+ } 71.22+ }; 71.23+ (from_string $t:tt $n:tt) => { 71.24+ #[no_mangle] 71.25+ pub unsafe extern "C" fn $n(ptr: *const c_char) -> *mut $t { 71.26+ assert!(!ptr.is_null()); 71.27+ let p = CStr::from_ptr(ptr).to_str().unwrap(); 71.28+ Box::into_raw(Box::new(p.into())) 71.29+ } 71.30+ }; 71.31+ (json_string $t:tt $r:tt $w:tt) => { 71.32+ #[no_mangle] 71.33+ pub unsafe extern "C" fn $r(ptr: *const c_char) -> *mut $t { 71.34+ assert!(!ptr.is_null()); 71.35+ let s = CStr::from_ptr(ptr); 71.36+ Box::into_raw(Box::new($t::from_json_str(&s.to_str().unwrap()).unwrap())) 71.37+ } 71.38+ 71.39+ #[no_mangle] 71.40+ pub unsafe extern "C" fn $w(ptr: *const $t) -> *mut c_char { 71.41+ let p = &*ptr; 71.42+ let x = p.to_json_string().unwrap(); 71.43+ CString::new(x.as_str().as_bytes()).unwrap().into_raw() 71.44+ } 71.45+ }; 71.46+ (ron_string $t:tt $r:tt $w:tt) => { 71.47+ #[no_mangle] 71.48+ pub unsafe extern "C" fn $r(ptr: *const c_char) -> *mut $t { 71.49+ assert!(!ptr.is_null()); 71.50+ let s = CStr::from_ptr(ptr); 71.51+ Box::into_raw(Box::new($t::from_ron_str(&s.to_str().unwrap()).unwrap())) 71.52+ } 71.53+ 71.54+ #[no_mangle] 71.55+ pub unsafe extern "C" fn $w(ptr: *const $t) -> *mut c_char { 71.56+ let p = &*ptr; 71.57+ let x = p.to_ron_string().unwrap(); 71.58+ CString::new(x.as_str().as_bytes()).unwrap().into_raw() 71.59+ } 71.60+ }; 71.61+ (bytes $t:tt $r:tt $w:tt) => { 71.62+ #[no_mangle] 71.63+ pub unsafe extern "C" fn $r(ptr: *const u8, len: size_t) -> *mut $t { 71.64+ Box::into_raw(Box::new($t::decode(slice::from_raw_parts(ptr,len)).unwrap())) 71.65+ } 71.66+ 71.67+ #[no_mangle] 71.68+ pub unsafe extern "C" fn $w(ptr: *const $t) -> *mut u8 { 71.69+ let p = &*ptr; 71.70+ let mut x = p.encode().unwrap(); 71.71+ let r = x.as_mut_ptr(); 71.72+ std::mem::forget(x); 71.73+ r 71.74+ } 71.75+ } 71.76+} 71.77+ 71.78+cdefn!(free Service free_service); 71.79+cdefn!(from_string Service service_from_string); 71.80+cdefn!(json_string Service service_from_json_string service_to_json_string); 71.81+cdefn!(ron_string Service service_from_ron_string service_to_ron_string); 71.82+cdefn!(bytes Service service_decode service_encode); 71.83+cdefn!(free CustomService free_custom_service); 71.84+cdefn!(from_string CustomService custom_service_from_string); 71.85+cdefn!(json_string CustomService custom_service_from_json_string custom_service_to_json_string); 71.86+cdefn!(ron_string CustomService custom_service_from_ron_string custom_service_to_ron_string); 71.87+cdefn!(bytes CustomService custom_service_decode custom_service_encode);
72.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 72.2+++ b/src/lib.rs Sat Jun 03 22:48:46 2023 -0400 72.3@@ -0,0 +1,117 @@ 72.4+//! demo/lib.rs --- generated by DEMO:RS-MACROEXPAND 72.5+extern crate libc; 72.6+extern crate obj; 72.7+use libc::{c_char, size_t}; 72.8+use obj::{CustomService, Objective, Service}; 72.9+use std::ffi::{CStr, CString}; 72.10+use std::slice; 72.11+#[no_mangle] 72.12+pub unsafe extern "C" fn free_service(ptr: *mut Service) { 72.13+ if ptr.is_null() { 72.14+ return; 72.15+ } 72.16+ let _ = Box::from_raw(ptr); 72.17+} 72.18+#[no_mangle] 72.19+pub unsafe extern "C" fn service_from_string(ptr: *const c_char) -> *mut Service { 72.20+ assert!(!ptr.is_null()); 72.21+ let p = CStr::from_ptr(ptr).to_str().unwrap(); 72.22+ Box::into_raw(Box::new(p.into())) 72.23+} 72.24+#[no_mangle] 72.25+pub unsafe extern "C" fn service_from_json_string(ptr: *const c_char) -> *mut Service { 72.26+ assert!(!ptr.is_null()); 72.27+ let s = CStr::from_ptr(ptr); 72.28+ Box::into_raw(Box::new( 72.29+ Service::from_json_str(&s.to_str().unwrap()).unwrap(), 72.30+ )) 72.31+} 72.32+#[no_mangle] 72.33+pub unsafe extern "C" fn service_to_json_string(ptr: *const Service) -> *mut c_char { 72.34+ let p = &*ptr; 72.35+ let x = p.to_json_string().unwrap(); 72.36+ CString::new(x.as_str().as_bytes()).unwrap().into_raw() 72.37+} 72.38+#[no_mangle] 72.39+pub unsafe extern "C" fn service_from_ron_string(ptr: *const c_char) -> *mut Service { 72.40+ assert!(!ptr.is_null()); 72.41+ let s = CStr::from_ptr(ptr); 72.42+ Box::into_raw(Box::new( 72.43+ Service::from_ron_str(&s.to_str().unwrap()).unwrap(), 72.44+ )) 72.45+} 72.46+#[no_mangle] 72.47+pub unsafe extern "C" fn service_to_ron_string(ptr: *const Service) -> *mut c_char { 72.48+ let p = &*ptr; 72.49+ let x = p.to_ron_string().unwrap(); 72.50+ CString::new(x.as_str().as_bytes()).unwrap().into_raw() 72.51+} 72.52+#[no_mangle] 72.53+pub unsafe extern "C" fn service_decode(ptr: *const u8, len: size_t) -> *mut Service { 72.54+ Box::into_raw(Box::new( 72.55+ Service::decode(slice::from_raw_parts(ptr, len)).unwrap(), 72.56+ )) 72.57+} 72.58+#[no_mangle] 72.59+pub unsafe extern "C" fn service_encode(ptr: *const Service) -> *mut u8 { 72.60+ let p = &*ptr; 72.61+ let mut x = p.encode().unwrap(); 72.62+ let r = x.as_mut_ptr(); 72.63+ std::mem::forget(x); 72.64+ r 72.65+} 72.66+#[no_mangle] 72.67+pub unsafe extern "C" fn free_custom_service(ptr: *mut CustomService) { 72.68+ if ptr.is_null() { 72.69+ return; 72.70+ } 72.71+ let _ = Box::from_raw(ptr); 72.72+} 72.73+#[no_mangle] 72.74+pub unsafe extern "C" fn custom_service_from_string(ptr: *const c_char) -> *mut CustomService { 72.75+ assert!(!ptr.is_null()); 72.76+ let p = CStr::from_ptr(ptr).to_str().unwrap(); 72.77+ Box::into_raw(Box::new(p.into())) 72.78+} 72.79+#[no_mangle] 72.80+pub unsafe extern "C" fn custom_service_from_json_string(ptr: *const c_char) -> *mut CustomService { 72.81+ assert!(!ptr.is_null()); 72.82+ let s = CStr::from_ptr(ptr); 72.83+ Box::into_raw(Box::new( 72.84+ CustomService::from_json_str(&s.to_str().unwrap()).unwrap(), 72.85+ )) 72.86+} 72.87+#[no_mangle] 72.88+pub unsafe extern "C" fn custom_service_to_json_string(ptr: *const CustomService) -> *mut c_char { 72.89+ let p = &*ptr; 72.90+ let x = p.to_json_string().unwrap(); 72.91+ CString::new(x.as_str().as_bytes()).unwrap().into_raw() 72.92+} 72.93+#[no_mangle] 72.94+pub unsafe extern "C" fn custom_service_from_ron_string(ptr: *const c_char) -> *mut CustomService { 72.95+ assert!(!ptr.is_null()); 72.96+ let s = CStr::from_ptr(ptr); 72.97+ Box::into_raw(Box::new( 72.98+ CustomService::from_ron_str(&s.to_str().unwrap()).unwrap(), 72.99+ )) 72.100+} 72.101+#[no_mangle] 72.102+pub unsafe extern "C" fn custom_service_to_ron_string(ptr: *const CustomService) -> *mut c_char { 72.103+ let p = &*ptr; 72.104+ let x = p.to_ron_string().unwrap(); 72.105+ CString::new(x.as_str().as_bytes()).unwrap().into_raw() 72.106+} 72.107+#[no_mangle] 72.108+pub unsafe extern "C" fn custom_service_decode(ptr: *const u8, len: size_t) -> *mut CustomService { 72.109+ Box::into_raw(Box::new( 72.110+ CustomService::decode(slice::from_raw_parts(ptr, len)).unwrap(), 72.111+ )) 72.112+} 72.113+#[no_mangle] 72.114+pub unsafe extern "C" fn custom_service_encode(ptr: *const CustomService) -> *mut u8 { 72.115+ let p = &*ptr; 72.116+ let mut x = p.encode().unwrap(); 72.117+ let r = x.as_mut_ptr(); 72.118+ std::mem::forget(x); 72.119+ r 72.120+}
73.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 73.2+++ b/src/rs.lisp Sat Jun 03 22:48:46 2023 -0400 73.3@@ -0,0 +1,78 @@ 73.4+;;; RUST DSL 73.5+ 73.6+;; So basically, this was born out of personal frustration with how 73.7+;; cbindgen and Rust macros work (they don't). Rust macros in general 73.8+;; are something of a pain in my opinion, so I thought why not just 73.9+;; generate Rust code from Lisp instead? 73.10+ 73.11+(in-package :demo) 73.12+ 73.13+(defvar *cargo-target* #p"/Users/ellis/dev/otom8/demo/target/") 73.14+(defvar *rs-macros* nil) 73.15+ 73.16+;; TODO gensyms 73.17+(defmacro rs-defmacro (name args &body body) 73.18+ "Define a macro which can be used within the body of a 'with-rs' form." 73.19+ `(prog1 73.20+ (defmacro ,name ,@(mapcar #`(,a1) args) ,@body) 73.21+ (push ',name *rs-macros*))) 73.22+ 73.23+(defun rs-mod-form (crate &optional mods pub) 73.24+ "Generate a basic mod form (CRATE . [MODS] [PUB])" 73.25+ `(,crate ,mods ,pub)) 73.26+ 73.27+(defmacro with-rs-env (imports &body body) 73.28+ "Generate an environment for use within a Rust generator macro." 73.29+ `(let ((imports ,(mapcar #'rs-mod-form imports))) 73.30+ (format nil "~A~&~A" imports ',body))) 73.31+ 73.32+(defun rs-use (crate &optional mods pub) 73.33+ "Generate a single Rust use statement." 73.34+ (concatenate 73.35+ 'string 73.36+ (if pub "pub " "") 73.37+ "use " crate "::{" 73.38+ (cond 73.39+ ((consp mods) 73.40+ (reduce 73.41+ (lambda (x y) (format nil "~A,~A" x y)) 73.42+ mods)) 73.43+ (t mods)) 73.44+ "};")) 73.45+ 73.46+(defun rs-mod (mod &optional pub) 73.47+ "Generate a single Rust mod statement." 73.48+ (concatenate 73.49+ 'string 73.50+ (if pub "pub " "") 73.51+ "mod " mod ";")) 73.52+ 73.53+(defun rs-imports (&rest imports) 73.54+ "Generate a string of Rust 'use' statements." 73.55+ (cond 73.56+ ((consp imports) 73.57+ (mapcar (lambda (x) (apply #'rs-use (apply #'rs-mod-form x))) imports)) 73.58+ (t imports))) 73.59+ 73.60+(defmacro rs-extern-c-fn (name args &optional pub unsafe no-mangle &body body) 73.61+ "Generate a Rust extern 'C' fn." 73.62+ `(concatenate 73.63+ 'string 73.64+ ,(when no-mangle (format nil "#[no_mangle]~&")) 73.65+ ,(when pub "pub ") 73.66+ ,(when unsafe "unsafe ") 73.67+ "extern \"C\" fn " ,name "(" 73.68+ ,(cond 73.69+ ((consp args) (reduce (lambda (x y) (format nil "~A,~A" x y)) args)) 73.70+ (t args)) 73.71+ ")" "{" ,@body "}")) 73.72+ 73.73+(defun rs-obj-impl (obj) 73.74+ "Implement Objective for give OBJ." 73.75+ (format nil "impl Objective for ~A {};" obj)) 73.76+ 73.77+;; (defun rs-macroexpand-1 (form &optional env)) 73.78+ 73.79+;; (defun rs-macroexpand (env &rest body) 73.80+ 73.81+;;;
74.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 74.2+++ b/src/tests.lisp Sat Jun 03 22:48:46 2023 -0400 74.3@@ -0,0 +1,1 @@ 74.4+(in-package :demo)
75.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 75.2+++ b/src/tests/demo_test.c Sat Jun 03 22:48:46 2023 -0400 75.3@@ -0,0 +1,8 @@ 75.4+#include <stdio.h> 75.5+#include "demo.h" 75.6+ 75.7+int main() { 75.8+ Service *srv = service_from_string("weather"); 75.9+ printf!("%s\n",service_to_json_str(srv)); 75.10+ free_service(srv); 75.11+}
76.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 76.2+++ b/src/tests/demo_test.py Sat Jun 03 22:48:46 2023 -0400 76.3@@ -0,0 +1,1 @@ 76.4+from _demo import lib
77.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 77.2+++ b/src/tests/prime-test.lisp Sat Jun 03 22:48:46 2023 -0400 77.3@@ -0,0 +1,67 @@ 77.4+;; (defun is-prime(n) 77.5+;; (do ((num 2 (+ num 1))) 77.6+;; ((> num (/ n 2)) t) 77.7+;; (if (= 0 (mod n num)) 77.8+;; (return-from is-prime nil)))) 77.9+ 77.10+;; (defun kth-prime(k) 77.11+;; (do ((candidate 2 (+ candidate 1))) 77.12+;; ((< k 1) (- candidate 1)) 77.13+;; (when (is-prime candidate) 77.14+;; (decf k)))) 77.15+ 77.16+;; (time (kth-prime 10000)) 77.17+ 77.18+;; (declaim (inline is-prime)) 77.19+;; (defun is-prime (n) 77.20+;; (loop for num of-type fixnum from 3 to (isqrt n) by 2 77.21+;; when (zerop (mod n num)) 77.22+;; return nil 77.23+;; finally (return t))) 77.24+ 77.25+;; (defun kth-prime (k) 77.26+;; (declare (optimize (speed 3) (safety 0)) 77.27+;; (fixnum k)) 77.28+;; (if (zerop k) 77.29+;; 2 77.30+;; (loop for candidate of-type fixnum from 3 by 2 77.31+;; when (<= k 0) return (- candidate 2) 77.32+;; when (is-prime candidate) do (decf k)))) 77.33+ 77.34+;; (declaim 77.35+;; (optimize (speed 3) (safety 0)) 77.36+;; (inline is-prime)) 77.37+ 77.38+;; (defun is-prime(n) 77.39+;; (declare (fixnum n)) 77.40+;; (do ((num 2 (+ num 1))) 77.41+;; ((> num (floor n 2)) t) 77.42+;; (declare (fixnum num)) 77.43+;; (if (= 0 (mod n num)) 77.44+;; (return-from is-prime nil)))) 77.45+ 77.46+;; (defun kth-prime(k) 77.47+;; (declare (fixnum k)) 77.48+;; (do ((candidate 2 (+ candidate 1))) 77.49+;; ((< k 1) (- candidate 1)) 77.50+;; (declare (fixnum candidate)) 77.51+;; (when (is-prime candidate) 77.52+;; (decf k)))) 77.53+ 77.54+;; (time (kth-prime 10000)) 77.55+ 77.56+(declaim (inline is-prime)) 77.57+(defun is-prime (n) 77.58+ (loop for num of-type fixnum from 2 to (ash n -1) 77.59+ when (zerop (mod n num)) 77.60+ return nil 77.61+ finally (return t))) 77.62+ 77.63+(defun kth-prime (k) 77.64+ (declare (optimize (speed 3) (safety 0)) 77.65+ (fixnum k)) 77.66+ (loop for candidate of-type fixnum from 2 77.67+ when (<= k 0) return (1- candidate) 77.68+ when (is-prime candidate) do (decf k))) 77.69+ 77.70+(time (kth-prime 10000))
78.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 78.2+++ b/src/tk.lisp Sat Jun 03 22:48:46 2023 -0400 78.3@@ -0,0 +1,28 @@ 78.4+(in-package :demo) 78.5+ 78.6+(defun mkstr (&rest args) 78.7+ (with-output-to-string (s) 78.8+ (dolist (a args) (princ a s)))) 78.9+ 78.10+(defun symb (&rest args) 78.11+ (values (intern (apply #'mkstr args)))) 78.12+ 78.13+(defun random-id () 78.14+ (format NIL "~8,'0x-~8,'0x" (random #xFFFFFFFF) (get-universal-time))) 78.15+ 78.16+(defun scan-dir (dir filename callback) 78.17+ (dolist (path (directory (merge-pathnames (merge-pathnames filename "**/") dir))) 78.18+ (funcall callback path))) 78.19+ 78.20+(defun sbq-reader (stream sub-char numarg) 78.21+ "The anaphoric sharp-backquote reader: #`((,a1))" 78.22+ (declare (ignore sub-char)) 78.23+ (unless numarg (setq numarg 1)) 78.24+ `(lambda ,(loop for i from 1 to numarg 78.25+ collect (symb 'a i)) 78.26+ ,(funcall 78.27+ (get-macro-character #\`) stream nil))) 78.28+ 78.29+(eval-when (:load-toplevel) 78.30+ (set-dispatch-macro-character 78.31+ #\# #\` #'demo:sbq-reader))
79.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000 79.2+++ b/src/ui.lisp Sat Jun 03 22:48:46 2023 -0400 79.3@@ -0,0 +1,43 @@ 79.4+(in-package :demo) 79.5+ 79.6+(defparameter ui-server-port 8080) 79.7+(defparameter ui-server-host "0.0.0.0") 79.8+ 79.9+(defclass ui-element (clog-element) () 79.10+ (:documentation "UI Element Object.")) 79.11+ 79.12+(defgeneric create-ui-element (obj &key hidden class id mode) 79.13+ (:documentation "Create a new ui-element as a child of OBJ.")) 79.14+(defmethod create-ui-element ((obj clog:clog-obj) 79.15+ &key (class nil) 79.16+ (hidden nil) 79.17+ (id nil) 79.18+ (mode 'auto)) 79.19+ (let ((new (clog:create-div obj 79.20+ :class class 79.21+ :hidden hidden 79.22+ :id id 79.23+ :mode mode))) 79.24+ (clog:set-geometry new :width 200 :height 100) 79.25+ (change-class new 'ui-element))) 79.26+ 79.27+(defun on-new-window (body) 79.28+ "Handle new window event." 79.29+ (clog:debug-mode body) 79.30+ (let ((elt (clog:create-child body "<h1>foobar</h1>"))) 79.31+ (clog:set-on-click 79.32+ elt 79.33+ (lambda (o) 79.34+ (setf (clog:color elt) "green"))))) 79.35+ 79.36+(defun start-ui () 79.37+ "Start the UI." 79.38+ (clog:initialize #'on-new-window 79.39+ :extended-routing t 79.40+ :host ui-server-host 79.41+ :port ui-server-port) 79.42+ (clog:open-browser)) 79.43+ 79.44+(defun stop-ui () 79.45+ "Stop the UI." 79.46+ (clog:shutdown))
80.1--- a/tests.lisp Sat Jun 03 19:57:46 2023 -0400 80.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 80.3@@ -1,1 +0,0 @@ 80.4-(in-package :demo)
81.1--- a/tests/demo_test.c Sat Jun 03 19:57:46 2023 -0400 81.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 81.3@@ -1,8 +0,0 @@ 81.4-#include <stdio.h> 81.5-#include "demo.h" 81.6- 81.7-int main() { 81.8- Service *srv = service_from_string("weather"); 81.9- printf!("%s\n",service_to_json_str(srv)); 81.10- free_service(srv); 81.11-}
82.1--- a/tests/demo_test.py Sat Jun 03 19:57:46 2023 -0400 82.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 82.3@@ -1,1 +0,0 @@ 82.4-from _demo import lib
83.1--- a/tests/prime-test.lisp Sat Jun 03 19:57:46 2023 -0400 83.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 83.3@@ -1,67 +0,0 @@ 83.4-;; (defun is-prime(n) 83.5-;; (do ((num 2 (+ num 1))) 83.6-;; ((> num (/ n 2)) t) 83.7-;; (if (= 0 (mod n num)) 83.8-;; (return-from is-prime nil)))) 83.9- 83.10-;; (defun kth-prime(k) 83.11-;; (do ((candidate 2 (+ candidate 1))) 83.12-;; ((< k 1) (- candidate 1)) 83.13-;; (when (is-prime candidate) 83.14-;; (decf k)))) 83.15- 83.16-;; (time (kth-prime 10000)) 83.17- 83.18-;; (declaim (inline is-prime)) 83.19-;; (defun is-prime (n) 83.20-;; (loop for num of-type fixnum from 3 to (isqrt n) by 2 83.21-;; when (zerop (mod n num)) 83.22-;; return nil 83.23-;; finally (return t))) 83.24- 83.25-;; (defun kth-prime (k) 83.26-;; (declare (optimize (speed 3) (safety 0)) 83.27-;; (fixnum k)) 83.28-;; (if (zerop k) 83.29-;; 2 83.30-;; (loop for candidate of-type fixnum from 3 by 2 83.31-;; when (<= k 0) return (- candidate 2) 83.32-;; when (is-prime candidate) do (decf k)))) 83.33- 83.34-;; (declaim 83.35-;; (optimize (speed 3) (safety 0)) 83.36-;; (inline is-prime)) 83.37- 83.38-;; (defun is-prime(n) 83.39-;; (declare (fixnum n)) 83.40-;; (do ((num 2 (+ num 1))) 83.41-;; ((> num (floor n 2)) t) 83.42-;; (declare (fixnum num)) 83.43-;; (if (= 0 (mod n num)) 83.44-;; (return-from is-prime nil)))) 83.45- 83.46-;; (defun kth-prime(k) 83.47-;; (declare (fixnum k)) 83.48-;; (do ((candidate 2 (+ candidate 1))) 83.49-;; ((< k 1) (- candidate 1)) 83.50-;; (declare (fixnum candidate)) 83.51-;; (when (is-prime candidate) 83.52-;; (decf k)))) 83.53- 83.54-;; (time (kth-prime 10000)) 83.55- 83.56-(declaim (inline is-prime)) 83.57-(defun is-prime (n) 83.58- (loop for num of-type fixnum from 2 to (ash n -1) 83.59- when (zerop (mod n num)) 83.60- return nil 83.61- finally (return t))) 83.62- 83.63-(defun kth-prime (k) 83.64- (declare (optimize (speed 3) (safety 0)) 83.65- (fixnum k)) 83.66- (loop for candidate of-type fixnum from 2 83.67- when (<= k 0) return (1- candidate) 83.68- when (is-prime candidate) do (decf k))) 83.69- 83.70-(time (kth-prime 10000))
84.1--- a/tk.lisp Sat Jun 03 19:57:46 2023 -0400 84.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 84.3@@ -1,28 +0,0 @@ 84.4-(in-package :demo) 84.5- 84.6-(defun mkstr (&rest args) 84.7- (with-output-to-string (s) 84.8- (dolist (a args) (princ a s)))) 84.9- 84.10-(defun symb (&rest args) 84.11- (values (intern (apply #'mkstr args)))) 84.12- 84.13-(defun random-id () 84.14- (format NIL "~8,'0x-~8,'0x" (random #xFFFFFFFF) (get-universal-time))) 84.15- 84.16-(defun scan-dir (dir filename callback) 84.17- (dolist (path (directory (merge-pathnames (merge-pathnames filename "**/") dir))) 84.18- (funcall callback path))) 84.19- 84.20-(defun sbq-reader (stream sub-char numarg) 84.21- "The anaphoric sharp-backquote reader: #`((,a1))" 84.22- (declare (ignore sub-char)) 84.23- (unless numarg (setq numarg 1)) 84.24- `(lambda ,(loop for i from 1 to numarg 84.25- collect (symb 'a i)) 84.26- ,(funcall 84.27- (get-macro-character #\`) stream nil))) 84.28- 84.29-(eval-when (:load-toplevel) 84.30- (set-dispatch-macro-character 84.31- #\# #\` #'demo:sbq-reader))
86.1--- a/tools/deps.nu Sat Jun 03 19:57:46 2023 -0400 86.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 86.3@@ -1,13 +0,0 @@ 86.4- 86.5-pacman -Sy sbcl 86.6-curl -o /tmp/ql.lisp http://beta.quicklisp.org/quicklisp.lisp 86.7-sbcl --no-sysinit --no-userinit --load /tmp/ql.lisp \ 86.8- --eval '(quicklisp-quickstart:install :path "~/.quicklisp")' \ 86.9- --eval '(ql:add-to-init-file)' \ 86.10- --quit 86.11-sbcl --eval '(ql:quickload :quicklisp-slime-helper)' --quit 86.12-# (load (expand-file-name "~/.quicklisp/slime-helper.el")) 86.13-# (setq inferior-lisp-program "sbcl") 86.14-curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh 86.15-cargo install cbindgen --force 86.16-cargo install slint-lsp --git https://github.com/slint-ui/slint --force 86.17\ No newline at end of file
87.1--- a/tools/scripts/check.ros Sat Jun 03 19:57:46 2023 -0400 87.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 87.3@@ -1,17 +0,0 @@ 87.4-#!/bin/sh 87.5-#|-*- mode:lisp -*-|# 87.6-#| 87.7-exec ros -Q -- $0 "$@" 87.8-|# 87.9-(progn ;;init forms 87.10- (ros:ensure-asdf) 87.11- #+quicklisp(ql:quickload '() :silent t) 87.12- ) 87.13- 87.14-(defpackage :ros.script.scriptscheck.3892329806 87.15- (:use :cl)) 87.16-(in-package :ros.script.scriptscheck.3892329806) 87.17- 87.18-(defun main (&rest argv) 87.19- (declare (ignorable argv))) 87.20-;;; vim: set ft=lisp lisp:
88.1--- a/tools/scripts/db.ros Sat Jun 03 19:57:46 2023 -0400 88.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 88.3@@ -1,12 +0,0 @@ 88.4-#!/bin/sh 88.5-#|-*- mode:lisp -*-|# 88.6-#| 88.7-exec ros -Q -- $0 "$@" 88.8-|# 88.9-(progn ;;init forms 88.10- (ros:ensure-asdf) 88.11- #+quicklisp(ql:quickload '() :silent t)) 88.12- 88.13-(defun main (&rest argv) 88.14- (declare (ignorable argv)) 88.15- (format t "hello world"))
89.1--- a/tools/scripts/demo.ros Sat Jun 03 19:57:46 2023 -0400 89.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 89.3@@ -1,12 +0,0 @@ 89.4-#!/bin/sh 89.5-#|-*- mode:lisp -*-|# 89.6-#| 89.7-exec ros -Q -- $0 "$@" 89.8-|# 89.9-(progn ;;init forms 89.10- (ros:ensure-asdf) 89.11- #+quicklisp(ql:quickload '(demo) :silent t)) 89.12- 89.13-(defun main (&rest argv) 89.14- (declare (ignorable argv)) 89.15- (demo:main))
90.1--- a/tools/scripts/pack.ros Sat Jun 03 19:57:46 2023 -0400 90.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 90.3@@ -1,17 +0,0 @@ 90.4-#!/bin/sh 90.5-#|-*- mode:lisp -*-|# 90.6-#| 90.7-exec ros -Q -- $0 "$@" 90.8-|# 90.9-(progn ;;init forms 90.10- (ros:ensure-asdf) 90.11- #+quicklisp(ql:quickload '() :silent t) 90.12- ) 90.13- 90.14-(defpackage :ros.script.pack.3891893796 90.15- (:use :cl)) 90.16-(in-package :ros.script.pack.3891893796) 90.17- 90.18-(defun main (&rest argv) 90.19- (declare (ignorable argv))) 90.20-;;; vim: set ft=lisp lisp:
91.1--- a/tools/scripts/test.ros Sat Jun 03 19:57:46 2023 -0400 91.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 91.3@@ -1,14 +0,0 @@ 91.4-#!/bin/sh 91.5-#|-*- mode:lisp -*-|# 91.6-#| 91.7-exec ros -Q -- $0 "$@" 91.8-|# 91.9-(progn ;;init forms 91.10- (ros:ensure-asdf) 91.11- #+quicklisp(ql:quickload '() :silent t)) 91.12- 91.13-(defun main (&rest argv) 91.14- (declare (ignorable argv)) 91.15- (write-line "> cargo test") 91.16- (uiop:run-program "cargo test") 91.17- (write-line " tested rust crates"))
93.1--- a/ui.lisp Sat Jun 03 19:57:46 2023 -0400 93.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 93.3@@ -1,43 +0,0 @@ 93.4-(in-package :demo) 93.5- 93.6-(defparameter ui-server-port 8080) 93.7-(defparameter ui-server-host "0.0.0.0") 93.8- 93.9-(defclass ui-element (clog-element) () 93.10- (:documentation "UI Element Object.")) 93.11- 93.12-(defgeneric create-ui-element (obj &key hidden class id mode) 93.13- (:documentation "Create a new ui-element as a child of OBJ.")) 93.14-(defmethod create-ui-element ((obj clog:clog-obj) 93.15- &key (class nil) 93.16- (hidden nil) 93.17- (id nil) 93.18- (mode 'auto)) 93.19- (let ((new (clog:create-div obj 93.20- :class class 93.21- :hidden hidden 93.22- :id id 93.23- :mode mode))) 93.24- (clog:set-geometry new :width 200 :height 100) 93.25- (change-class new 'ui-element))) 93.26- 93.27-(defun on-new-window (body) 93.28- "Handle new window event." 93.29- (clog:debug-mode body) 93.30- (let ((elt (clog:create-child body "<h1>foobar</h1>"))) 93.31- (clog:set-on-click 93.32- elt 93.33- (lambda (o) 93.34- (setf (clog:color elt) "green"))))) 93.35- 93.36-(defun start-ui () 93.37- "Start the UI." 93.38- (clog:initialize #'on-new-window 93.39- :extended-routing t 93.40- :host ui-server-host 93.41- :port ui-server-port) 93.42- (clog:open-browser)) 93.43- 93.44-(defun stop-ui () 93.45- "Stop the UI." 93.46- (clog:shutdown))
94.1--- a/ui/Cargo.toml Sat Jun 03 19:57:46 2023 -0400 94.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 94.3@@ -1,22 +0,0 @@ 94.4-[package] 94.5-name = "ui" 94.6-version = "0.1.0" 94.7-edition = "2021" 94.8-build = "build.rs" 94.9-[lib] 94.10-path = "lib.rs" 94.11-crate-type = ["rlib","cdylib"] 94.12-[[bin]] 94.13-name = "demo-ui" 94.14-path = "main.rs" 94.15-[build-dependencies] 94.16-slint-build = "1.0.2" 94.17-[dependencies] 94.18-obj = {version = "0.1.0",path = "../obj"} 94.19-env_logger = "0.10.0" 94.20-log = "0.4.17" 94.21-slint = "1.0.2" 94.22-[target.'cfg(target_arch = "wasm32")'.dependencies] 94.23-wasm-bindgen = { version = "0.2" } 94.24-web-sys = { version = "0.3", features=["console"] } 94.25-console_error_panic_hook = "0.1.5"
95.1--- a/ui/build.rs Sat Jun 03 19:57:46 2023 -0400 95.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 95.3@@ -1,3 +0,0 @@ 95.4-fn main() { 95.5- slint_build::compile("ui.slint").unwrap(); 95.6-}
96.1--- a/ui/config.slint Sat Jun 03 19:57:46 2023 -0400 96.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 96.3@@ -1,3 +0,0 @@ 96.4-export global UiConfig { 96.5- in property<bool> widgets-disabled: false; 96.6-} 96.7\ No newline at end of file
97.1Binary file ui/img/ayo.jpeg has changed
98.1Binary file ui/img/treez.png has changed
99.1--- a/ui/index.html Sat Jun 03 19:57:46 2023 -0400 99.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 99.3@@ -1,9 +0,0 @@ 99.4-<html> 99.5- <body> 99.6- <canvas id="canvas">>/canvas> 99.7- <script type="module"> 99.8- import init from './pkg/ui.js'; 99.9- init(); 99.10- </script> 99.11- </body> 99.12-</html>
100.1--- a/ui/lib.rs Sat Jun 03 19:57:46 2023 -0400 100.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 100.3@@ -1,69 +0,0 @@ 100.4-#![deny(unsafe_code)] 100.5- 100.6-#[cfg(target_arch = "wasm32")] 100.7-use wasm_bindgen::prelude::*; 100.8- 100.9-slint::include_modules!(); 100.10- 100.11-use std::rc::Rc; 100.12- 100.13-use slint::{Model, StandardListViewItem, VecModel}; 100.14- 100.15-#[cfg_attr(target_arch = "wasm32", wasm_bindgen(start))] 100.16-pub fn run() { 100.17- // This provides better error messages in debug mode. 100.18- // It's disabled in release mode so it doesn't bloat up the file size. 100.19- #[cfg(all(debug_assertions, target_arch = "wasm32"))] 100.20- console_error_panic_hook::set_once(); 100.21- 100.22- let app = App::new().unwrap(); 100.23- 100.24- let row_data: Rc<VecModel<slint::ModelRc<StandardListViewItem>>> = Rc::new(VecModel::default()); 100.25- 100.26- for r in 1..101 { 100.27- let items = Rc::new(VecModel::default()); 100.28- 100.29- for c in 1..5 { 100.30- items.push(slint::format!("Item {r}.{c}").into()); 100.31- } 100.32- 100.33- row_data.push(items.into()); 100.34- } 100.35- 100.36- app.global::<TableViewPageAdapter>().set_row_data(row_data.clone().into()); 100.37- 100.38- app.global::<TableViewPageAdapter>().on_sort_ascending({ 100.39- let app_weak = app.as_weak(); 100.40- let row_data = row_data.clone(); 100.41- move |index| { 100.42- let row_data = row_data.clone(); 100.43- 100.44- let sort_model = Rc::new(row_data.sort_by(move |r_a, r_b| { 100.45- let c_a = r_a.row_data(index as usize).unwrap(); 100.46- let c_b = r_b.row_data(index as usize).unwrap(); 100.47- 100.48- c_a.text.cmp(&c_b.text) 100.49- })); 100.50- 100.51- app_weak.unwrap().global::<TableViewPageAdapter>().set_row_data(sort_model.into()); 100.52- } 100.53- }); 100.54- 100.55- app.global::<TableViewPageAdapter>().on_sort_descending({ 100.56- let app_weak = app.as_weak(); 100.57- move |index| { 100.58- let row_data = row_data.clone(); 100.59- 100.60- let sort_model = Rc::new(row_data.sort_by(move |r_a, r_b| { 100.61- let c_a = r_a.row_data(index as usize).unwrap(); 100.62- let c_b = r_b.row_data(index as usize).unwrap(); 100.63- 100.64- c_b.text.cmp(&c_a.text) 100.65- })); 100.66- 100.67- app_weak.unwrap().global::<TableViewPageAdapter>().set_row_data(sort_model.into()); 100.68- } 100.69- }); 100.70- 100.71- app.run().unwrap(); 100.72-}
101.1--- a/ui/main.rs Sat Jun 03 19:57:46 2023 -0400 101.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 101.3@@ -1,4 +0,0 @@ 101.4-use ui::run; 101.5-fn main() { 101.6- run(); 101.7-}
102.1--- a/ui/pages.slint Sat Jun 03 19:57:46 2023 -0400 102.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 102.3@@ -1,7 +0,0 @@ 102.4-import { AboutPage } from "pages/about.slint"; 102.5-import { ControlsPage } from "pages/controls.slint"; 102.6-import { ListViewPage } from "pages/list_view.slint"; 102.7-import { TableViewPage, TableViewPageAdapter } from "pages/table_view.slint"; 102.8-import { TextEditPage } from "pages/text_edit.slint"; 102.9- 102.10-export { AboutPage, ControlsPage, ListViewPage, TextEditPage, TableViewPage, TableViewPageAdapter } 102.11\ No newline at end of file
103.1--- a/ui/pages/about.slint Sat Jun 03 19:57:46 2023 -0400 103.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 103.3@@ -1,10 +0,0 @@ 103.4-import { AboutSlint } from "std-widgets.slint"; 103.5-import { UiConfig } from "../config.slint"; 103.6-import { Page } from "page.slint"; 103.7- 103.8-export component AboutPage inherits Page { 103.9- title: "About"; 103.10- description: "Are you curious now? Check out the docs and gettings start from the Github repository and the website https://slint-ui.com and try it yourself."; 103.11- 103.12- AboutSlint {} 103.13-} 103.14\ No newline at end of file
104.1--- a/ui/pages/controls.slint Sat Jun 03 19:57:46 2023 -0400 104.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 104.3@@ -1,145 +0,0 @@ 104.4-import { Button, GroupBox, SpinBox, ComboBox, CheckBox, LineEdit, TabWidget, VerticalBox, HorizontalBox, 104.5- Slider, SpinBox } from "std-widgets.slint"; 104.6-import { UiConfig } from "../config.slint"; 104.7-import { Page } from "page.slint"; 104.8- 104.9-export component ControlsPage inherits Page { 104.10- title: "Controls"; 104.11- description: "This page gives an overview of the default widget set provided by Slint. The widgets are available in different styles native, fluent-(dark/light) and material-(dark/light). The widgets can be imported from \"std-widgets.slint\"."; 104.12- 104.13- GroupBox { 104.14- vertical-stretch: 0; 104.15- title: "Buttons"; 104.16- 104.17- HorizontalLayout { 104.18- spacing: 8px; 104.19- alignment: start; 104.20- 104.21- Button { 104.22- text: "Regular Button"; 104.23- enabled: !UiConfig.widgets-disabled; 104.24- } 104.25- 104.26- Button { 104.27- text: "Button with Icon"; 104.28- icon: @image-url("../img/treez.png"); 104.29- enabled: !UiConfig.widgets-disabled; 104.30- } 104.31- 104.32- Button { 104.33- checkable: true; 104.34- text: self.checked ? "ON" : "OFF"; 104.35- enabled: !UiConfig.widgets-disabled; 104.36- } 104.37- } 104.38- } 104.39- 104.40- GroupBox { 104.41- title: "CheckBox - SpinBox - ComboBox"; 104.42- vertical-stretch: 0; 104.43- 104.44- HorizontalBox { 104.45- alignment: start; 104.46- checkbox := CheckBox { 104.47- text: checkbox.checked ? "(checked)" : "(unchecked)"; 104.48- checked: true; 104.49- enabled: !UiConfig.widgets-disabled; 104.50- } 104.51- 104.52- 104.53- SpinBox { 104.54- vertical-stretch: 0; 104.55- value: 42; 104.56- enabled: !UiConfig.widgets-disabled; 104.57- } 104.58- 104.59- ComboBox { 104.60- model: ["Select Something", "From this", "Combobox"]; 104.61- enabled: !UiConfig.widgets-disabled; 104.62- } 104.63- } 104.64- 104.65- 104.66- } 104.67- 104.68- GroupBox { 104.69- title: "LineEdit"; 104.70- vertical-stretch: 0; 104.71- 104.72- LineEdit { 104.73- placeholder-text: "Enter some text"; 104.74- enabled: !UiConfig.widgets-disabled; 104.75- } 104.76- } 104.77- 104.78- GroupBox { 104.79- title: "Slider"; 104.80- vertical-stretch: 0; 104.81- 104.82- Slider { 104.83- min-width: 160px; 104.84- minimum: -100; 104.85- maximum: 100; 104.86- value: 42; 104.87- enabled: !UiConfig.widgets-disabled; 104.88- } 104.89- } 104.90- 104.91- GroupBox { 104.92- title: "TabWidget"; 104.93- 104.94- TabWidget { 104.95- Tab { 104.96- title: "Tab 1"; 104.97- 104.98- VerticalBox { 104.99- alignment: start; 104.100- 104.101- GroupBox { 104.102- title: "Content of tab 1"; 104.103- 104.104- HorizontalBox { 104.105- alignment: start; 104.106- 104.107- Button { 104.108- text: "Click me"; 104.109- enabled: !UiConfig.widgets-disabled; 104.110- } 104.111- } 104.112- } 104.113- } 104.114- } 104.115- 104.116- Tab { 104.117- title: "Tab 2"; 104.118- 104.119- VerticalBox { 104.120- alignment: start; 104.121- 104.122- GroupBox { 104.123- title: "Content of tab 2"; 104.124- 104.125- VerticalBox { 104.126- alignment: start; 104.127- 104.128- CheckBox { 104.129- text: "Check me"; 104.130- enabled: !UiConfig.widgets-disabled; 104.131- } 104.132- } 104.133- } 104.134- } 104.135- } 104.136- 104.137- Tab { 104.138- title: "Tab 3"; 104.139- 104.140- VerticalBox { 104.141- Text { 104.142- text: "Content of tab 3"; 104.143- } 104.144- } 104.145- } 104.146- } 104.147- } 104.148-} 104.149\ No newline at end of file
105.1--- a/ui/pages/list_view.slint Sat Jun 03 19:57:46 2023 -0400 105.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 105.3@@ -1,45 +0,0 @@ 105.4-import { HorizontalBox, VerticalBox, ListView, StandardListView, GroupBox } from "std-widgets.slint"; 105.5-import { UiConfig } from "../config.slint"; 105.6-import { Page } from "page.slint"; 105.7- 105.8-export component ListViewPage inherits Page { 105.9- title: "ListView"; 105.10- description: "ListViews can be used to display a list of elements. The StandardListBox is like the default ListView just with a default text based definition of the visual items. Both can be imported from \"std-widgets.slint\""; 105.11- 105.12- HorizontalBox { 105.13- vertical-stretch: 1; 105.14- GroupBox { 105.15- title: "ListView"; 105.16- 105.17- ListView { 105.18- vertical-stretch: 0; 105.19- for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] : HorizontalBox { 105.20- Image { 105.21- width: 24px; 105.22- source: @image-url("../img/ayo.jpeg"); 105.23- } 105.24- Text { 105.25- text: "Item " + i; 105.26- } 105.27- } 105.28- } 105.29- } 105.30- 105.31- GroupBox { 105.32- title: "StandardListView"; 105.33- vertical-stretch: 0; 105.34- 105.35- StandardListView { 105.36- model: [ 105.37- {text: "Lorem"}, {text: "ipsum"},{text: "dolor"},{text: "sit"},{text: "amet"},{text: "consetetur"}, 105.38- {text: "Lorem"}, {text: "ipsum"},{text: "dolor"},{text: "sit"},{text: "amet"},{text: "consetetur"}, 105.39- {text: "Lorem"}, {text: "ipsum"},{text: "dolor"},{text: "sit"},{text: "amet"},{text: "consetetur"}, 105.40- {text: "Lorem"}, {text: "ipsum"},{text: "dolor"},{text: "sit"},{text: "amet"},{text: "consetetur"}, 105.41- {text: "Lorem"}, {text: "ipsum"},{text: "dolor"},{text: "sit"},{text: "amet"},{text: "consetetur"}, 105.42- {text: "Lorem"}, {text: "ipsum"},{text: "dolor"},{text: "sit"},{text: "amet"},{text: "consetetur"}, 105.43- {text: "Lorem"}, {text: "ipsum"},{text: "dolor"},{text: "sit"},{text: "amet"},{text: "consetetur"}, 105.44- ]; 105.45- } 105.46- } 105.47- } 105.48-} 105.49\ No newline at end of file
106.1--- a/ui/pages/page.slint Sat Jun 03 19:57:46 2023 -0400 106.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 106.3@@ -1,27 +0,0 @@ 106.4-import { CheckBox, GridBox, ListView, ScrollView, VerticalBox } from "std-widgets.slint"; 106.5- 106.6-import { UiConfig } from "../config.slint"; 106.7- 106.8-export component Page inherits VerticalBox { 106.9- in property<string> title: "title"; 106.10- in property<string> description: "description"; 106.11- 106.12- HorizontalLayout { 106.13- height: 24px; 106.14- Text { 106.15- font-size: 20px; 106.16- text <=> root.title; 106.17- } 106.18- 106.19- // Spacer 106.20- Rectangle {} 106.21- 106.22- CheckBox { 106.23- horizontal-stretch: 0; 106.24- text: "Disable widgets"; 106.25- checked <=> UiConfig.widgets-disabled; 106.26- } 106.27- } 106.28- 106.29- @children 106.30-} 106.31\ No newline at end of file
107.1--- a/ui/pages/table_view.slint Sat Jun 03 19:57:46 2023 -0400 107.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 107.3@@ -1,48 +0,0 @@ 107.4-import { HorizontalBox, VerticalBox, StandardTableView, GroupBox} from "std-widgets.slint"; 107.5-import { UiConfig } from "../config.slint"; 107.6-import { Page } from "page.slint"; 107.7- 107.8-export global TableViewPageAdapter { 107.9- callback sort_ascending(int); 107.10- callback sort_descending(int); 107.11- in property <[[StandardListViewItem]]> row_data: [ 107.12- [ { text: "Item 1.1" }, { text: "Item 1.2" }, { text: "Item 1.3" }, { text: "Item 1.4" }, ], 107.13- [ { text: "Item 2.1" }, { text: "Item 2.2" }, { text: "Item 2.3" }, { text: "Item 2.4" }, ], 107.14- [ { text: "Item 3.1" }, { text: "Item 3.2" }, { text: "Item 3.3" }, { text: "Item 3.4" }, ], 107.15- [ { text: "Item 4.1" }, { text: "Item 4.2" }, { text: "Item 4.3" }, { text: "Item 4.4" }, ], 107.16- [ { text: "Item 5.1" }, { text: "Item 5.2" }, { text: "Item 5.3" }, { text: "Item 5.4" }, ], 107.17- [ { text: "Item 6.1" }, { text: "Item 6.2" }, { text: "Item 6.3" }, { text: "Item 6.4" }, ], 107.18- ]; 107.19-} 107.20- 107.21-export component TableViewPage inherits Page { 107.22- title: "TableView"; 107.23- description: "StandardTableView can be used to display a list of text elements in columns and rows. It can be imported from \"std-widgets.slint\""; 107.24- 107.25- HorizontalBox { 107.26- vertical-stretch: 1; 107.27- 107.28- GroupBox { 107.29- title: "StandardTableView"; 107.30- vertical-stretch: 0; 107.31- 107.32- StandardTableView { 107.33- sort-ascending(index) => { 107.34- TableViewPageAdapter.sort_ascending(index); 107.35- } 107.36- 107.37- sort-descending(index) => { 107.38- TableViewPageAdapter.sort-descending(index); 107.39- } 107.40- 107.41- columns: [ 107.42- { title: "Header 1" }, 107.43- { title: "Header 2" }, 107.44- { title: "Header 3" }, 107.45- { title: "Header 4" }, 107.46- ]; 107.47- rows: TableViewPageAdapter.row_data; 107.48- } 107.49- } 107.50- } 107.51-} 107.52\ No newline at end of file
108.1--- a/ui/pages/text_edit.slint Sat Jun 03 19:57:46 2023 -0400 108.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 108.3@@ -1,32 +0,0 @@ 108.4-import { HorizontalBox, GroupBox, TextEdit } from "std-widgets.slint"; 108.5-import { UiConfig } from "../config.slint"; 108.6-import { Page } from "page.slint"; 108.7- 108.8-export component TextEditPage inherits Page { 108.9- title: "TextEdit"; 108.10- description: "Similar to LineEdit, but can be used to enter several lines of text. The widget can be imported from \"std-widgets.slint\"."; 108.11- 108.12- HorizontalBox { 108.13- GroupBox { 108.14- vertical-stretch: 0; 108.15- title: "Word-Wrap"; 108.16- te1 := TextEdit { 108.17- min-width: 200px; 108.18- text: "This is our TextEdit widget, which allows for editing text that spans over multiple paragraphs.\nFor example this line starts in a new paragraph.\n\nWhen the amount of lines - due to wrapping and number of paragraphs - exceeds the available vertical height, a vertical scrollbar is shown that allows scrolling.\nYou may want to enter a bit of text here then in order to make them visible."; 108.19- wrap: word-wrap; 108.20- enabled: !UiConfig.widgets-disabled; 108.21- } 108.22- } 108.23- 108.24- GroupBox { 108.25- title: "No-Wrap"; 108.26- vertical-stretch: 0; 108.27- te2 := TextEdit { 108.28- min-width: 200px; 108.29- text <=> te1.text; 108.30- wrap: no-wrap; 108.31- enabled: !UiConfig.widgets-disabled; 108.32- } 108.33- } 108.34- } 108.35-} 108.36\ No newline at end of file
109.1--- a/ui/sidebar.slint Sat Jun 03 19:57:46 2023 -0400 109.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 109.3@@ -1,127 +0,0 @@ 109.4-import { StyleMetrics } from "std-widgets.slint"; 109.5- 109.6-component SideBarItem inherits Rectangle { 109.7- callback clicked <=> touch.clicked; 109.8- in-out property<string> text <=> label.text; 109.9- in property<bool> selected; 109.10- in property<bool> has-focus; 109.11- 109.12- min-height: l.preferred-height; 109.13- 109.14- state := Rectangle { 109.15- opacity: 0; 109.16- background: StyleMetrics.window-background; 109.17- 109.18- animate opacity { duration: 150ms; } 109.19- } 109.20- 109.21- l := HorizontalLayout { 109.22- y: (parent.height - self.height) / 2; 109.23- padding: StyleMetrics.layout-padding; 109.24- spacing: 0px; 109.25- 109.26- label := Text { 109.27- color: StyleMetrics.default-text-color; 109.28- vertical-alignment: center; 109.29- } 109.30- } 109.31- 109.32- touch := TouchArea { 109.33- width: 100%; 109.34- height: 100%; 109.35- } 109.36- 109.37- states [ 109.38- pressed when touch.pressed : { 109.39- state.opacity: 0.8; 109.40- } 109.41- hover when touch.has-hover : { 109.42- state.opacity: 0.6; 109.43- } 109.44- selected when root.selected : { 109.45- state.opacity: 1; 109.46- } 109.47- focused when root.has-focus : { 109.48- state.opacity: 0.8; 109.49- } 109.50- ] 109.51-} 109.52- 109.53-export component SideBar inherits Rectangle { 109.54- in property<[string]> model: []; 109.55- out property<int> current-item: 0; 109.56- in property<string> title <=> label.text; 109.57- out property<int> current-focused: fs.has-focus ? fs.focused-tab : -1; // The currently focused tab 109.58- width: 180px; 109.59- 109.60- forward-focus: fs; 109.61- 109.62- accessible-role: tab; 109.63- accessible-delegate-focus: root.current-focused >= 0 ? root.current-focused : root.current-item; 109.64- 109.65- Rectangle { 109.66- background: StyleMetrics.window-background.darker(0.2); 109.67- 109.68- fs := FocusScope { 109.69- x:0; 109.70- width: 0px; // Do not react on clicks 109.71- property<int> focused-tab: 0; 109.72- 109.73- key-pressed(event) => { 109.74- if (event.text == "\n") { 109.75- root.current-item = root.current-focused; 109.76- return accept; 109.77- } 109.78- if (event.text == Key.UpArrow) { 109.79- self.focused-tab = Math.max(self.focused-tab - 1, 0); 109.80- return accept; 109.81- } 109.82- if (event.text == Key.DownArrow) { 109.83- self.focused-tab = Math.min(self.focused-tab + 1, root.model.length - 1); 109.84- return accept; 109.85- } 109.86- return reject; 109.87- } 109.88- 109.89- key-released(event) => { 109.90- if (event.text == " ") { 109.91- root.current-item = root.current-focused; 109.92- return accept; 109.93- } 109.94- return reject; 109.95- } 109.96- } 109.97- } 109.98- 109.99- VerticalLayout { 109.100- padding-top: StyleMetrics.layout-padding; 109.101- padding-bottom: StyleMetrics.layout-padding; 109.102- spacing: StyleMetrics.layout-spacing; 109.103- alignment: start; 109.104- 109.105- label := Text { 109.106- font-size: 16px; 109.107- horizontal-alignment: center; 109.108- } 109.109- 109.110- navigation := VerticalLayout { 109.111- alignment: start; 109.112- vertical-stretch: 0; 109.113- for item[index] in root.model : SideBarItem { 109.114- has-focus: index == root.current-focused; 109.115- text: item; 109.116- selected: index == root.current-item; 109.117- clicked => { root.current-item = index; } 109.118- } 109.119- } 109.120- 109.121- VerticalLayout { 109.122- bottom := VerticalLayout { 109.123- padding-left: StyleMetrics.layout-padding; 109.124- padding-right: StyleMetrics.layout-padding; 109.125- 109.126- @children 109.127- } 109.128- } 109.129- } 109.130-} 109.131\ No newline at end of file
110.1--- a/ui/ui.slint Sat Jun 03 19:57:46 2023 -0400 110.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 110.3@@ -1,20 +0,0 @@ 110.4-import {CheckBox, StandardListView, StyleMetrics} from "std-widgets.slint"; 110.5-import {AboutPage, ControlsPage, ListViewPage, TableViewPage, TableViewPageAdapter, TextEditPage} from "pages.slint"; 110.6-import {UiConfig} from "config.slint"; 110.7-import {SideBar} from "sidebar.slint"; 110.8-export {TableViewPageAdapter} 110.9-export component App inherits Window { 110.10- title: "Demo"; 110.11- icon: @image-url("img/treez.png"); 110.12- HorizontalLayout { 110.13- side-bar := SideBar { 110.14- title: "Demo"; 110.15- model: ["Controls", "ListView", "TableView", "TextEdit", "About"]; 110.16- } 110.17- if(side-bar.current-item == 0) : ControlsPage {} 110.18- if(side-bar.current-item == 1) : ListViewPage {} 110.19- if(side-bar.current-item == 2) : TableViewPage {} 110.20- if(side-bar.current-item == 3) : TextEditPage {} 110.21- if(side-bar.current-item == 4) : AboutPage {} 110.22- } 110.23-} 110.24\ No newline at end of file