Make web-frontend a crate that automatically rebuilds

This commit is contained in:
Austen Adler 2023-03-15 23:41:04 -04:00
parent 712313f153
commit 8b39e6fe69
11 changed files with 172 additions and 14 deletions

10
Cargo.lock generated
View File

@ -1738,9 +1738,19 @@ dependencies = [
"serde", "serde",
"tokio", "tokio",
"ufmt", "ufmt",
"web-frontend",
"xpin", "xpin",
] ]
[[package]]
name = "web-frontend"
version = "0.1.0"
dependencies = [
"rocket",
"rust-embed",
"xpin-wasm",
]
[[package]] [[package]]
name = "winapi" name = "winapi"
version = "0.3.9" version = "0.3.9"

View File

@ -9,6 +9,7 @@ members = [
"./words", "./words",
"./xpin-wasm/", "./xpin-wasm/",
"./web", "./web",
"./web-frontend/",
] ]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View File

@ -1,5 +1,4 @@
# Rust test needs to be built after because the web crate depends on js-build build: fmt rust-build rust-test
build: fmt js-build rust-build rust-test
push: push:
podman push gitea.austen-wares.com/public/xpin-server podman push gitea.austen-wares.com/public/xpin-server
@ -8,7 +7,7 @@ rust-test:
cargo test --all cargo test --all
cargo fmt --all --check cargo fmt --all --check
rust-build: output-clean js-build rust-build: output-clean
cargo build --all cargo build --all
cargo build -p web --release --target x86_64-unknown-linux-musl cargo build -p web --release --target x86_64-unknown-linux-musl
earthly +rust-image earthly +rust-image
@ -21,10 +20,9 @@ wasm-build: output-clean
wordlist-build: wordlist-build:
. wordlist/venv/bin/activate && cd wordlist && for i in *.py; do "./${i}"; done . wordlist/venv/bin/activate && cd wordlist && for i in *.py; do "./${i}"; done
js-build: output-clean wasm-build docs-build # js-build: output-clean wasm-build docs-build
for f in "${PWD}/web-frontend/src/lib/docs/"*.html; do ./web-frontend/node_modules/.bin/inliner "${f}" >"${f}-2" && mv -v -- "${f}-2" "${f}"; done # yarn --cwd ./web-frontend/ build
yarn --cwd ./web-frontend/ build # # rsync -ha ./web-frontend/build/ ./build/
rsync -ha ./web-frontend/build/ ./build/
output-clean: output-clean:
rm -vrf ./build/ ./web-frontend/build/ ./web-frontend/src/lib/docs/ rm -vrf ./build/ ./web-frontend/build/ ./web-frontend/src/lib/docs/
@ -33,6 +31,7 @@ output-clean:
docs-build: output-clean docs-build: output-clean
earthly +docs earthly +docs
rsync --stats -ha ./build/docs/ ./web-frontend/src/lib/docs/ rsync --stats -ha ./build/docs/ ./web-frontend/src/lib/docs/
for f in "${PWD}/web-frontend/src/lib/docs/"*.html; do ./web-frontend/node_modules/.bin/inliner "${f}" >"${f}-2" && mv -v -- "${f}-2" "${f}"; done
cargo doc --all cargo doc --all
# TODO: Clippy # TODO: Clippy

View File

@ -2,6 +2,7 @@
#![allow(clippy::cast_possible_truncation, clippy::multiple_crate_versions)] #![allow(clippy::cast_possible_truncation, clippy::multiple_crate_versions)]
#![allow(unused_imports)] #![allow(unused_imports)]
pub mod dense;
pub mod v0; pub mod v0;
use conversions::lat_lon_to_cellid; use conversions::lat_lon_to_cellid;
pub use s2::s1::angle::Angle; pub use s2::s1::angle::Angle;

11
web-frontend/Cargo.toml Normal file
View File

@ -0,0 +1,11 @@
[package]
name = "web-frontend"
version = "0.1.0"
edition = "2021"
[dependencies]
rocket = {version="0.5.0-rc.2", features=["json"]}
rust-embed = { version = "6.6.0", features = ["rocket"] }
[build-dependencies]
xpin-wasm={path="../xpin-wasm/"}

32
web-frontend/build.rs Normal file
View File

@ -0,0 +1,32 @@
use std::process::Command;
fn main() {
for path in [
// ".svelte-kit",
"Cargo.toml",
"README.md",
// "build",
"build.rs",
"jsconfig.json",
// Excluding because it includes the module `xpin-wasm`
// "node_modules",
"package.json",
"postcss.config.cjs",
"src",
"static",
"svelte.config.js",
"tailwind.config.cjs",
"vite.config.js",
"yarn.lock",
] {
println!("cargo:rerun-if-changed=./{path}");
}
if !Command::new("yarn")
.arg("build")
.status()
.expect("Could not spawn yarn build")
.success()
{
panic!("yarn build failed");
}
}

5
web-frontend/src/lib.rs Normal file
View File

@ -0,0 +1,5 @@
use rust_embed::RustEmbed;
#[derive(RustEmbed)]
#[folder = "./build/"]
pub struct Asset;

View File

@ -12,3 +12,4 @@ xpin={path=".."}
serde = {version="1", features=["derive"]} serde = {version="1", features=["derive"]}
rust-embed = { version = "6.6.0", features = ["rocket"] } rust-embed = { version = "6.6.0", features = ["rocket"] }
ufmt = "0.2.0" ufmt = "0.2.0"
web-frontend={path="../web-frontend/"}

View File

@ -1,3 +0,0 @@
fn main() {
println!("cargo:rerun-if-changed=../build");
}

View File

@ -5,10 +5,7 @@ use rust_embed::RustEmbed;
use std::borrow::Cow; use std::borrow::Cow;
use std::ffi::OsStr; use std::ffi::OsStr;
use std::path::PathBuf; use std::path::PathBuf;
use web_frontend::Asset;
#[derive(RustEmbed)]
#[folder = "../build/"]
struct Asset;
#[get("/<file..>")] #[get("/<file..>")]
pub(crate) fn dist(file: PathBuf) -> Option<(ContentType, Cow<'static, [u8]>)> { pub(crate) fn dist(file: PathBuf) -> Option<(ContentType, Cow<'static, [u8]>)> {

View File

@ -54,6 +54,71 @@ where
.copied() .copied()
} }
/// Gets multiple words given their index, but without repitition by skipping words if they would match
///
/// For example, if the numeric value this should encode is [0, 0, 0],
/// the index of the words would be [0, 1, 2]
///
/// [1, 2, 3] => word number [1, 3, 5]
/// [3, 2, 1] => word number [3, 2, 1]
/// [1, 1, 0] => word number [1, 2, 0]
pub fn get_words_multi<const N: usize>(word_idx: [u16; N]) -> [&'static Word<'static>; N] {
// The vec of words to return
let mut words = Vec::with_capacity(N);
// The effective index of every word
let mut seen_effective_idx = Vec::with_capacity(N);
for w_idx in word_idx {
let mut w_effective = w_idx;
seen_effective_idx.sort();
for other_effective_idx in seen_effective_idx.iter() {
if &w_effective >= other_effective_idx {
w_effective += 1;
}
}
seen_effective_idx.push(w_effective);
words.push(NUMBER_TO_WORDS[w_effective as usize][0]);
}
words
.try_into()
.expect("get_words_multi return vec did not match size")
}
pub fn get_word_numbers_multi<const N: usize>(words: [&Word<'static>; N]) -> [u16; N] {
let mut values = Vec::with_capacity(N);
let mut seen_effective_idx = words.iter().map(|w| w.number).collect::<Vec<_>>();
seen_effective_idx.sort();
for w_e in words.iter().rev().map(|w| w.number) {
let mut w_idx = w_e;
if let Some(idx) = seen_effective_idx
.iter()
.position(|other_e| *other_e == w_idx)
{
seen_effective_idx.remove(idx);
}
for other_e in seen_effective_idx.iter().rev() {
if w_idx >= *other_e {
w_idx -= 1;
}
}
values.push(w_idx);
}
values.reverse();
// pub fn get_idx_from_multi(words: &[&'static Word<'static>>]) -> Vec<&'static Word<'static>> {
values
.try_into()
.expect("get_words_multi return vec did not match size")
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@ -96,4 +161,43 @@ mod tests {
// te!(sent, scents); // te!(sent, scents);
// te!(sent, cents); // te!(sent, cents);
} }
#[test]
fn test_get_words_multi() {
for w1i in 0..=5 {
for w2i in 0..=5 {
for w3i in 0..=5 {
let input = [w1i, w2i, w3i];
eprintln!("Testing getting word {input:?}");
let effective = get_words_multi(input);
let [w1e, w2e, w3e] = effective;
let output = get_word_numbers_multi(effective);
// let [w1o, w2o, w30] = output;
eprintln!("{:?} => {:?} => {:?}", input, effective, output);
// Make sure the effective values are not the same
assert_ne!(w1e, w2e);
assert_ne!(w2e, w3e);
assert_ne!(w1e, w3e);
// Make sure the encoded owrds are not the same
assert_ne!(w1e.number, w2e.number);
assert_ne!(w2e.number, w3e.number);
assert_ne!(w1e.number, w3e.number);
assert_ne!(w1e.word, w2e.word);
assert_ne!(w2e.word, w3e.word);
assert_ne!(w1e.word, w3e.word);
// Make sure that once decoded again, the results match
assert_eq!(input, output);
}
}
}
assert!(false);
}
} }