1.1--- a/.gitlab-ci.yml Thu Jun 20 22:31:58 2024 -0400
1.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3@@ -1,32 +0,0 @@
1.4-image: fukamachi/sbcl
1.5-before_script:
1.6-- apt-get mercurial
1.7-- curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
1.8-- rustup default nightly
1.9-- hg clone https://lab.rwest.io/otom8/demo ~/quicklisp/local-projects/demo
1.10-stages:
1.11- - build
1.12- - test
1.13- - deploy
1.14-build-job:
1.15- stage: build
1.16- script:
1.17- - echo "Compiling the code..."
1.18- - make build
1.19- - echo "Compile complete."
1.20-unit-test-job:
1.21- stage: test
1.22- script:
1.23- - echo "Running unit tests..."
1.24- - make test
1.25-lint-test-job:
1.26- stage: test
1.27- script:
1.28- - echo "Linting code..."
1.29- - make fmt
1.30- - echo "No lint issues found."
1.31-deploy-job:
1.32- stage: deploy
1.33- script:
1.34- - echo "Deploying application..."
1.35- - echo "Application successfully deployed."
1.36\ No newline at end of file
2.1--- a/Cargo.toml Thu Jun 20 22:31:58 2024 -0400
2.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2.3@@ -1,2 +0,0 @@
2.4-[workspace]
2.5-members = ["src/crates/obj","src/crates/ui","src/crates/service"]
3.1--- a/Containerfile Thu Jun 20 22:31:58 2024 -0400
3.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
3.3@@ -1,10 +0,0 @@
3.4-FROM clfoundation/sbcl:latest
3.5-ENV QUICKLISP_ADD_TO_INIT_FILE=true
3.6-ENV QUICKLISP_DIST_VERSION=latest
3.7-ENV LISP=sbcl
3.8-WORKDIR /usr/src/demo
3.9-COPY . .
3.10-RUN mkdir -p ~/.config/common-lisp/source-registry.conf.d && \
3.11- echo '(:tree "/usr/src/demo")' > ~/.config/common-lisp/source-registry.conf.d/workspace.conf && \
3.12- /usr/local/bin/install-quicklisp
3.13-CMD [ "make", "ci" ]
3.14\ No newline at end of file
4.1--- a/demo.asd Thu Jun 20 22:31:58 2024 -0400
4.2+++ b/demo.asd Sun Jul 28 21:18:52 2024 -0400
4.3@@ -1,40 +1,15 @@
4.4 ;;; demo.asd
4.5 (defsystem "demo"
4.6 :version "0.1.0"
4.7- :author "ellis <ellis@rwest.io>"
4.8- :maintainer "ellis <ellis@rwest.io>"
4.9+ :author "Richard Westhaver <richard.westhaver@gmail.com>"
4.10+ :maintainer "Richard Westhaver <richard.westhaver@gmail.com>"
4.11 :description "comp demo system"
4.12 :homepage "https://rwest.io/demo"
4.13- :bug-tracker "https://lab.rwest.io/otom8/demo/issues"
4.14- :source-control (:hg "https://lab.rwest.io/otom8/demo")
4.15+ :bug-tracker "https://vc.compiler.ocmpany/demo/issues"
4.16+ :source-control (:hg "https://vc.compiler.company/demo")
4.17 :license "WTF"
4.18- :depends-on (:sxp :log4cl :bordeaux-threads :clog)
4.19- :in-order-to ((test-op (test-op "demo/tests")))
4.20- :components ((:file "src/package")
4.21- (:file "src/cfg")))
4.22+ :depends-on (:user)
4.23+ :components ((:file "pkg")))
4.24
4.25 (defmethod perform :after ((op load-op) (c (eql (find-system :demo))))
4.26 (pushnew :demo *features*))
4.27-
4.28-(defsystem "demo/cli"
4.29- :depends-on ("demo" "clingon")
4.30- :components ((:module "src/cli"
4.31- :components ((:file "cli"))))
4.32- :in-order-to ((test-op (test-op "demo/tests")))
4.33- :build-operation "program-op"
4.34- :build-pathname "bin/demo")
4.35-
4.36-(defsystem "demo/tests"
4.37- :depends-on ("demo" "demo-cli" "fiveam")
4.38- :components ((:module "src/tests"
4.39- :serial t
4.40- :components
4.41- ((:file "package")
4.42- (:file "utils")
4.43- (:module "clients"
4.44- :serial t
4.45- :components
4.46- ((:file "cli")
4.47- (:file "web"))))))
4.48- :perform (test-op (op component)
4.49- (uiop:symbol-call '#:demo-tests '#:run-tests)))
5.1--- a/makefile Thu Jun 20 22:31:58 2024 -0400
5.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
5.3@@ -1,23 +0,0 @@
5.4-# otom8/demo makefile
5.5-MODE?=release
5.6-LISP?=sbcl
5.7-CFG?=default.cfg
5.8-L_C=$(L) --no-userinit
5.9-L_D=$(L) --load demo.asd --eval '(ql:quickload "demo")'
5.10-L_S=$(L) --script
5.11-ARCH?=
5.12-A_C=ifeq ($(ARCH),x86_64) A_C=arch -$(ARCH) endif
5.13-.PHONY:build
5.14-RS:Cargo.toml rustfmt.toml src/crates/*
5.15-CL:*/*.asd */*.lisp
5.16-deps:;
5.17-clean:;rm -rf **/*.fasl;cargo clean
5.18-fmt:$(RS);cargo fmt
5.19-build:$(RS) $(CL);cargo build --$(MODE);$(L_D)
5.20- --eval '(asdf:make "demo")' \
5.21- --eval '(quit)'
5.22-docs:$(RS);cargo doc
5.23-test:$(RS) $(CL);cargo test;$(L_D) --eval '(asdf:test "demo")' --eval '(quit)'
5.24-#pack:;scripts/pack.ros
5.25-#check:;scripts/check.ros
5.26-ci:clean fmt build docs test;
6.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2+++ b/pkg.lisp Sun Jul 28 21:18:52 2024 -0400
6.3@@ -0,0 +1,9 @@
6.4+;; demo packages.lisp
6.5+(defpackage :demo-int
6.6+ (:use :cl :std))
6.7+
6.8+(defpackage :demo
6.9+ (:use #:cl #:demo-int))
6.10+
6.11+(std:defpkg :demo-user
6.12+ (:use-reexport :demo))
7.1--- a/run.lisp Thu Jun 20 22:31:58 2024 -0400
7.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
7.3@@ -1,2 +0,0 @@
7.4-(defparameter *cwd* (asdf:system-source-directory :demo))
7.5-(load (merge-pathnames "tools/build-image.lisp" *cwd*))
8.1--- a/rustfmt.toml Thu Jun 20 22:31:58 2024 -0400
8.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
8.3@@ -1,3 +0,0 @@
8.4-edition = "2021"
8.5-tab_spaces = 2
8.6-wrap_comments = true
8.7\ No newline at end of file
9.1--- a/skelfile Thu Jun 20 22:31:58 2024 -0400
9.2+++ b/skelfile Sun Jul 28 21:18:52 2024 -0400
9.3@@ -1,4 +1,4 @@
9.4-;;; demo/skelfile --- Demo Skeleton
9.5+;;; demo/skelfile --- Demo Skelfile
9.6 :name demo
9.7 :author "Richard Westhaver <richard.westhaver@gmail.com>"
9.8 :version "0.1.0"
11.1--- a/src/cli/cli.lisp Thu Jun 20 22:31:58 2024 -0400
11.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
11.3@@ -1,45 +0,0 @@
11.4-;; cli.lisp
11.5-(in-package :demo-cli)
11.6-
11.7-(defparameter demo-path (merge-pathnames "demo" (uiop:temporary-directory)))
11.8-
11.9-(defvar db-path (merge-pathnames "db" demo-path))
11.10-
11.11-(defun cli-opts ()
11.12- "Returns the top-level CLI options."
11.13- (list
11.14- (clingon:make-option
11.15- :string
11.16- :description "demo app to run"
11.17- :short-name #\x
11.18- :long-name "app"
11.19- :initial-value "client"
11.20- :env-vars '("DEMO_APP")
11.21- :key :app)
11.22- (clingon:make-option
11.23- :string
11.24- :description "path to config"
11.25- :short-name #\c
11.26- :long-name "config"
11.27- :initial-value "$DEMO_PATH/.fig"
11.28- :env-vars '("DEMO_CONFIG"))))
11.29-
11.30-(defun cli-handler (cmd)
11.31- "Handler for the `demo' command."
11.32- (let ((app (clingon:getopt cmd :app)))
11.33- (format t "running: ~A!~%" app)))
11.34-
11.35-(defun cli-cmd ()
11.36- "Our demo command."
11.37- (clingon:make-command
11.38- :name "demo"
11.39- :description "A collection of demos"
11.40- :version "1.0.0"
11.41- :authors '("ellis <ellis@rwest.io>")
11.42- :license "WTFPL"
11.43- :options (cli-opts)
11.44- :handler #'cli-handler))
11.45-
11.46-(defun run-cli ()
11.47- "A demo of some common-lisp functionality."
11.48- (clingon:run (cli-cmd)))
12.1--- a/src/cli/package.lisp Thu Jun 20 22:31:58 2024 -0400
12.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
12.3@@ -1,9 +0,0 @@
12.4-(defpackage :demo-cli
12.5- (:use :demo)
12.6- (:export
12.7- #:run-cli
12.8- #:demo-path
12.9- #:db-path
12.10- #:cli-opts
12.11- #:cli-handler
12.12- #:cli-cmd))
13.1--- a/src/crates/obj/Cargo.toml Thu Jun 20 22:31:58 2024 -0400
13.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
13.3@@ -1,27 +0,0 @@
13.4-[package]
13.5-name = "obj"
13.6-version = "0.1.0"
13.7-edition = "2021"
13.8-[features]
13.9-oauth = ["yup-oauth2"]
13.10-
13.11-[dependencies]
13.12-ron = "0.7.0"
13.13-bincode = "1.3.3"
13.14-serde_json = "1.0.68"
13.15-serde = { version = "1.0.130", features = ["derive"] }
13.16-chrono = { version = "0.4.19", features = ["serde"] }
13.17-mime = "0.3.16"
13.18-regex = "1.5.4"
13.19-rusty_ulid = "0.11.0"
13.20-uuid = { version = "0.8", features = ["serde"] }
13.21-yup-oauth2 = { version = "5.1.0", optional = true }
13.22-blake3 = "1.0.0"
13.23-hashbrown = "0.11.2"
13.24-rand = "0.8.0"
13.25-sha2 = "0.9.5"
13.26-hex = "0.4.3"
13.27-ulid = "1.0.0"
13.28-
13.29-[target.'cfg(target_arch = "wasm32")'.dependencies]
13.30-uuid = { version = "0.8", features = ["wasm-bindgen"] }
14.1--- a/src/crates/obj/proc_macros/Cargo.toml Thu Jun 20 22:31:58 2024 -0400
14.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
14.3@@ -1,10 +0,0 @@
14.4-[package]
14.5-name = "proc_macros"
14.6-version = "0.1.0"
14.7-edition = "2021"
14.8-[lib]
14.9-proc-macro = true
14.10-[dependencies]
14.11-quote = "1.0"
14.12-proc-macro2 = "1.0"
14.13-syn = "1.0"
14.14\ No newline at end of file
15.1--- a/src/crates/obj/proc_macros/src/derive.rs Thu Jun 20 22:31:58 2024 -0400
15.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
15.3@@ -1,5 +0,0 @@
15.4-mod derive;
15.5-use proc_macro::TokenStream;
15.6-pub fn derive_static_type(input: TokenStream) -> TokenStream {
15.7- derive::derive_static_type(input)
15.8-}
16.1--- a/src/crates/obj/proc_macros/src/lib.rs Thu Jun 20 22:31:58 2024 -0400
16.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
16.3@@ -1,1 +0,0 @@
16.4-
17.1--- a/src/crates/obj/src/auth.rs Thu Jun 20 22:31:58 2024 -0400
17.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
17.3@@ -1,72 +0,0 @@
17.4-//! Auth Configs
17.5-use serde::{Deserialize, Serialize};
17.6-
17.7-#[cfg(feature = "oauth")]
17.8-use yup_oauth2::ApplicationSecret;
17.9-
17.10-#[derive(Serialize, Deserialize, Debug, Default, Hash)]
17.11-pub struct AuthConfig {
17.12- pub provider: String,
17.13- #[cfg(feature = "oauth")]
17.14- pub oauth: Option<Oauth2Config>,
17.15- pub ssh: Option<SshConfig>,
17.16- pub pw: Option<PasswordConfig>,
17.17-}
17.18-
17.19-#[derive(Serialize, Deserialize, Default, Debug, Hash)]
17.20-pub struct PasswordConfig(String, String);
17.21-
17.22-#[cfg(feature = "oauth")]
17.23-#[derive(Serialize, Deserialize, Hash, Debug, PartialEq, Clone, Default)]
17.24-pub struct Oauth2Config {
17.25- pub client_id: String,
17.26- pub client_secret: String,
17.27- pub redirect_uris: Vec<String>,
17.28- pub auth_uri: String,
17.29- pub token_uri: String,
17.30- pub project_id: Option<String>, //for apptoken
17.31- pub client_email: Option<String>,
17.32- /// The URL of the public x509 certificate, used to verify the signature on
17.33- /// JWTs, such as ID tokens, signed by the authentication provider.
17.34- pub auth_provider_x509_cert_url: Option<String>,
17.35- /// The URL of the public x509 certificate, used to verify JWTs signed by the
17.36- /// client.
17.37- pub client_x509_cert_url: Option<String>,
17.38-}
17.39-
17.40-#[cfg(feature = "oauth")]
17.41-impl From<ApplicationSecret> for Oauth2Config {
17.42- fn from(shh: ApplicationSecret) -> Self {
17.43- Oauth2Config {
17.44- client_id: shh.client_id,
17.45- client_secret: shh.client_secret,
17.46- redirect_uris: shh.redirect_uris,
17.47- auth_uri: shh.auth_uri,
17.48- token_uri: shh.token_uri,
17.49- project_id: shh.project_id,
17.50- client_email: shh.client_email,
17.51- auth_provider_x509_cert_url: shh.auth_provider_x509_cert_url,
17.52- client_x509_cert_url: shh.client_x509_cert_url,
17.53- }
17.54- }
17.55-}
17.56-
17.57-#[cfg(feature = "oauth")]
17.58-impl From<Oauth2Config> for ApplicationSecret {
17.59- fn from(cfg: Oauth2Config) -> Self {
17.60- ApplicationSecret {
17.61- client_id: cfg.client_id,
17.62- client_secret: cfg.client_secret,
17.63- redirect_uris: cfg.redirect_uris,
17.64- auth_uri: cfg.auth_uri,
17.65- token_uri: cfg.token_uri,
17.66- project_id: cfg.project_id,
17.67- client_email: cfg.client_email,
17.68- auth_provider_x509_cert_url: cfg.auth_provider_x509_cert_url,
17.69- client_x509_cert_url: cfg.client_x509_cert_url,
17.70- }
17.71- }
17.72-}
17.73-
17.74-#[derive(Serialize, Deserialize, Hash, Debug, PartialEq, Clone, Default)]
17.75-pub struct SshConfig {}
18.1--- a/src/crates/obj/src/cfg.rs Thu Jun 20 22:31:58 2024 -0400
18.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
18.3@@ -1,51 +0,0 @@
18.4-/// common trait for all config modules. This trait provides functions
18.5-/// for de/serializing to/from RON, updating fields, and formatting.
18.6-use serde::{Serialize, Deserialize};
18.7-use crate::Objective;
18.8-use std::collections::HashMap as M;
18.9-use std::path::PathBuf;
18.10-use std::string::String as S;
18.11-use std::error::Error as E;
18.12-use std::boxed::Box as B;
18.13-type R<X> = std::result::Result<X,B<dyn E>>;
18.14-
18.15-pub trait Configure: Objective {
18.16- fn update(&self) -> R<()> {
18.17- Ok(())
18.18- }
18.19-}
18.20-
18.21-#[derive(Serialize, Deserialize, Debug, Default)]
18.22-pub struct ShellConfig {
18.23- pub env: M<S,S>,
18.24- pub cmds: M<S,S>,
18.25- pub shell: ShellType,
18.26-}
18.27-
18.28-impl Objective for ShellConfig {}
18.29-
18.30-#[derive(Serialize, Deserialize, Debug, Hash, Default)]
18.31-pub enum ShellType {
18.32- #[default]
18.33- Bash,
18.34- Zsh,
18.35- Sh,
18.36-}
18.37-
18.38-#[derive(Serialize, Deserialize, Debug, Default)]
18.39-pub enum EditorType {
18.40- #[default]
18.41- Emacs,
18.42- Vi,
18.43- Nano,
18.44-}
18.45-
18.46-#[derive(Serialize, Deserialize, Debug, Default)]
18.47-pub struct EditorConfig {
18.48- pub editor: EditorType,
18.49- pub cmds: M<S,S>,
18.50- pub init_file: PathBuf,
18.51-}
18.52-
18.53-#[cfg(test)]
18.54-mod tests;
19.1--- a/src/crates/obj/src/database.rs Thu Jun 20 22:31:58 2024 -0400
19.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
19.3@@ -1,18 +0,0 @@
19.4-//! cfg::config::database
19.5-//!
19.6-//! Database configuration primitives
19.7-use serde::{Deserialize, Serialize};
19.8-
19.9-#[derive(Serialize, Deserialize, Debug, Hash, PartialEq, Eq)]
19.10-pub struct DatabaseConfig {
19.11- engine: DatabaseType,
19.12- path: String,
19.13- cfs: Vec<String>,
19.14-}
19.15-
19.16-#[derive(Serialize, Deserialize, Debug, Hash, PartialEq, Eq)]
19.17-pub enum DatabaseType {
19.18- RocksDB,
19.19- Postgres,
19.20- Alch,
19.21-}
20.1--- a/src/crates/obj/src/err.rs Thu Jun 20 22:31:58 2024 -0400
20.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
20.3@@ -1,81 +0,0 @@
20.4-//! obj errors
20.5-use std::{fmt, io};
20.6-
20.7-/// obj Result wrapper
20.8-pub type Result<T> = std::result::Result<T, Error>;
20.9-
20.10-/// obj Error type
20.11-#[derive(Debug)]
20.12-pub enum Error {
20.13- Message(String),
20.14- Ron(ron::error::Error),
20.15- Json(serde_json::error::Error),
20.16- Io(io::Error),
20.17- Bincode(bincode::Error),
20.18- Utf8(std::string::FromUtf8Error),
20.19- Parse(std::string::ParseError),
20.20-}
20.21-
20.22-impl serde::ser::Error for Error {
20.23- fn custom<T: fmt::Display>(msg: T) -> Self {
20.24- Error::Message(msg.to_string())
20.25- }
20.26-}
20.27-
20.28-impl serde::de::Error for Error {
20.29- fn custom<T: fmt::Display>(msg: T) -> Self {
20.30- Error::Message(msg.to_string())
20.31- }
20.32-}
20.33-
20.34-impl fmt::Display for Error {
20.35- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
20.36- match self {
20.37- Error::Message(msg) => f.write_str(msg),
20.38- Error::Io(ref err) => write!(f, "obj IO error: {}", err),
20.39- Error::Ron(ref err) => write!(f, "obj Ron error: {}", err),
20.40- Error::Json(ref err) => write!(f, "obj Json error: {}", err),
20.41- Error::Bincode(ref err) => write!(f, "obj Bincode error: {}", err),
20.42- Error::Utf8(ref err) => write!(f, "obj Utf8 error: {}", err),
20.43- Error::Parse(ref err) => write!(f, "obj Parse error: {}", err),
20.44- }
20.45- }
20.46-}
20.47-
20.48-impl From<io::Error> for Error {
20.49- fn from(e: io::Error) -> Self {
20.50- Error::Io(e)
20.51- }
20.52-}
20.53-
20.54-impl From<std::string::ParseError> for Error {
20.55- fn from(e: std::string::ParseError) -> Self {
20.56- Error::Parse(e)
20.57- }
20.58-}
20.59-
20.60-impl From<std::string::FromUtf8Error> for Error {
20.61- fn from(err: std::string::FromUtf8Error) -> Self {
20.62- Error::Utf8(err)
20.63- }
20.64-}
20.65-
20.66-impl From<ron::Error> for Error {
20.67- fn from(e: ron::Error) -> Self {
20.68- Error::Ron(e)
20.69- }
20.70-}
20.71-
20.72-impl From<serde_json::Error> for Error {
20.73- fn from(e: serde_json::Error) -> Self {
20.74- Error::Json(e)
20.75- }
20.76-}
20.77-
20.78-impl From<bincode::Error> for Error {
20.79- fn from(e: bincode::Error) -> Self {
20.80- Error::Bincode(e)
20.81- }
20.82-}
20.83-
20.84-impl std::error::Error for Error {}
21.1--- a/src/crates/obj/src/hash.rs Thu Jun 20 22:31:58 2024 -0400
21.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
21.3@@ -1,51 +0,0 @@
21.4-//! hash - wrapper for hash algorithms and types
21.5-
21.6-pub use blake3::{derive_key, hash, keyed_hash, Hash as B3Hash, Hasher as B3Hasher, OutputReader};
21.7-pub use hex;
21.8-pub use sha2::Sha512;
21.9-
21.10-pub use std::hash::{Hash, Hasher};
21.11-
21.12-pub const KEY_LEN: usize = 32;
21.13-pub const OUT_LEN: usize = 32;
21.14-pub const OUT_LEN_HEX: usize = OUT_LEN * 2;
21.15-
21.16-#[cfg(test)]
21.17-mod tests {
21.18- use super::*;
21.19- use crate::*;
21.20- #[test]
21.21- fn id_state_hash() {
21.22- let id = id::Id(vec![0; KEY_LEN]);
21.23- let hash = id.state_hash(&mut B3Hasher::new());
21.24- assert_eq!(hash, id.state_hash(&mut B3Hasher::new()));
21.25- }
21.26-
21.27- #[test]
21.28- fn id_hex() {
21.29- let id = id::Id(vec![255; KEY_LEN]);
21.30-
21.31- assert_eq!(
21.32- hex::decode("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(),
21.33- id.0
21.34- );
21.35- }
21.36-
21.37- #[test]
21.38- fn rand_id() {
21.39- let id = id::Id::rand();
21.40- let hash = id.state_hash(&mut B3Hasher::new());
21.41- assert_eq!(hash, id.state_hash(&mut B3Hasher::new()));
21.42- }
21.43-
21.44- #[test]
21.45- fn random_demon_id_is_valid() {
21.46- use id::PeerId;
21.47- for _ in 0..5000 {
21.48- let did = PeerId::rand();
21.49- let did2 = PeerId::rand();
21.50- assert_eq!(did, did);
21.51- assert_ne!(did, did2);
21.52- }
21.53- }
21.54-}
22.1--- a/src/crates/obj/src/id.rs Thu Jun 20 22:31:58 2024 -0400
22.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
22.3@@ -1,120 +0,0 @@
22.4-use crate::hash::{B3Hasher, KEY_LEN, OUT_LEN};
22.5-use rand::Rng;
22.6-use serde::{Deserialize, Serialize};
22.7-use std::{fmt, str::FromStr};
22.8-pub use ulid::Ulid;
22.9-pub use uuid::Uuid;
22.10-/// a simple Id abstraction
22.11-#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Serialize, Deserialize, Hash)]
22.12-pub struct Id(pub Vec<u8>);
22.13-
22.14-impl Id {
22.15- pub fn rand() -> Self {
22.16- let mut rng = rand::thread_rng();
22.17- let vals: Vec<u8> = (0..KEY_LEN).map(|_| rng.gen_range(0..u8::MAX)).collect();
22.18- Id(vals)
22.19- }
22.20-
22.21- pub fn state_hash(&self, state: &mut B3Hasher) -> Self {
22.22- let mut output = vec![0; OUT_LEN];
22.23- state.update(&self.0);
22.24- let mut res = state.finalize_xof();
22.25- res.fill(&mut output);
22.26- Id(output)
22.27- }
22.28-
22.29- pub fn to_hex(&self) -> String {
22.30- hex::encode(&self.0)
22.31- }
22.32-}
22.33-
22.34-/// PeerId
22.35-///
22.36-/// identifies a unique Peer
22.37-#[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd, Debug)]
22.38-pub struct PeerId {
22.39- id: [u8; 32],
22.40-}
22.41-
22.42-impl PeerId {
22.43- pub fn new() -> Self {
22.44- Self::default()
22.45- }
22.46-
22.47- pub fn rand() -> Self {
22.48- let pd = rand::thread_rng().gen::<[u8; 32]>();
22.49- Self { id: pd }
22.50- }
22.51-
22.52- pub fn from_bytes(data: &[u8]) -> Self {
22.53- let pd = blake3::hash(data);
22.54- let hash = pd.as_bytes();
22.55- Self { id: *hash }
22.56- }
22.57-}
22.58-
22.59-impl Default for PeerId {
22.60- fn default() -> Self {
22.61- PeerId { id: [0; 32] }
22.62- }
22.63-}
22.64-
22.65-/// Identity trait
22.66-///
22.67-/// Defines Identity-related behaviors
22.68-pub trait Identity: Sized {
22.69- /// return the hashed bytes of an ObjectId
22.70- fn id(&self) -> Id;
22.71-}
22.72-
22.73-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
22.74-pub struct ObjectId(u128);
22.75-
22.76-pub struct NameSpace {
22.77- pub prefix: Option<String>,
22.78- pub capacity: u64,
22.79- pub route: Vec<Id>,
22.80- pub key: Option<Id>,
22.81-}
22.82-
22.83-pub struct Domain {
22.84- pub ns: NameSpace,
22.85- pub id: Id,
22.86-}
22.87-
22.88-impl From<Uuid> for ObjectId {
22.89- fn from(uuid: Uuid) -> Self {
22.90- ObjectId(uuid.as_u128())
22.91- }
22.92-}
22.93-
22.94-impl From<Ulid> for ObjectId {
22.95- fn from(ulid: Ulid) -> Self {
22.96- ObjectId(u128::from(ulid))
22.97- }
22.98-}
22.99-
22.100-impl From<u128> for ObjectId {
22.101- fn from(src: u128) -> Self {
22.102- ObjectId(src)
22.103- }
22.104-}
22.105-
22.106-impl FromStr for ObjectId {
22.107- type Err = ();
22.108- fn from_str(input: &str) -> std::result::Result<ObjectId, Self::Err> {
22.109- match input {
22.110- i => Ok(ObjectId(u128::from(Ulid::from_str(i).unwrap()))),
22.111- }
22.112- }
22.113-}
22.114-
22.115-impl fmt::Display for ObjectId {
22.116- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
22.117- match *self {
22.118- ObjectId(i) => {
22.119- write!(f, "{}", Ulid::from(i))
22.120- }
22.121- }
22.122- }
22.123-}
23.1--- a/src/crates/obj/src/lib.rs Thu Jun 20 22:31:58 2024 -0400
23.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
23.3@@ -1,148 +0,0 @@
23.4-//! obj/src/lib.rs --- Objective type library
23.5-#![feature(associated_type_bounds)]
23.6-mod err;
23.7-pub use err::{Error, Result};
23.8-mod types;
23.9-pub use types::*;
23.10-pub mod auth;
23.11-pub mod database;
23.12-pub mod hash;
23.13-pub mod id;
23.14-pub mod network;
23.15-pub use bincode;
23.16-pub use ron;
23.17-use ron::extensions::Extensions;
23.18-use serde::{de::DeserializeOwned, Deserialize, Serialize};
23.19-pub use serde_json;
23.20-use std::collections::{BTreeMap, HashMap};
23.21-use std::io;
23.22-
23.23-/// Objective trait
23.24-/// Define Object behaviors, implemented by Objects
23.25-pub trait Objective {
23.26- fn encode(&self) -> Result<Vec<u8>>
23.27- where
23.28- Self: Serialize,
23.29- {
23.30- Ok(bincode::serialize(self)?)
23.31- }
23.32-
23.33- fn encode_into<W>(&self, writer: W) -> Result<()>
23.34- where
23.35- W: io::Write,
23.36- Self: Serialize,
23.37- {
23.38- Ok(bincode::serialize_into(writer, self)?)
23.39- }
23.40-
23.41- fn decode<'a>(bytes: &'a [u8]) -> Result<Self>
23.42- where
23.43- Self: Deserialize<'a>,
23.44- {
23.45- Ok(bincode::deserialize(bytes)?)
23.46- }
23.47-
23.48- fn decode_from<R>(&self, rdr: R) -> Result<Self>
23.49- where
23.50- R: io::Read,
23.51- Self: DeserializeOwned,
23.52- {
23.53- Ok(bincode::deserialize_from(rdr)?)
23.54- }
23.55-
23.56- fn to_ron_writer<W>(&self, writer: W) -> Result<()>
23.57- where
23.58- W: io::Write,
23.59- Self: Serialize,
23.60- {
23.61- Ok(ron::ser::to_writer_pretty(
23.62- writer,
23.63- &self,
23.64- ron::ser::PrettyConfig::new()
23.65- .indentor(" ".to_owned())
23.66- .extensions(Extensions::all()),
23.67- )?)
23.68- }
23.69-
23.70- fn to_ron_string(&self) -> Result<String>
23.71- where
23.72- Self: Serialize,
23.73- {
23.74- Ok(ron::ser::to_string_pretty(
23.75- &self,
23.76- ron::ser::PrettyConfig::new().indentor(" ".to_owned()),
23.77- )?)
23.78- }
23.79-
23.80- fn from_ron_reader<R>(&self, mut rdr: R) -> Result<Self>
23.81- where
23.82- R: io::Read,
23.83- Self: DeserializeOwned,
23.84- {
23.85- let mut bytes = Vec::new();
23.86- rdr.read_to_end(&mut bytes)?;
23.87- Ok(ron::de::from_bytes(&bytes)?)
23.88- }
23.89-
23.90- fn from_ron_str<'a>(s: &'a str) -> Result<Self>
23.91- where
23.92- Self: Deserialize<'a>,
23.93- {
23.94- Ok(ron::de::from_bytes(s.as_bytes())?)
23.95- }
23.96-
23.97- fn to_json_writer<W>(&self, writer: W) -> Result<()>
23.98- where
23.99- W: io::Write,
23.100- Self: Serialize,
23.101- {
23.102- // let formatter = serde_json::ser::PrettyFormatter::with_indent(b" ");
23.103- Ok(serde_json::ser::to_writer_pretty(writer, &self)?)
23.104- }
23.105-
23.106- fn to_json_string(&self) -> Result<String>
23.107- where
23.108- Self: Serialize,
23.109- {
23.110- Ok(serde_json::ser::to_string_pretty(&self)?)
23.111- }
23.112-
23.113- fn from_json_reader<R>(&self, mut rdr: R) -> Result<Self>
23.114- where
23.115- R: io::Read,
23.116- Self: DeserializeOwned,
23.117- {
23.118- let mut bytes = Vec::new();
23.119- rdr.read_to_end(&mut bytes)?;
23.120- Ok(serde_json::de::from_slice(&bytes)?)
23.121- }
23.122-
23.123- fn from_json_str<'a>(s: &'a str) -> Result<Self>
23.124- where
23.125- Self: Deserialize<'a>,
23.126- {
23.127- Ok(serde_json::de::from_slice(s.as_bytes())?)
23.128- }
23.129-}
23.130-
23.131-impl<T> Objective for Vec<T> {}
23.132-impl<K, V> Objective for HashMap<K, V> {}
23.133-impl<K, V> Objective for BTreeMap<K, V> {}
23.134-impl Objective for std::path::PathBuf {}
23.135-impl Objective for std::path::Path {}
23.136-impl Objective for std::string::String {}
23.137-impl Objective for std::any::TypeId {}
23.138-impl Objective for u8 {}
23.139-impl Objective for u16 {}
23.140-impl Objective for u32 {}
23.141-impl Objective for u64 {}
23.142-impl Objective for u128 {}
23.143-impl Objective for i8 {}
23.144-impl Objective for i16 {}
23.145-impl Objective for i32 {}
23.146-impl Objective for i64 {}
23.147-impl Objective for i128 {}
23.148-impl Objective for isize {}
23.149-impl Objective for usize {}
23.150-impl Objective for f32 {}
23.151-impl Objective for f64 {}
24.1--- a/src/crates/obj/src/network.rs Thu Jun 20 22:31:58 2024 -0400
24.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
24.3@@ -1,59 +0,0 @@
24.4-//! cfg::config::network
24.5-//!
24.6-//! Network configuration primitives
24.7-use serde::{Deserialize, Serialize};
24.8-use std::{fmt, net::SocketAddr};
24.9-
24.10-/// Network configuration
24.11-#[derive(Serialize, Deserialize, Hash, Debug, PartialEq, Clone)]
24.12-pub struct NetworkConfig {
24.13- /// a socket to bind
24.14- pub socket: SocketAddr,
24.15- /// a proxy to forward packets from
24.16- pub proxy: Option<SocketAddr>,
24.17- /// tunnel to use
24.18- pub tunnel: Option<String>,
24.19- /// network engine to attach
24.20- pub engine: EngineType,
24.21- /// peers to register AOT
24.22- pub peers: Option<Vec<SocketAddr>>,
24.23-}
24.24-
24.25-impl Default for NetworkConfig {
24.26- fn default() -> Self {
24.27- NetworkConfig {
24.28- socket: "127.0.0.1:0".parse().unwrap(),
24.29- proxy: None,
24.30- tunnel: None,
24.31- engine: EngineType::default(),
24.32- peers: None,
24.33- }
24.34- }
24.35-}
24.36-
24.37-#[derive(Serialize, Deserialize, Hash, Debug, PartialEq, Clone)]
24.38-pub enum EngineType {
24.39- Quic,
24.40- Http,
24.41- Dns,
24.42- Ssh,
24.43- Uds,
24.44-}
24.45-
24.46-impl Default for EngineType {
24.47- fn default() -> Self {
24.48- Self::Http
24.49- }
24.50-}
24.51-
24.52-impl std::fmt::Display for EngineType {
24.53- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
24.54- match self {
24.55- EngineType::Quic => write!(f, "quic"),
24.56- EngineType::Http => write!(f, "http"),
24.57- EngineType::Dns => write!(f, "dns"),
24.58- EngineType::Ssh => write!(f, "ssh"),
24.59- EngineType::Uds => write!(f, "uds"),
24.60- }
24.61- }
24.62-}
25.1--- a/src/crates/obj/src/types.rs Thu Jun 20 22:31:58 2024 -0400
25.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
25.3@@ -1,70 +0,0 @@
25.4-//! obj/src/types.rs --- OBJ type descriptions used by our demo
25.5-use crate::{Deserialize, Objective, Result, Serialize};
25.6-use std::collections::HashMap;
25.7-
25.8-/// APPLICATION TYPES
25.9-#[derive(Serialize, Deserialize, Default)]
25.10-pub enum Service {
25.11- Weather,
25.12- Stocks,
25.13- Dynamic(Vec<Service>),
25.14- Custom(CustomService),
25.15- #[default]
25.16- Bench,
25.17-}
25.18-
25.19-impl Objective for Service {}
25.20-
25.21-impl From<&str> for Service {
25.22- fn from(value: &str) -> Self {
25.23- match value {
25.24- "weather" => Service::Weather,
25.25- "stocks" => Service::Stocks,
25.26- "bench" => Service::Bench,
25.27- s => {
25.28- if s.contains(",") {
25.29- let x = s.split(",");
25.30- Service::Dynamic(
25.31- x.map(|y| Service::Custom(y.into()))
25.32- .collect::<Vec<Service>>(),
25.33- )
25.34- } else {
25.35- Service::Custom(s.into())
25.36- }
25.37- }
25.38- }
25.39- }
25.40-}
25.41-
25.42-#[derive(Serialize, Deserialize, Default)]
25.43-pub struct CustomService {
25.44- name: String,
25.45- registry: HashMap<String, Vec<u8>>,
25.46-}
25.47-
25.48-impl Objective for CustomService {}
25.49-impl From<CustomService> for Service {
25.50- fn from(value: CustomService) -> Self {
25.51- Service::Custom(value)
25.52- }
25.53-}
25.54-impl From<&str> for CustomService {
25.55- fn from(value: &str) -> Self {
25.56- let name = value.to_owned();
25.57- let registry = HashMap::new();
25.58- CustomService { name, registry }
25.59- }
25.60-}
25.61-
25.62-#[derive(Serialize, Deserialize, Default)]
25.63-pub struct Complex<X: Objective> {
25.64- data: X,
25.65- stack: Vec<u8>,
25.66- registry: HashMap<String, Vec<u8>>,
25.67-}
25.68-
25.69-impl Objective for Complex<Service> {}
25.70-
25.71-pub fn generate_complex() -> Result<Complex<Service>> {
25.72- Ok(Complex::<Service>::from_json_str("hi")?)
25.73-}
26.1--- a/src/crates/service/Cargo.toml Thu Jun 20 22:31:58 2024 -0400
26.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
26.3@@ -1,21 +0,0 @@
26.4-[package]
26.5-name = "demo_service"
26.6-version = "0.1.0"
26.7-edition = "2021"
26.8-[lib]
26.9-path = "lib.rs"
26.10-[[bin]]
26.11-name = "demo-service"
26.12-path = "main.rs"
26.13-[[test]]
26.14-name = "tests"
26.15-path = "tests.rs"
26.16-
26.17-[dependencies]
26.18-obj = { version = "0.1.0", path = "../obj" }
26.19-tokio = { version = "1.28.2", features = ["full"] }
26.20-sqlx = { version = "0.6.3", features = ["runtime-tokio-rustls", "any", "postgres"] }
26.21-axum = { version = "0.6.18" }
26.22-tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
26.23-tracing = "0.1.37"
26.24-
27.1--- a/src/crates/service/lib.rs Thu Jun 20 22:31:58 2024 -0400
27.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
27.3@@ -1,1 +0,0 @@
27.4-
28.1--- a/src/crates/service/main.rs Thu Jun 20 22:31:58 2024 -0400
28.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
28.3@@ -1,17 +0,0 @@
28.4-
28.5-use tokio::net::TcpListener;
28.6-use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
28.7-
28.8-#[tokio::main]
28.9-async fn main() {
28.10- tracing_subscriber::registry()
28.11- .with(
28.12- tracing_subscriber::EnvFilter::try_from_default_env()
28.13- .unwrap_or_else(|_| "demo_service=debug".into()),
28.14- )
28.15- .with(tracing_subscriber::fmt::layer())
28.16- .init();
28.17-
28.18- let listener = TcpListener::bind("127.0.0.1:8888").await.unwrap();
28.19- tracing::debug!("listening on {}", listener.local_addr().unwrap());
28.20-}
29.1--- a/src/crates/service/tests.rs Thu Jun 20 22:31:58 2024 -0400
29.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
29.3@@ -1,1 +0,0 @@
29.4-
30.1--- a/src/crates/ui/Cargo.toml Thu Jun 20 22:31:58 2024 -0400
30.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
30.3@@ -1,22 +0,0 @@
30.4-[package]
30.5-name = "ui"
30.6-version = "0.1.0"
30.7-edition = "2021"
30.8-build = "build.rs"
30.9-[lib]
30.10-path = "lib.rs"
30.11-crate-type = ["rlib","cdylib"]
30.12-[[bin]]
30.13-name = "demo-ui"
30.14-path = "main.rs"
30.15-[build-dependencies]
30.16-slint-build = "1.0.2"
30.17-[dependencies]
30.18-obj = {version = "0.1.0",path = "../obj"}
30.19-env_logger = "0.10.0"
30.20-log = "0.4.17"
30.21-slint = "1.0.2"
30.22-[target.'cfg(target_arch = "wasm32")'.dependencies]
30.23-wasm-bindgen = { version = "0.2" }
30.24-web-sys = { version = "0.3", features=["console"] }
30.25-console_error_panic_hook = "0.1.5"
31.1--- a/src/crates/ui/build.rs Thu Jun 20 22:31:58 2024 -0400
31.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
31.3@@ -1,3 +0,0 @@
31.4-fn main() {
31.5- slint_build::compile("ui.slint").unwrap();
31.6-}
32.1--- a/src/crates/ui/config.slint Thu Jun 20 22:31:58 2024 -0400
32.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
32.3@@ -1,3 +0,0 @@
32.4-export global UiConfig {
32.5- in property<bool> widgets-disabled: false;
32.6-}
32.7\ No newline at end of file
33.1Binary file src/crates/ui/img/ayo.jpeg has changed
34.1Binary file src/crates/ui/img/treez.png has changed
35.1--- a/src/crates/ui/index.html Thu Jun 20 22:31:58 2024 -0400
35.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
35.3@@ -1,9 +0,0 @@
35.4-<html>
35.5- <body>
35.6- <canvas id="canvas">>/canvas>
35.7- <script type="module">
35.8- import init from './pkg/ui.js';
35.9- init();
35.10- </script>
35.11- </body>
35.12-</html>
36.1--- a/src/crates/ui/lib.rs Thu Jun 20 22:31:58 2024 -0400
36.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
36.3@@ -1,77 +0,0 @@
36.4-#![deny(unsafe_code)]
36.5-
36.6-#[cfg(target_arch = "wasm32")]
36.7-use wasm_bindgen::prelude::*;
36.8-
36.9-slint::include_modules!();
36.10-
36.11-use std::rc::Rc;
36.12-
36.13-use slint::{Model, StandardListViewItem, VecModel};
36.14-
36.15-#[cfg_attr(target_arch = "wasm32", wasm_bindgen(start))]
36.16-pub fn run() {
36.17- // This provides better error messages in debug mode.
36.18- // It's disabled in release mode so it doesn't bloat up the file size.
36.19- #[cfg(all(debug_assertions, target_arch = "wasm32"))]
36.20- console_error_panic_hook::set_once();
36.21-
36.22- let app = App::new().unwrap();
36.23-
36.24- let row_data: Rc<VecModel<slint::ModelRc<StandardListViewItem>>> = Rc::new(VecModel::default());
36.25-
36.26- for r in 1..101 {
36.27- let items = Rc::new(VecModel::default());
36.28-
36.29- for c in 1..5 {
36.30- items.push(slint::format!("Item {r}.{c}").into());
36.31- }
36.32-
36.33- row_data.push(items.into());
36.34- }
36.35-
36.36- app
36.37- .global::<TableViewPageAdapter>()
36.38- .set_row_data(row_data.clone().into());
36.39-
36.40- app.global::<TableViewPageAdapter>().on_sort_ascending({
36.41- let app_weak = app.as_weak();
36.42- let row_data = row_data.clone();
36.43- move |index| {
36.44- let row_data = row_data.clone();
36.45-
36.46- let sort_model = Rc::new(row_data.sort_by(move |r_a, r_b| {
36.47- let c_a = r_a.row_data(index as usize).unwrap();
36.48- let c_b = r_b.row_data(index as usize).unwrap();
36.49-
36.50- c_a.text.cmp(&c_b.text)
36.51- }));
36.52-
36.53- app_weak
36.54- .unwrap()
36.55- .global::<TableViewPageAdapter>()
36.56- .set_row_data(sort_model.into());
36.57- }
36.58- });
36.59-
36.60- app.global::<TableViewPageAdapter>().on_sort_descending({
36.61- let app_weak = app.as_weak();
36.62- move |index| {
36.63- let row_data = row_data.clone();
36.64-
36.65- let sort_model = Rc::new(row_data.sort_by(move |r_a, r_b| {
36.66- let c_a = r_a.row_data(index as usize).unwrap();
36.67- let c_b = r_b.row_data(index as usize).unwrap();
36.68-
36.69- c_b.text.cmp(&c_a.text)
36.70- }));
36.71-
36.72- app_weak
36.73- .unwrap()
36.74- .global::<TableViewPageAdapter>()
36.75- .set_row_data(sort_model.into());
36.76- }
36.77- });
36.78-
36.79- app.run().unwrap();
36.80-}
37.1--- a/src/crates/ui/main.rs Thu Jun 20 22:31:58 2024 -0400
37.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
37.3@@ -1,4 +0,0 @@
37.4-use ui::run;
37.5-fn main() {
37.6- run();
37.7-}
38.1--- a/src/crates/ui/pages.slint Thu Jun 20 22:31:58 2024 -0400
38.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
38.3@@ -1,7 +0,0 @@
38.4-import { AboutPage } from "pages/about.slint";
38.5-import { ControlsPage } from "pages/controls.slint";
38.6-import { ListViewPage } from "pages/list_view.slint";
38.7-import { TableViewPage, TableViewPageAdapter } from "pages/table_view.slint";
38.8-import { TextEditPage } from "pages/text_edit.slint";
38.9-
38.10-export { AboutPage, ControlsPage, ListViewPage, TextEditPage, TableViewPage, TableViewPageAdapter }
38.11\ No newline at end of file
39.1--- a/src/crates/ui/pages/about.slint Thu Jun 20 22:31:58 2024 -0400
39.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
39.3@@ -1,10 +0,0 @@
39.4-import { AboutSlint } from "std-widgets.slint";
39.5-import { UiConfig } from "../config.slint";
39.6-import { Page } from "page.slint";
39.7-
39.8-export component AboutPage inherits Page {
39.9- title: "About";
39.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.";
39.11-
39.12- AboutSlint {}
39.13-}
39.14\ No newline at end of file
40.1--- a/src/crates/ui/pages/controls.slint Thu Jun 20 22:31:58 2024 -0400
40.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
40.3@@ -1,145 +0,0 @@
40.4-import { Button, GroupBox, SpinBox, ComboBox, CheckBox, LineEdit, TabWidget, VerticalBox, HorizontalBox,
40.5- Slider, SpinBox } from "std-widgets.slint";
40.6-import { UiConfig } from "../config.slint";
40.7-import { Page } from "page.slint";
40.8-
40.9-export component ControlsPage inherits Page {
40.10- title: "Controls";
40.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\".";
40.12-
40.13- GroupBox {
40.14- vertical-stretch: 0;
40.15- title: "Buttons";
40.16-
40.17- HorizontalLayout {
40.18- spacing: 8px;
40.19- alignment: start;
40.20-
40.21- Button {
40.22- text: "Regular Button";
40.23- enabled: !UiConfig.widgets-disabled;
40.24- }
40.25-
40.26- Button {
40.27- text: "Button with Icon";
40.28- icon: @image-url("../img/treez.png");
40.29- enabled: !UiConfig.widgets-disabled;
40.30- }
40.31-
40.32- Button {
40.33- checkable: true;
40.34- text: self.checked ? "ON" : "OFF";
40.35- enabled: !UiConfig.widgets-disabled;
40.36- }
40.37- }
40.38- }
40.39-
40.40- GroupBox {
40.41- title: "CheckBox - SpinBox - ComboBox";
40.42- vertical-stretch: 0;
40.43-
40.44- HorizontalBox {
40.45- alignment: start;
40.46- checkbox := CheckBox {
40.47- text: checkbox.checked ? "(checked)" : "(unchecked)";
40.48- checked: true;
40.49- enabled: !UiConfig.widgets-disabled;
40.50- }
40.51-
40.52-
40.53- SpinBox {
40.54- vertical-stretch: 0;
40.55- value: 42;
40.56- enabled: !UiConfig.widgets-disabled;
40.57- }
40.58-
40.59- ComboBox {
40.60- model: ["Select Something", "From this", "Combobox"];
40.61- enabled: !UiConfig.widgets-disabled;
40.62- }
40.63- }
40.64-
40.65-
40.66- }
40.67-
40.68- GroupBox {
40.69- title: "LineEdit";
40.70- vertical-stretch: 0;
40.71-
40.72- LineEdit {
40.73- placeholder-text: "Enter some text";
40.74- enabled: !UiConfig.widgets-disabled;
40.75- }
40.76- }
40.77-
40.78- GroupBox {
40.79- title: "Slider";
40.80- vertical-stretch: 0;
40.81-
40.82- Slider {
40.83- min-width: 160px;
40.84- minimum: -100;
40.85- maximum: 100;
40.86- value: 42;
40.87- enabled: !UiConfig.widgets-disabled;
40.88- }
40.89- }
40.90-
40.91- GroupBox {
40.92- title: "TabWidget";
40.93-
40.94- TabWidget {
40.95- Tab {
40.96- title: "Tab 1";
40.97-
40.98- VerticalBox {
40.99- alignment: start;
40.100-
40.101- GroupBox {
40.102- title: "Content of tab 1";
40.103-
40.104- HorizontalBox {
40.105- alignment: start;
40.106-
40.107- Button {
40.108- text: "Click me";
40.109- enabled: !UiConfig.widgets-disabled;
40.110- }
40.111- }
40.112- }
40.113- }
40.114- }
40.115-
40.116- Tab {
40.117- title: "Tab 2";
40.118-
40.119- VerticalBox {
40.120- alignment: start;
40.121-
40.122- GroupBox {
40.123- title: "Content of tab 2";
40.124-
40.125- VerticalBox {
40.126- alignment: start;
40.127-
40.128- CheckBox {
40.129- text: "Check me";
40.130- enabled: !UiConfig.widgets-disabled;
40.131- }
40.132- }
40.133- }
40.134- }
40.135- }
40.136-
40.137- Tab {
40.138- title: "Tab 3";
40.139-
40.140- VerticalBox {
40.141- Text {
40.142- text: "Content of tab 3";
40.143- }
40.144- }
40.145- }
40.146- }
40.147- }
40.148-}
40.149\ No newline at end of file
41.1--- a/src/crates/ui/pages/list_view.slint Thu Jun 20 22:31:58 2024 -0400
41.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
41.3@@ -1,45 +0,0 @@
41.4-import { HorizontalBox, VerticalBox, ListView, StandardListView, GroupBox } from "std-widgets.slint";
41.5-import { UiConfig } from "../config.slint";
41.6-import { Page } from "page.slint";
41.7-
41.8-export component ListViewPage inherits Page {
41.9- title: "ListView";
41.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\"";
41.11-
41.12- HorizontalBox {
41.13- vertical-stretch: 1;
41.14- GroupBox {
41.15- title: "ListView";
41.16-
41.17- ListView {
41.18- vertical-stretch: 0;
41.19- for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] : HorizontalBox {
41.20- Image {
41.21- width: 24px;
41.22- source: @image-url("../img/ayo.jpeg");
41.23- }
41.24- Text {
41.25- text: "Item " + i;
41.26- }
41.27- }
41.28- }
41.29- }
41.30-
41.31- GroupBox {
41.32- title: "StandardListView";
41.33- vertical-stretch: 0;
41.34-
41.35- StandardListView {
41.36- model: [
41.37- {text: "Lorem"}, {text: "ipsum"},{text: "dolor"},{text: "sit"},{text: "amet"},{text: "consetetur"},
41.38- {text: "Lorem"}, {text: "ipsum"},{text: "dolor"},{text: "sit"},{text: "amet"},{text: "consetetur"},
41.39- {text: "Lorem"}, {text: "ipsum"},{text: "dolor"},{text: "sit"},{text: "amet"},{text: "consetetur"},
41.40- {text: "Lorem"}, {text: "ipsum"},{text: "dolor"},{text: "sit"},{text: "amet"},{text: "consetetur"},
41.41- {text: "Lorem"}, {text: "ipsum"},{text: "dolor"},{text: "sit"},{text: "amet"},{text: "consetetur"},
41.42- {text: "Lorem"}, {text: "ipsum"},{text: "dolor"},{text: "sit"},{text: "amet"},{text: "consetetur"},
41.43- {text: "Lorem"}, {text: "ipsum"},{text: "dolor"},{text: "sit"},{text: "amet"},{text: "consetetur"},
41.44- ];
41.45- }
41.46- }
41.47- }
41.48-}
41.49\ No newline at end of file
42.1--- a/src/crates/ui/pages/page.slint Thu Jun 20 22:31:58 2024 -0400
42.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
42.3@@ -1,27 +0,0 @@
42.4-import { CheckBox, GridBox, ListView, ScrollView, VerticalBox } from "std-widgets.slint";
42.5-
42.6-import { UiConfig } from "../config.slint";
42.7-
42.8-export component Page inherits VerticalBox {
42.9- in property<string> title: "title";
42.10- in property<string> description: "description";
42.11-
42.12- HorizontalLayout {
42.13- height: 24px;
42.14- Text {
42.15- font-size: 20px;
42.16- text <=> root.title;
42.17- }
42.18-
42.19- // Spacer
42.20- Rectangle {}
42.21-
42.22- CheckBox {
42.23- horizontal-stretch: 0;
42.24- text: "Disable widgets";
42.25- checked <=> UiConfig.widgets-disabled;
42.26- }
42.27- }
42.28-
42.29- @children
42.30-}
42.31\ No newline at end of file
43.1--- a/src/crates/ui/pages/table_view.slint Thu Jun 20 22:31:58 2024 -0400
43.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
43.3@@ -1,48 +0,0 @@
43.4-import { HorizontalBox, VerticalBox, StandardTableView, GroupBox} from "std-widgets.slint";
43.5-import { UiConfig } from "../config.slint";
43.6-import { Page } from "page.slint";
43.7-
43.8-export global TableViewPageAdapter {
43.9- callback sort_ascending(int);
43.10- callback sort_descending(int);
43.11- in property <[[StandardListViewItem]]> row_data: [
43.12- [ { text: "Item 1.1" }, { text: "Item 1.2" }, { text: "Item 1.3" }, { text: "Item 1.4" }, ],
43.13- [ { text: "Item 2.1" }, { text: "Item 2.2" }, { text: "Item 2.3" }, { text: "Item 2.4" }, ],
43.14- [ { text: "Item 3.1" }, { text: "Item 3.2" }, { text: "Item 3.3" }, { text: "Item 3.4" }, ],
43.15- [ { text: "Item 4.1" }, { text: "Item 4.2" }, { text: "Item 4.3" }, { text: "Item 4.4" }, ],
43.16- [ { text: "Item 5.1" }, { text: "Item 5.2" }, { text: "Item 5.3" }, { text: "Item 5.4" }, ],
43.17- [ { text: "Item 6.1" }, { text: "Item 6.2" }, { text: "Item 6.3" }, { text: "Item 6.4" }, ],
43.18- ];
43.19-}
43.20-
43.21-export component TableViewPage inherits Page {
43.22- title: "TableView";
43.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\"";
43.24-
43.25- HorizontalBox {
43.26- vertical-stretch: 1;
43.27-
43.28- GroupBox {
43.29- title: "StandardTableView";
43.30- vertical-stretch: 0;
43.31-
43.32- StandardTableView {
43.33- sort-ascending(index) => {
43.34- TableViewPageAdapter.sort_ascending(index);
43.35- }
43.36-
43.37- sort-descending(index) => {
43.38- TableViewPageAdapter.sort-descending(index);
43.39- }
43.40-
43.41- columns: [
43.42- { title: "Header 1" },
43.43- { title: "Header 2" },
43.44- { title: "Header 3" },
43.45- { title: "Header 4" },
43.46- ];
43.47- rows: TableViewPageAdapter.row_data;
43.48- }
43.49- }
43.50- }
43.51-}
43.52\ No newline at end of file
44.1--- a/src/crates/ui/pages/text_edit.slint Thu Jun 20 22:31:58 2024 -0400
44.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
44.3@@ -1,32 +0,0 @@
44.4-import { HorizontalBox, GroupBox, TextEdit } from "std-widgets.slint";
44.5-import { UiConfig } from "../config.slint";
44.6-import { Page } from "page.slint";
44.7-
44.8-export component TextEditPage inherits Page {
44.9- title: "TextEdit";
44.10- description: "Similar to LineEdit, but can be used to enter several lines of text. The widget can be imported from \"std-widgets.slint\".";
44.11-
44.12- HorizontalBox {
44.13- GroupBox {
44.14- vertical-stretch: 0;
44.15- title: "Word-Wrap";
44.16- te1 := TextEdit {
44.17- min-width: 200px;
44.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.";
44.19- wrap: word-wrap;
44.20- enabled: !UiConfig.widgets-disabled;
44.21- }
44.22- }
44.23-
44.24- GroupBox {
44.25- title: "No-Wrap";
44.26- vertical-stretch: 0;
44.27- te2 := TextEdit {
44.28- min-width: 200px;
44.29- text <=> te1.text;
44.30- wrap: no-wrap;
44.31- enabled: !UiConfig.widgets-disabled;
44.32- }
44.33- }
44.34- }
44.35-}
44.36\ No newline at end of file
45.1--- a/src/crates/ui/sidebar.slint Thu Jun 20 22:31:58 2024 -0400
45.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
45.3@@ -1,127 +0,0 @@
45.4-import { StyleMetrics } from "std-widgets.slint";
45.5-
45.6-component SideBarItem inherits Rectangle {
45.7- callback clicked <=> touch.clicked;
45.8- in-out property<string> text <=> label.text;
45.9- in property<bool> selected;
45.10- in property<bool> has-focus;
45.11-
45.12- min-height: l.preferred-height;
45.13-
45.14- state := Rectangle {
45.15- opacity: 0;
45.16- background: StyleMetrics.window-background;
45.17-
45.18- animate opacity { duration: 150ms; }
45.19- }
45.20-
45.21- l := HorizontalLayout {
45.22- y: (parent.height - self.height) / 2;
45.23- padding: StyleMetrics.layout-padding;
45.24- spacing: 0px;
45.25-
45.26- label := Text {
45.27- color: StyleMetrics.default-text-color;
45.28- vertical-alignment: center;
45.29- }
45.30- }
45.31-
45.32- touch := TouchArea {
45.33- width: 100%;
45.34- height: 100%;
45.35- }
45.36-
45.37- states [
45.38- pressed when touch.pressed : {
45.39- state.opacity: 0.8;
45.40- }
45.41- hover when touch.has-hover : {
45.42- state.opacity: 0.6;
45.43- }
45.44- selected when root.selected : {
45.45- state.opacity: 1;
45.46- }
45.47- focused when root.has-focus : {
45.48- state.opacity: 0.8;
45.49- }
45.50- ]
45.51-}
45.52-
45.53-export component SideBar inherits Rectangle {
45.54- in property<[string]> model: [];
45.55- out property<int> current-item: 0;
45.56- in property<string> title <=> label.text;
45.57- out property<int> current-focused: fs.has-focus ? fs.focused-tab : -1; // The currently focused tab
45.58- width: 180px;
45.59-
45.60- forward-focus: fs;
45.61-
45.62- accessible-role: tab;
45.63- accessible-delegate-focus: root.current-focused >= 0 ? root.current-focused : root.current-item;
45.64-
45.65- Rectangle {
45.66- background: StyleMetrics.window-background.darker(0.2);
45.67-
45.68- fs := FocusScope {
45.69- x:0;
45.70- width: 0px; // Do not react on clicks
45.71- property<int> focused-tab: 0;
45.72-
45.73- key-pressed(event) => {
45.74- if (event.text == "\n") {
45.75- root.current-item = root.current-focused;
45.76- return accept;
45.77- }
45.78- if (event.text == Key.UpArrow) {
45.79- self.focused-tab = Math.max(self.focused-tab - 1, 0);
45.80- return accept;
45.81- }
45.82- if (event.text == Key.DownArrow) {
45.83- self.focused-tab = Math.min(self.focused-tab + 1, root.model.length - 1);
45.84- return accept;
45.85- }
45.86- return reject;
45.87- }
45.88-
45.89- key-released(event) => {
45.90- if (event.text == " ") {
45.91- root.current-item = root.current-focused;
45.92- return accept;
45.93- }
45.94- return reject;
45.95- }
45.96- }
45.97- }
45.98-
45.99- VerticalLayout {
45.100- padding-top: StyleMetrics.layout-padding;
45.101- padding-bottom: StyleMetrics.layout-padding;
45.102- spacing: StyleMetrics.layout-spacing;
45.103- alignment: start;
45.104-
45.105- label := Text {
45.106- font-size: 16px;
45.107- horizontal-alignment: center;
45.108- }
45.109-
45.110- navigation := VerticalLayout {
45.111- alignment: start;
45.112- vertical-stretch: 0;
45.113- for item[index] in root.model : SideBarItem {
45.114- has-focus: index == root.current-focused;
45.115- text: item;
45.116- selected: index == root.current-item;
45.117- clicked => { root.current-item = index; }
45.118- }
45.119- }
45.120-
45.121- VerticalLayout {
45.122- bottom := VerticalLayout {
45.123- padding-left: StyleMetrics.layout-padding;
45.124- padding-right: StyleMetrics.layout-padding;
45.125-
45.126- @children
45.127- }
45.128- }
45.129- }
45.130-}
45.131\ No newline at end of file
46.1--- a/src/crates/ui/ui.slint Thu Jun 20 22:31:58 2024 -0400
46.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
46.3@@ -1,20 +0,0 @@
46.4-import {CheckBox, StandardListView, StyleMetrics} from "std-widgets.slint";
46.5-import {AboutPage, ControlsPage, ListViewPage, TableViewPage, TableViewPageAdapter, TextEditPage} from "pages.slint";
46.6-import {UiConfig} from "config.slint";
46.7-import {SideBar} from "sidebar.slint";
46.8-export {TableViewPageAdapter}
46.9-export component App inherits Window {
46.10- title: "Demo";
46.11- icon: @image-url("img/treez.png");
46.12- HorizontalLayout {
46.13- side-bar := SideBar {
46.14- title: "Demo";
46.15- model: ["Controls", "ListView", "TableView", "TextEdit", "About"];
46.16- }
46.17- if(side-bar.current-item == 0) : ControlsPage {}
46.18- if(side-bar.current-item == 1) : ListViewPage {}
46.19- if(side-bar.current-item == 2) : TableViewPage {}
46.20- if(side-bar.current-item == 3) : TextEditPage {}
46.21- if(side-bar.current-item == 4) : AboutPage {}
46.22- }
46.23-}
46.24\ No newline at end of file
47.1--- a/src/db/db.lisp Thu Jun 20 22:31:58 2024 -0400
47.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
47.3@@ -1,1 +0,0 @@
47.4-(in-package :demo-db)
48.1--- a/src/package.lisp Thu Jun 20 22:31:58 2024 -0400
48.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
48.3@@ -1,36 +0,0 @@
48.4-;; demo packages.lisp
48.5-
48.6-(defpackage :demo-core
48.7- (:use :cl))
48.8-
48.9-(defpackage :demo-utils
48.10- (:use :demo-core)
48.11- (:export
48.12- #:source-dir
48.13- #:random-id
48.14- #:scan-dir
48.15- #:*cargo-target*
48.16- #:*rs-macros*
48.17- #:rs-defmacro
48.18- #:rs-macroexpand-1
48.19- #:rs-macroexpand))
48.20-
48.21-(defpackage :demo-db
48.22- (:use :demo-core))
48.23-
48.24-(defpackage :demo-ui
48.25- (:use :demo-core)
48.26- (:export
48.27- #:on-new-window
48.28- #:start-ui))
48.29-
48.30-(defpackage :demo
48.31- (:use #:cl #:demo-core #:demo-utils #:demo-db #:demo-ui)
48.32- (:local-nicknames
48.33- (#:bt #:bordeaux-threads)))
48.34-
48.35-(defpackage :demo-cli
48.36- (:use :demo :clingon))
48.37-
48.38-(defpackage :demo-user
48.39- (:use :demo))
49.1--- a/src/tests/clients/cli.lisp Thu Jun 20 22:31:58 2024 -0400
49.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
49.3@@ -1,7 +0,0 @@
49.4-(in-package #:demo-tests)
49.5-
49.6-(def-suite* :demo.cli
49.7- :in :demo)
49.8-
49.9-(test cli.args
49.10- (is (= 2 2)))
50.1--- a/src/tests/clients/web.lisp Thu Jun 20 22:31:58 2024 -0400
50.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
50.3@@ -1,7 +0,0 @@
50.4-(in-package #:demo-tests)
50.5-
50.6-(def-suite* :demo.web
50.7- :in :demo)
50.8-
50.9-(test web.index
50.10- (is (= 2 2)))
51.1--- a/src/tests/package.lisp Thu Jun 20 22:31:58 2024 -0400
51.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
51.3@@ -1,11 +0,0 @@
51.4-(defpackage #:demo-tests
51.5- (:use #:demo #:fiveam)
51.6- (:shadowing-import-from #:fiveam #:test)
51.7- (:export #:run-tests))
51.8-
51.9-(in-package #:demo-tests)
51.10-
51.11-(def-suite :demo)
51.12-
51.13-(defun run-tests ()
51.14- (run! :demo))
53.1--- a/src/tests/utils.lisp Thu Jun 20 22:31:58 2024 -0400
53.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
53.3@@ -1,46 +0,0 @@
53.4-(in-package #:demo-tests)
53.5-
53.6-(def-suite* :demo.utils
53.7- :in :demo)
53.8-
53.9-(defun gen-word ()
53.10- (gen-one-element "lorem" "ipsum"))
53.11-
53.12-(defun gen-text-element ()
53.13- (let ((word (gen-word)))
53.14- (lambda ()
53.15- (case (random 10)
53.16- (9 #\Newline)
53.17- (t (funcall word))))))
53.18-
53.19-(defun gen-text (&key (length (gen-integer :min 1 :max 20))
53.20- (element (gen-text-element)))
53.21- (let ((elements (gen-list :length length :elements element)))
53.22- (lambda ()
53.23- (with-output-to-string (stream)
53.24- (loop for previous = nil then element
53.25- for element in (funcall elements)
53.26- do (cond ((and previous (not (eql previous #\Newline)) (not (eql element #\Newline)))
53.27- (write-char #\Space stream)
53.28- (write-string element stream))
53.29- (t ; (and (eql previous #\Newline) (not (eql element #\Newline)))
53.30- (princ element stream))))))))
53.31-
53.32-(defun gen-offset (&key (integer (gen-integer :min -10 :max 10)))
53.33- (lambda ()
53.34- (case (random 10)
53.35- ((8 9 10) nil)
53.36- (t (funcall integer)))))
53.37-
53.38-(defun gen-margin (&key (integer (gen-integer :min 1 :max 10)))
53.39- (lambda ()
53.40- (case (random 10)
53.41- ((8 9 10) nil)
53.42- (t (funcall integer)))))
53.43-
53.44-(defun gen-count (&key (integer (gen-integer :min 1 :max 10)))
53.45- (lambda ()
53.46- (case (random 10)
53.47- ((8 9 10) nil)
53.48- (t (funcall integer)))))
53.49-
54.1--- a/src/ui/ui.lisp Thu Jun 20 22:31:58 2024 -0400
54.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
54.3@@ -1,43 +0,0 @@
54.4-(in-package :demo-ui)
54.5-
54.6-(defparameter ui-server-port 8080)
54.7-(defparameter ui-server-host "0.0.0.0")
54.8-
54.9-(defclass ui-element (clog-element) ()
54.10- (:documentation "UI Element Object."))
54.11-
54.12-(defgeneric create-ui-element (obj &key hidden class id mode)
54.13- (:documentation "Create a new ui-element as a child of OBJ."))
54.14-(defmethod create-ui-element ((obj clog:clog-obj)
54.15- &key (class nil)
54.16- (hidden nil)
54.17- (id nil)
54.18- (mode 'auto))
54.19- (let ((new (clog:create-div obj
54.20- :class class
54.21- :hidden hidden
54.22- :id id
54.23- :mode mode)))
54.24- (clog:set-geometry new :width 200 :height 100)
54.25- (change-class new 'ui-element)))
54.26-
54.27-(defun on-new-window (body)
54.28- "Handle new window event."
54.29- (clog:debug-mode body)
54.30- (let ((elt (clog:create-child body "<h1>foobar</h1>")))
54.31- (clog:set-on-click
54.32- elt
54.33- (lambda (o)
54.34- (setf (clog:color elt) "green")))))
54.35-
54.36-(defun start-ui ()
54.37- "Start the UI."
54.38- (clog:initialize #'on-new-window
54.39- :extended-routing t
54.40- :host ui-server-host
54.41- :port ui-server-port)
54.42- (clog:open-browser))
54.43-
54.44-(defun stop-ui ()
54.45- "Stop the UI."
54.46- (clog:shutdown))
55.1--- a/src/utils/rs.lisp Thu Jun 20 22:31:58 2024 -0400
55.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
55.3@@ -1,78 +0,0 @@
55.4-;;; RUST DSL
55.5-
55.6-;; So basically, this was born out of personal frustration with how
55.7-;; cbindgen and Rust macros work (they don't). Rust macros in general
55.8-;; are something of a pain in my opinion, so I thought why not just
55.9-;; generate Rust code from Lisp instead?
55.10-
55.11-(in-package :demo-utils)
55.12-
55.13-(defvar *cargo-target* #p"/Users/ellis/dev/otom8/demo/target/")
55.14-(defvar *rs-macros* nil)
55.15-
55.16-;; TODO gensyms
55.17-(defmacro rs-defmacro (name args &body body)
55.18- "Define a macro which can be used within the body of a 'with-rs' form."
55.19- `(prog1
55.20- (defmacro ,name ,@(mapcar #`(,a1) args) ,@body)
55.21- (push ',name *rs-macros*)))
55.22-
55.23-(defun rs-mod-form (crate &optional mods pub)
55.24- "Generate a basic mod form (CRATE . [MODS] [PUB])"
55.25- `(,crate ,mods ,pub))
55.26-
55.27-(defmacro with-rs-env (imports &body body)
55.28- "Generate an environment for use within a Rust generator macro."
55.29- `(let ((imports ,(mapcar #'rs-mod-form imports)))
55.30- (format nil "~A~&~A" imports ',body)))
55.31-
55.32-(defun rs-use (crate &optional mods pub)
55.33- "Generate a single Rust use statement."
55.34- (concatenate
55.35- 'string
55.36- (if pub "pub " "")
55.37- "use " crate "::{"
55.38- (cond
55.39- ((consp mods)
55.40- (reduce
55.41- (lambda (x y) (format nil "~A,~A" x y))
55.42- mods))
55.43- (t mods))
55.44- "};"))
55.45-
55.46-(defun rs-mod (mod &optional pub)
55.47- "Generate a single Rust mod statement."
55.48- (concatenate
55.49- 'string
55.50- (if pub "pub " "")
55.51- "mod " mod ";"))
55.52-
55.53-(defun rs-imports (&rest imports)
55.54- "Generate a string of Rust 'use' statements."
55.55- (cond
55.56- ((consp imports)
55.57- (mapcar (lambda (x) (apply #'rs-use (apply #'rs-mod-form x))) imports))
55.58- (t imports)))
55.59-
55.60-(defmacro rs-extern-c-fn (name args &optional pub unsafe no-mangle &body body)
55.61- "Generate a Rust extern 'C' fn."
55.62- `(concatenate
55.63- 'string
55.64- ,(when no-mangle (format nil "#[no_mangle]~&"))
55.65- ,(when pub "pub ")
55.66- ,(when unsafe "unsafe ")
55.67- "extern \"C\" fn " ,name "("
55.68- ,(cond
55.69- ((consp args) (reduce (lambda (x y) (format nil "~A,~A" x y)) args))
55.70- (t args))
55.71- ")" "{" ,@body "}"))
55.72-
55.73-(defun rs-obj-impl (obj)
55.74- "Implement Objective for give OBJ."
55.75- (format nil "impl Objective for ~A {};" obj))
55.76-
55.77-;; (defun rs-macroexpand-1 (form &optional env))
55.78-
55.79-;; (defun rs-macroexpand (env &rest body)
55.80-
55.81-;;;
56.1--- a/src/utils/utils.lisp Thu Jun 20 22:31:58 2024 -0400
56.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
56.3@@ -1,28 +0,0 @@
56.4-(in-package :demo-utils)
56.5-
56.6-(defun mkstr (&rest args)
56.7- (with-output-to-string (s)
56.8- (dolist (a args) (princ a s))))
56.9-
56.10-(defun symb (&rest args)
56.11- (values (intern (apply #'mkstr args))))
56.12-
56.13-(defun random-id ()
56.14- (format NIL "~8,'0x-~8,'0x" (random #xFFFFFFFF) (get-universal-time)))
56.15-
56.16-(defun scan-dir (dir filename callback)
56.17- (dolist (path (directory (merge-pathnames (merge-pathnames filename "**/") dir)))
56.18- (funcall callback path)))
56.19-
56.20-(defun sbq-reader (stream sub-char numarg)
56.21- "The anaphoric sharp-backquote reader: #`((,a1))"
56.22- (declare (ignore sub-char))
56.23- (unless numarg (setq numarg 1))
56.24- `(lambda ,(loop for i from 1 to numarg
56.25- collect (symb 'a i))
56.26- ,(funcall
56.27- (get-macro-character #\`) stream nil)))
56.28-
56.29-(eval-when (:load-toplevel)
56.30- (set-dispatch-macro-character
56.31- #\# #\` #'sbq-reader))
57.1--- a/system-index.txt Thu Jun 20 22:31:58 2024 -0400
57.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
57.3@@ -1,3 +0,0 @@
57.4-demo.asd
57.5-examples/examples.asd
57.6-examples/db/xdb/xdb.asd