Static site generator + my presonnal website written in rust for some reason.

Compare changes

Choose any two refs to compare.

+1
.gitignore
···
/target
+
/output
+33 -538
Cargo.lock
···
version = 3
[[package]]
-
name = "addr2line"
-
version = "0.22.0"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678"
-
dependencies = [
-
"gimli",
-
]
-
-
[[package]]
-
name = "adler"
-
version = "1.0.2"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
-
-
[[package]]
name = "adler2"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
]
[[package]]
-
name = "askama_axum"
-
version = "0.4.0"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "a41603f7cdbf5ac4af60760f17253eb6adf6ec5b6f14a7ed830cf687d375f163"
-
dependencies = [
-
"askama",
-
"axum-core",
-
"http",
-
]
-
-
[[package]]
name = "askama_derive"
version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
"proc-macro2",
"quote",
"serde",
-
"syn 2.0.76",
+
"syn 2.0.77",
]
[[package]]
···
]
[[package]]
-
name = "async-trait"
-
version = "0.1.81"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107"
-
dependencies = [
-
"proc-macro2",
-
"quote",
-
"syn 2.0.76",
-
]
-
-
[[package]]
name = "autocfg"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]]
-
name = "axum"
-
version = "0.7.5"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf"
-
dependencies = [
-
"async-trait",
-
"axum-core",
-
"bytes",
-
"futures-util",
-
"http",
-
"http-body",
-
"http-body-util",
-
"hyper",
-
"hyper-util",
-
"itoa",
-
"matchit",
-
"memchr",
-
"mime",
-
"percent-encoding",
-
"pin-project-lite",
-
"rustversion",
-
"serde",
-
"serde_json",
-
"serde_path_to_error",
-
"serde_urlencoded",
-
"sync_wrapper 1.0.1",
-
"tokio",
-
"tower",
-
"tower-layer",
-
"tower-service",
-
"tracing",
-
]
-
-
[[package]]
-
name = "axum-core"
-
version = "0.4.3"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3"
-
dependencies = [
-
"async-trait",
-
"bytes",
-
"futures-util",
-
"http",
-
"http-body",
-
"http-body-util",
-
"mime",
-
"pin-project-lite",
-
"rustversion",
-
"sync_wrapper 0.1.2",
-
"tower-layer",
-
"tower-service",
-
"tracing",
-
]
-
-
[[package]]
-
name = "backtrace"
-
version = "0.3.73"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a"
-
dependencies = [
-
"addr2line",
-
"cc",
-
"cfg-if",
-
"libc",
-
"miniz_oxide 0.7.4",
-
"object",
-
"rustc-demangle",
-
]
-
-
[[package]]
name = "base64"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
-
name = "bytes"
-
version = "1.7.1"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
-
-
[[package]]
name = "caseless"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
"heck",
"proc-macro2",
"quote",
-
"syn 2.0.76",
+
"syn 2.0.77",
]
[[package]]
···
"proc-macro2",
"quote",
"strsim",
-
"syn 2.0.76",
+
"syn 2.0.77",
]
[[package]]
···
dependencies = [
"darling_core",
"quote",
-
"syn 2.0.76",
+
"syn 2.0.77",
]
[[package]]
···
[[package]]
name = "derive_builder"
-
version = "0.20.0"
+
version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "0350b5cb0331628a5916d6c5c0b72e97393b8b6b03b47a9284f4e7f5a405ffd7"
+
checksum = "cd33f37ee6a119146a1781d3356a7c26028f83d779b2e04ecd45fdc75c76877b"
dependencies = [
"derive_builder_macro",
]
[[package]]
name = "derive_builder_core"
-
version = "0.20.0"
+
version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "d48cda787f839151732d396ac69e3473923d54312c070ee21e9effcaa8ca0b1d"
+
checksum = "7431fa049613920234f22c47fdc33e6cf3ee83067091ea4277a3f8c4587aae38"
dependencies = [
"darling",
"proc-macro2",
"quote",
-
"syn 2.0.76",
+
"syn 2.0.77",
]
[[package]]
name = "derive_builder_macro"
-
version = "0.20.0"
+
version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b"
+
checksum = "4abae7035bf79b9877b779505d8cf3749285b80c43941eda66604841889451dc"
dependencies = [
"derive_builder_core",
-
"syn 2.0.76",
+
"syn 2.0.77",
]
[[package]]
···
checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253"
dependencies = [
"crc32fast",
-
"miniz_oxide 0.8.0",
+
"miniz_oxide",
]
[[package]]
···
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
-
name = "form_urlencoded"
-
version = "1.2.1"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
-
dependencies = [
-
"percent-encoding",
-
]
-
-
[[package]]
-
name = "futures-channel"
-
version = "0.3.30"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
-
dependencies = [
-
"futures-core",
-
]
-
-
[[package]]
-
name = "futures-core"
-
version = "0.3.30"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
-
-
[[package]]
-
name = "futures-sink"
-
version = "0.3.30"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
-
-
[[package]]
-
name = "futures-task"
-
version = "0.3.30"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
-
-
[[package]]
-
name = "futures-util"
-
version = "0.3.30"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
-
dependencies = [
-
"futures-core",
-
"futures-task",
-
"pin-project-lite",
-
"pin-utils",
-
]
-
-
[[package]]
name = "getrandom"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
]
[[package]]
-
name = "gimli"
-
version = "0.29.0"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
-
-
[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
-
name = "hermit-abi"
-
version = "0.3.9"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
-
-
[[package]]
-
name = "http"
-
version = "1.1.0"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258"
-
dependencies = [
-
"bytes",
-
"fnv",
-
"itoa",
-
]
-
-
[[package]]
-
name = "http-body"
-
version = "1.0.1"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
-
dependencies = [
-
"bytes",
-
"http",
-
]
-
-
[[package]]
-
name = "http-body-util"
-
version = "0.1.2"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
-
dependencies = [
-
"bytes",
-
"futures-util",
-
"http",
-
"http-body",
-
"pin-project-lite",
-
]
-
-
[[package]]
-
name = "http-range-header"
-
version = "0.4.1"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "08a397c49fec283e3d6211adbe480be95aae5f304cfb923e9970e08956d5168a"
-
-
[[package]]
-
name = "httparse"
-
version = "1.9.4"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9"
-
-
[[package]]
-
name = "httpdate"
-
version = "1.0.3"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
-
-
[[package]]
name = "humansize"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
]
[[package]]
-
name = "hyper"
-
version = "1.4.1"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05"
-
dependencies = [
-
"bytes",
-
"futures-channel",
-
"futures-util",
-
"http",
-
"http-body",
-
"httparse",
-
"httpdate",
-
"itoa",
-
"pin-project-lite",
-
"smallvec",
-
"tokio",
-
]
-
-
[[package]]
-
name = "hyper-util"
-
version = "0.1.7"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9"
-
dependencies = [
-
"bytes",
-
"futures-util",
-
"http",
-
"http-body",
-
"hyper",
-
"pin-project-lite",
-
"tokio",
-
]
-
-
[[package]]
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
[[package]]
name = "indexmap"
-
version = "2.4.0"
+
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c"
+
checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5"
dependencies = [
"equivalent",
"hashbrown 0.14.5",
···
]
[[package]]
-
name = "matchit"
-
version = "0.7.3"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
-
-
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
-
-
[[package]]
-
name = "miniz_oxide"
-
version = "0.7.4"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
-
dependencies = [
-
"adler",
-
]
[[package]]
name = "miniz_oxide"
···
]
[[package]]
-
name = "mio"
-
version = "1.0.2"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec"
-
dependencies = [
-
"hermit-abi",
-
"libc",
-
"wasi",
-
"windows-sys 0.52.0",
-
]
-
-
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
]
[[package]]
-
name = "object"
-
version = "0.36.3"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9"
-
dependencies = [
-
"memchr",
-
]
-
-
[[package]]
name = "once_cell"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
-
name = "pin-project"
-
version = "1.1.5"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3"
-
dependencies = [
-
"pin-project-internal",
-
]
-
-
[[package]]
-
name = "pin-project-internal"
-
version = "1.1.5"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
-
dependencies = [
-
"proc-macro2",
-
"quote",
-
"syn 2.0.76",
-
]
-
-
[[package]]
-
name = "pin-project-lite"
-
version = "0.2.14"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
-
-
[[package]]
-
name = "pin-utils"
-
version = "0.1.0"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
-
-
[[package]]
name = "pkg-config"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016"
dependencies = [
"base64",
-
"indexmap 2.4.0",
+
"indexmap 2.5.0",
"quick-xml",
"serde",
"time",
···
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
[[package]]
-
name = "rustc-demangle"
-
version = "0.1.24"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
-
-
[[package]]
name = "rustix"
version = "0.38.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
]
[[package]]
-
name = "rustversion"
-
version = "1.0.17"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6"
-
-
[[package]]
-
name = "rusty_duck"
-
version = "0.1.0"
-
dependencies = [
-
"askama",
-
"askama_axum",
-
"axum",
-
"comrak",
-
"markdown-parser",
-
"rand",
-
"serde",
-
"serde_yaml 0.9.34+deprecated",
-
"tokio",
-
"tower-http",
-
]
-
-
[[package]]
name = "ryu"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
dependencies = [
"proc-macro2",
"quote",
-
"syn 2.0.76",
+
"syn 2.0.77",
]
[[package]]
···
]
[[package]]
-
name = "serde_path_to_error"
-
version = "0.1.16"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6"
-
dependencies = [
-
"itoa",
-
"serde",
-
]
-
-
[[package]]
-
name = "serde_urlencoded"
-
version = "0.7.1"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
-
dependencies = [
-
"form_urlencoded",
-
"itoa",
-
"ryu",
-
"serde",
-
]
-
-
[[package]]
name = "serde_yaml"
version = "0.8.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
dependencies = [
-
"indexmap 2.4.0",
+
"indexmap 2.5.0",
"itoa",
"ryu",
"serde",
···
]
[[package]]
-
name = "smallvec"
-
version = "1.13.2"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
-
-
[[package]]
-
name = "socket2"
-
version = "0.5.7"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c"
+
name = "staticrustator"
+
version = "0.1.0"
dependencies = [
-
"libc",
-
"windows-sys 0.52.0",
+
"askama",
+
"comrak",
+
"markdown-parser",
+
"rand",
+
"serde",
+
"serde_yaml 0.9.34+deprecated",
+
"syntect",
]
[[package]]
···
[[package]]
name = "syn"
-
version = "2.0.76"
+
version = "2.0.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525"
+
checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
dependencies = [
"proc-macro2",
"quote",
···
]
[[package]]
-
name = "sync_wrapper"
-
version = "0.1.2"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
-
-
[[package]]
-
name = "sync_wrapper"
-
version = "1.0.1"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394"
-
-
[[package]]
name = "syntect"
version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
dependencies = [
"proc-macro2",
"quote",
-
"syn 2.0.76",
+
"syn 2.0.77",
[[package]]
···
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
-
name = "tokio"
-
version = "1.39.3"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5"
-
dependencies = [
-
"backtrace",
-
"bytes",
-
"libc",
-
"mio",
-
"pin-project-lite",
-
"socket2",
-
"tokio-macros",
-
"windows-sys 0.52.0",
-
]
-
-
[[package]]
-
name = "tokio-macros"
-
version = "2.4.0"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
-
dependencies = [
-
"proc-macro2",
-
"quote",
-
"syn 2.0.76",
-
]
-
-
[[package]]
-
name = "tokio-util"
-
version = "0.7.11"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1"
-
dependencies = [
-
"bytes",
-
"futures-core",
-
"futures-sink",
-
"pin-project-lite",
-
"tokio",
-
]
-
-
[[package]]
name = "toml"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
[[package]]
-
name = "tower"
-
version = "0.4.13"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
-
dependencies = [
-
"futures-core",
-
"futures-util",
-
"pin-project",
-
"pin-project-lite",
-
"tokio",
-
"tower-layer",
-
"tower-service",
-
"tracing",
-
]
-
-
[[package]]
-
name = "tower-http"
-
version = "0.5.2"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5"
-
dependencies = [
-
"bitflags 2.6.0",
-
"bytes",
-
"futures-util",
-
"http",
-
"http-body",
-
"http-body-util",
-
"http-range-header",
-
"httpdate",
-
"mime",
-
"mime_guess",
-
"percent-encoding",
-
"pin-project-lite",
-
"tokio",
-
"tokio-util",
-
"tower-layer",
-
"tower-service",
-
"tracing",
-
]
-
-
[[package]]
-
name = "tower-layer"
-
version = "0.3.3"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
-
-
[[package]]
-
name = "tower-service"
-
version = "0.3.3"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
-
-
[[package]]
-
name = "tracing"
-
version = "0.1.40"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
-
dependencies = [
-
"log",
-
"pin-project-lite",
-
"tracing-core",
-
]
-
-
[[package]]
-
name = "tracing-core"
-
version = "0.1.32"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
-
dependencies = [
-
"once_cell",
-
]
-
-
[[package]]
name = "typed-arena"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
"once_cell",
"proc-macro2",
"quote",
-
"syn 2.0.76",
+
"syn 2.0.77",
"wasm-bindgen-shared",
···
dependencies = [
"proc-macro2",
"quote",
-
"syn 2.0.76",
+
"syn 2.0.77",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
···
dependencies = [
"proc-macro2",
"quote",
-
"syn 2.0.76",
+
"syn 2.0.77",
+4 -7
Cargo.toml
···
[package]
-
name = "rusty_duck"
+
name = "staticrustator"
version = "0.1.0"
edition = "2021"
···
strip = "symbols" # Strip symbols from binary
[dependencies]
-
askama = { version = "0.12.1", features = ["with-axum"] }
-
askama_axum = "0.4.0"
-
axum = "0.7.5"
-
comrak = "0.27.0"
+
askama = { version = "0.12.1" }
+
comrak = { version = "0.27.0", features = ["syntect"] }
markdown-parser = "0.1.2"
rand = "0.8.5"
serde = { version = "1.0.209", features = ["derive"] }
serde_yaml = "0.9.34"
-
tokio = { version = "1.39.3", features = ["macros", "rt-multi-thread"] }
-
tower-http = { version = "0.5.2", features = ["fs"] }
+
syntect = "5.2.0"
+51
README.md
···
+
# Staticrustator (being workshopped)
+
+
After struggling with rewriting personnal website in a myriad of ways, all in some way unsatisfying,
+
I have decided to write my own statis site generator.
+
+
Heavily inspired by [Saait](https://codemadness.org/git/saait/), since that is what I have been using previously.
+
+
To build
+
```bash
+
cargo build
+
```
+
+
and to create the website structure
+
```bash
+
cargo run
+
```
+
+
This will create the folder `output` then you can sync to your vpc, or however you serve stataic files.
+
+
-------
+
## File organization
+
+
The posts are taken from `posts/` folder, are structured as markdown files, with a front matter in yaml for the date, and title of the post.
+
+
+
Example:
+
```markdown
+
---
+
title: Pantheon
+
date: 2024-03-03
+
---
+
# WATCH PANTHEON
+
+
## I DO NOT CARE WHAT DAY IT IS
+
+
### HERE'S YOUR PLAN
+
+
1. Wake up.
+
2. Open whatever device you watch things on.
+
3. Obtain, legally or illegaly, by any means necessary, 2 (two) seasons of Pantheon, created by Craig Silverstein based on short stories by Ken Liu.
+
4. Binge the 2 sesons in a single night (it is feasable I checked)
+
+
Thank you for coming to my Ted Talk.
+
```
+
+
Additional pages such as `about` is also taken from there, however you could modify the about template in `templates` folder.
+
[Askama](https://github.com/djc/askama) is a rendering engine based on Jinja, so it is rather straight forward to use,
+
but also it can take rust `structs` to hold template context, which is very nice.
+
+
I have not yet integrated htmx into is, for faster loads of the post body,but that's for the future (also I hate js).
+
+7
content/pages/about.md
···
+
---
+
title:about page
+
date:01-09-2024
+
---
+
# Welcome to my site!
+
+
Inspired originally by the yesterweb ring, a small portion of the internet where I post (rarely) about stuff i think i make that is cool.
+14
content/posts/000-genesis.md
···
+
---
+
title: Full website Update
+
date: 2023-01-12
+
---
+
## New Website
+
+
### Saait
+
+
I got a little bit tired of the old site, so changed it to something more ~websit-y~
+
+
Now its made using [Saait](https://git.codemadness.org/saait/) and what a treat it is.
+
+
More Updates coming.
+
+11
content/posts/001-bash_blogger.md
···
+
---
+
title: Creating posts with bash and git from terminal
+
date: 2023-01-13
+
---
+
Since updating this website with Saait, I have decided to create a tool to streamline page creation from the terminal.
+
+
Inspired by [bash_blog](https://github.com/j0m/bash_blog) and [bashblog](https://github.com/cfenollosa/bashblog) especially bash was chosen.
+
+
It is goofy, not as practical as I would think, but neat nevertheless.
+
+
Source at my [git](https://git.technoduck.me) repo.
+32
content/posts/002-services.md
···
+
---
+
title: List of Services running on the server
+
date: 2023-01-13
+
---
+
+
### This blog
+
+
Self explanatory. This is my [website](/), my little corner of the internet.
+
+
### Email
+
+
Self hosted email server using Dovecot + Posfix.
+
+
### Git
+
+
[forgejo](https://git.technoduck.me) instance for my personal projects.
+
+
### Etebase
+
+
An [Etebase](https://etebase.technoduck.me) instance for syncing my tasks, to-do's and contacts between devices.
+
+
### Grocy
+
+
[Grocy](https://grocy.technoduck.me) instance for keeping track of food and grocery lists ( and literally anything else in your house including batteris in devices? ) it's really cool give it a check.
+
+
### Wiki
+
+
A [wikimedia](https://wiki.cold-metal.technoduck.me) instance running for a friend for categorizing all the lore of the world that is being created for a soft fiction story.
+
+
### WIP
+
+
Work in progress of a [website](https://wip.technoduck.me) I am making for a photographer/photography business.
+41
content/posts/003-led_hoop.md
···
+
---
+
title: PCB LED hoop earring project
+
date: 2024-01-02
+
---
+
## LED Hoops
+
+
### What?
+
+
First, a blog post by [mitxela](https://mitxela.com) came upon my eyes, and piqued my interest.
+
+
Inspired by the [industrial piercing](https://mitxela.com/projects/scaffold) and the electronics that went into it, I though if other pieces of jewelry can be made with electronics (they can, it was specifically a question if my measly hands could craft them).
+
+
Since for the first time, I didn't want to experiment with absolute microscopic sizes, I decided that a 4 cm hoop was an adequate project to attempt.
+
+
![schematic_kicad_image](/assets/img/led_hoop/schematic.png)
+
+
An Attiny 24/44/84A can be used, I went with a -M variant, since it is slightly larger then the -MM variant, by a whole mm, which I assume will be easier to solder.
+
+
Placing them all in a nice hoop looking pcb, we obtain this:
+
+
![pcb_kicad_image](/assets/img/led_hoop/pcb.svg)
+
+
The test version comes with ISP pins for debugging and programming the chip when it's already installed.
+
+
0603 LED's were chosen for the same reason, they are small enough to be not that noticeable, but large enough to be not an incredible pain to work with.
+
+
### Why??
+
+
It looked and sounded fun, my only previous projects related to PCB production before this was edition a split [Sweep](https://github.com/davidphilipbarr/Sweep) keyboard.
+
+
And so I did.
+
+
### Cool. What now?
+
+
You can take your chance and go to [the git repository](https://git.technoduck.me/technoduck/led_hoop) for the project, `git pull`, and try your own luck.
+
+
+
+
+
Batteries not included.
+
+16
content/posts/004-pantheon.md
···
+
---
+
title: Pantheon
+
date: 2024-03-03
+
---
+
# WATCH PANTHEON
+
+
## I DO NOT CARE WHAT DAY IT IS
+
+
### HERE'S YOUR PLAN
+
+
1. Wake up.
+
2. Open whatever device you watch things on.
+
3. Obtain, legally or illegaly, by any means necessary, 2 (two) seasons of Pantheon, created by Craig Silverstein based on short stories by Ken Liu.
+
4. Binge the 2 sesons in a single night (it is feasable I checked)
+
+
Thank you for coming to my Ted Talk.
+106
content/posts/005-regenesis.md
···
+
---
+
title: Full website Re-Update
+
date: 2024-08-29
+
---
+
## New Website?
+
+
### Rust
+
+
The time has come and another re-write is upon us.
+
+
This time inspied by [this article](https://blog.transrights.art/blogs/2024_Screw-Frameworks-New-Site-2),
+
[theprimeagen](https://www.youtube.com/watch?v=rcZSOLAI1lM), and everpresent desire to rewrite everything in Rust,
+
the new website is a complete rewrite using rust and adjacent techniques.
+
+
Using only
+
```
+
[dependencies]
+
askama = { version = "0.12.1", features = ["with-axum"] }
+
askama_axum = "0.4.0"
+
axum = "0.7.5"
+
comrak = "0.27.0"
+
markdown-parser = "0.1.2"
+
rand = "0.8.5"
+
serde = { version = "1.0.209", features = ["derive"] }
+
serde_yaml = "0.9.34"
+
tokio = { version = "1.39.3", features = ["macros", "rt-multi-thread"] }
+
tower-http = { version = "0.5.2", features = ["fs"] }
+
```
+
as dependencies in the end we get a clean~ish, 2.8MB executable.
+
+
All markdown compilation gets done every time page is loaded, which is sub-optimal,
+
But reading time for all posts is non-significant compared to other loading times.
+
+
And voila, there is the new post.
+
+
## Update
+
+
This approach however had few issues.
+
As fun as it is writing your own routing logic, It feels purely unnecessary.
+
+
Even scaling down from `axum` to `tiny_http`, it doesn't change the binary size, and because of the limited resources and location of the VPS,
+
it does not affect the load times.
+
+
Short of rewriting it all in [Yew](yew.rs) and loading the wasm as a SPA (which comes with it's own complexity) loading times would not improve.
+
+
Therefore the goal has been slightly changed.
+
From serving the files the goal is now using askama like a sort of static site generator.
+
+
# DIY Hugo?
+
+
Not exactly. In the current state it is basically Saait again, but with extra steps.
+
Additional pages require source code intervention, which isn't hard, but tidious.
+
+
//TODO: use some enum for pages, with derive as EnumString, so new pages can be added simply by adding a template.
+
+
+
But for now, the new dependencies now look like this:
+
+
```toml
+
[dependencies]
+
askama = { version = "0.12.1" }
+
comrak = "0.27.0"
+
markdown-parser = "0.1.2"
+
rand = "0.8.5"
+
serde = { version = "1.0.209", features = ["derive"] }
+
serde_yaml = "0.9.34"
+
syntect = "5.2.0"
+
```
+
+
Syntect providing oh so nice code highlighting in the markdown.
+
+
+
```json
+
{
+
"firstName": "John",
+
"lastName": "Smith",
+
"age": 25
+
}
+
```
+
+
```rust
+
+
std::fs::write(format!("{output_path}/index.html"), handlers::index().as_bytes()).expect("Couldnt write index file");
+
std::fs::write(format!("{output_path}/about.html"), handlers::about().as_bytes()).expect("Couldnt write about file");
+
std::fs::write(format!("{output_path}/404.html"), handlers::not_found().as_bytes()).expect("Couldnt write 404 file");
+
+
+
for entry in post_dir_iter {
+
if let Ok(entry) = entry {
+
+
let filename = entry.file_name().into_string().unwrap().split(".").collect::<Vec<_>>()[0].to_string();
+
+
fs::write(format!("{output_path}/blog/{filename}.html"), handlers::blog(filename).as_bytes()).expect("Couldnt write blog entry");
+
};
+
+
}
+
+
```
+
+
For now, I am rather happy with the result.
+
+
Built for release profile, binary is just 3.1M (majority of it is syntact), and produces a output folder with it's contents in a rather pleasant amount of time.
+
> ./target/release/rusty_duck 0.03s user 0.01s system 97% cpu 0.035 total
+
+
This is no **BLAZING** speed, but it's honest work.
+
+90
content/posts/006-tangled.md
···
+
---
+
title: Tangled
+
date: 2025-03-17
+
---
+
+
# Personal git forges
+
+
In pursuit of federation for git forges, few attempts are being made.
+
+
Until recently the main one being [Forgejo](https://forgejo.org/), with utilization of ActivityPub, the driving force behind Mastodon, Pleroma, and the like, as communication protocol.
+
+
## how Personal
+
+
Forgejo is a community maintained fork of Gitea, and for good reason and with good effect. It allowed them to while maintaining some compatibility, but also go into a radically different direction then Gitea could.
+
+
A consequence of being a fork of Gitea is well, at core being a git forge designed for communities and not individuals.
+
+
Not in a *usage* sense, but in **operations** sense.
+
+
## say what
+
+
Frogejo my beloved, always will be. Its delightful to work with, its easy to host and run, its dead easy to update (don't forget breaking config changes), action runners are easy to setup and use, and the whole thing is easy to manage.
+
+
That all however comes at a cost of a whole-ass web-server running all the time, with a postgres db running in the background where your repositories are actually kept.
+
+
At scale its well, the best case scenario. But we aren't talking about the best case scenario we are talking about 1 (one) idiot (big one) running it for personal projects.
+
+
And that's a lot of overhead for what can be a bare git repo on a server running git-daemon.
+
+
Its not useless overhead, but having a whole gig of memory on my poor 2 gig VPS taken up by a git forge I don't use even a 3rd of services of is a bit too much. (also cant federate just yet).
+
+
+
+
# Alternatives?
+
+
[git-send-mail](https://git-scm.com/docs/git-send-email), the most federalized mode of collaboration in the world, used to work on the Linux kernel, arguably? largest community project right now.
+
+
It is flexible, infinitely customizable for both you the user and the recipient, and requires no account other then a single (1) email address I hope everyone has.
+
But like IRC chatrooms, it is realistically used by far not all even amongst developers, and is more or less inaccessible to people new to the whole git thing.
+
+
[Radicle](https://radicle.xyz/), fully P2P, custom communication protocol, similar system that all nodes are viewable from the central website, but there is no central authority for what the repo state is, it is local first.
+
Really interesting, **written in rust**, and will get a good amount of attention from me because well it's pretty cool. To collaborate in the network, like with the Tor network, from which it drew heavy inspiration as I understand (again, really cool),
+
one has to run their own node. Which isn't ideal always for, same issues as before, beginners (although getting to understand such things one could argue is a worthy and formative trial by fire, and should be done).
+
+
[Tangled](https://tangled.sh) The topic of today
+
+
+
# [Tangled](https://tangled.sh)
+
+
A very new and currently in development git forge based on the AT Protocol, used by Bluesky.
+
+
I will let them make [their own case](https://blog.tangled.sh/intro), in a rather short and sweet introduction.
+
+
With the long story short being as such.
+
+
To collaborate, one requires a Bluesky account. More precisely an account in the AT Protocol network, but I digress.
+
Repositories are hosted on **knots**, headless servers that behave very much like git-daemons, with repositories being hosted in bare repos.
+
+
There is a central knot managed by the tangled team, `knot.tangled.sh`, on which anyone can make a repo, or if you are authorized with other knots, hosted by anyone, you can author repos there.
+
+
All of that, can be viewed on centrally in the appview hosted by tangled.sh team at, you guessed it, [tangled.sh](https://tangled.sh).
+
(in theory there can be other appview, the same way as there are alternative clients for bsky.app, there could be alternative appviews for tangled, with the same underlying content).
+
+
So, account creation is not complex, hosting your own nodes is not a requirement, it is linked to a social network, which could be argued to be excessive, but you can create alternative accounts if you don't want your code to be associated with your public activity (or the other way around).
+
+
+
And, while Forgejo is indeed lightweight and performant, very few things can compete with
+
```
+
* knotserver.service - tangled knot server
+
Loaded: loaded (/etc/systemd/system/knotserver.service; enabled; preset: enabled)
+
Active: active (running) since Fri 2025-03-14 02:44:33 UTC; 3 days ago
+
Main PID: [you thought] (knotserver)
+
Tasks: 7 (limit: 2424)
+
Memory: 50.9M
+
CPU: 32.406s
+
CGroup: /system.slice/knotserver.service
+
- [nuh-uh] /usr/local/bin/knotserver
+
```
+
+
Ah yes, 50.9M of memory used.
+
Much better.
+
+
Anyway gotta get now `git.technoduck.me` to redirect to my git profile on tangled, which should be [https://tangled.sh/@technoduck.me](https://tangled.sh/@technoduck.me).
+
+
Or fully remove, I have not decided yet.
+
+
+
Anyway, that's it.
+
+
Go on collaborooting or something.
-14
posts/000-genesis.md
···
-
---
-
title: Full website Update
-
date: 2023-01-12
-
---
-
## New Website
-
-
### Saait
-
-
I got a little bit tired of the old site, so changed it to something more ~websit-y~
-
-
Now its made using [Saait](https://git.codemadness.org/saait/) and what a treat it is.
-
-
More Updates coming.
-
-11
posts/001-bash_blogger.md
···
-
---
-
title: Creating posts with bash and git from terminal
-
date: 2023-01-13
-
---
-
Since updating this website with Saait, I have decided to create a tool to streamline page creation from the terminal.
-
-
Inspired by [bash_blog](https://github.com/j0m/bash_blog) and [bashblog](https://github.com/cfenollosa/bashblog) especially bash was chosen.
-
-
It is goofy, not as practical as I would think, but neat nevertheless.
-
-
Source at my [git](https://git.technoduck.me) repo.
-32
posts/002-services.md
···
-
---
-
title: List of Services running on the server
-
date: 2023-01-13
-
---
-
-
### This blog
-
-
Self explanatory. This is my [website](/), my little corner of the internet.
-
-
### Email
-
-
Self hosted email server using Dovecot + Posfix.
-
-
### Git
-
-
[forgejo](https://git.technoduck.me) instance for my personal projects.
-
-
### Etebase
-
-
An [Etebase](https://etebase.technoduck.me) instance for syncing my tasks, to-do's and contacts between devices.
-
-
### Grocy
-
-
[Grocy](https://grocy.technoduck.me) instance for keeping track of food and grocery lists ( and literally anything else in your house including batteris in devices? ) it's really cool give it a check.
-
-
### Wiki
-
-
A [wikimedia](https://wiki.cold-metal.technoduck.me) instance running for a friend for categorizing all the lore of the world that is being created for a soft fiction story.
-
-
### WIP
-
-
Work in progress of a [website](https://wip.technoduck.me) I am making for a photographer/photography business.
-41
posts/003-led_hoop.md
···
-
---
-
title: PCB LED hoop earring project
-
date: 2024-01-02
-
---
-
## LED Hoops
-
-
### What?
-
-
First, a blog post by [mitxela](https://mitxela.com) came upon my eyes, and piqued my interest.
-
-
Inspired by the [industrial piercing](https://mitxela.com/projects/scaffold) and the electronics that went into it, I though if other pieces of jewelry can be made with electronics (they can, it was specifically a question if my measly hands could craft them).
-
-
Since for the first time, I didn't want to experiment with absolute microscopic sizes, I decided that a 4 cm hoop was an adequate project to attempt.
-
-
![schematic_kicad_image](img/led_hoop/schematic.png =800x)
-
-
An Attiny 24/44/84A can be used, I went with a -M variant, since it is slightly larger then the -MM variant, by a whole mm, which I assume will be easier to solder.
-
-
Placing them all in a nice hoop looking pcb, we obtain this:
-
-
![pcb_kicad_image](/assets/img/led_hoop/pcb.svg)
-
-
The test version comes with ISP pins for debugging and programming the chip when it's already installed.
-
-
0603 LED's were chosen for the same reason, they are small enough to be not that noticeable, but large enough to be not an incredible pain to work with.
-
-
### Why??
-
-
It looked and sounded fun, my only previous projects related to PCB production before this was edition a split [Sweep](https://github.com/davidphilipbarr/Sweep) keyboard.
-
-
And so I did.
-
-
### Cool. What now?
-
-
You can take your chance and go to [the git repository](https://git.technoduck.me/technoduck/led_hoop) for the project, `git pull`, and try your own luck.
-
-
-
-
-
Batteries not included.
-
-16
posts/004-pantheon.md
···
-
---
-
title: Pantheon
-
date: 2024-03-03
-
---
-
# WATCH PANTHEON
-
-
## I DO NOT CARE WHAT DAY IT IS
-
-
### HERE'S YOUR PLAN
-
-
1. Wake up.
-
2. Open whatever device you watch things on.
-
3. Obtain, legally or illegaly, by any means necessary, 2 (two) seasons of Pantheon, created by Craig Silverstein based on short stories by Ken Liu.
-
4. Binge the 2 sesons in a single night (it is feasable I checked)
-
-
Thank you for coming to my Ted Talk.
-36
posts/005-regenesis.md
···
-
---
-
title: Full website Re-Update
-
date: 2024-08-29
-
---
-
## New Website?
-
-
### Rust
-
-
The time has come and another re-write is upon us.
-
-
This time inspied by [this article](https://blog.transrights.art/blogs/2024_Screw-Frameworks-New-Site-2),
-
[theprimeagen](https://www.youtube.com/watch?v=rcZSOLAI1lM), and everpresent desire to rewrite everything in Rust,
-
the new website is a complete rewrite using rust and adjacent techniques.
-
-
Using only
-
```
-
[dependencies]
-
askama = { version = "0.12.1", features = ["with-axum"] }
-
askama_axum = "0.4.0"
-
axum = "0.7.5"
-
comrak = "0.27.0"
-
markdown-parser = "0.1.2"
-
rand = "0.8.5"
-
serde = { version = "1.0.209", features = ["derive"] }
-
serde_yaml = "0.9.34"
-
tokio = { version = "1.39.3", features = ["macros", "rt-multi-thread"] }
-
tower-http = { version = "0.5.2", features = ["fs"] }
-
```
-
-
as dependancies in the end we get a clean~ish, 2.8MB executable.
-
-
All markdown compilation gets done every time page is loaded, which is sub-optimal,
-
But reading time for all posts is non-significant compared to other loading times.
-
-
And voila, there is the new post.
-
+4 -5
src/blog_entries.rs
···
use crate::structs::{BlogInfo, IndexPostEntry};
pub fn get_blog_entry_markdown(path:&String) -> Result<Markdown,Error> {
-
let location = format!("posts/{path}.md").to_string();
+
let location = format!("content/posts/{path}.md").to_string();
read_file(Path::new(&location))
}
pub fn get_all_markdowns() -> Vec<IndexPostEntry> {
let mut post_vec:Vec<IndexPostEntry> = Vec::new();
-
let mr_dir_iter = match read_dir("posts/") {
+
let mr_dir_iter = match read_dir("content/posts") {
Ok(iter) => iter,
-
Err(err) => panic!("could ls files, err {err}")
+
Err(err) => panic!("couldnt ls files, err {err}")
};
-
for entry in mr_dir_iter {
if let Ok(entry) = entry {
···
post_vec.push(IndexPostEntry{
title: front_matter.title,
date: front_matter.date,
-
path: format!("/blog/{filename}"),
+
path: format!("/blog/{filename}.html"),
});
}
+31 -18
src/handlers.rs
···
-
use axum::{extract::Path,response::Html};
use crate::structs::*;
use crate::rand_quote::get_quote;
use crate::blog_entries::{get_all_markdowns, get_blog_entry_markdown};
-
pub async fn index() -> Html<String> {
+
pub fn index() -> String {
let all_entries = get_all_markdowns();
let quote = get_quote();
let new_page = IndexTemplate { random_quote: quote, index_post_entries:&all_entries};
-
Html(new_page.to_string())
+
new_page.to_string()
}
-
pub async fn about() -> Html<String> {
-
-
let about_content = comrak::markdown_to_html("about", &comrak::Options::default());
+
pub fn about() -> String {
+
let about_markdown = markdown_parser::read_file("content/pages/about.md").expect("Could no find about.md file in content/pages/ folder");
+
let about_content = parse_markdown(about_markdown.content());
let page_content = AboutTemplate{about_content: &about_content};
-
Html(page_content.to_string())
+
page_content.to_string()
}
-
pub async fn blog(Path(blog_path):Path<String>) -> Html<String> {
+
pub fn blog(blog_path:String) -> String {
+
match get_blog_entry_markdown(&blog_path){
+
Ok(markdown) =>
+
BlogTemplate{
+
blog_content: &parse_markdown(markdown.content()),
+
front_matter:&serde_yaml::from_str(markdown.front_matter()).unwrap()}.to_string()
+
,
+
Err(..) => not_found(),
+
}
-
match get_blog_entry_markdown(&blog_path){
-
Ok(markdown) => Html(
-
BlogTemplate{
-
blog_content: &comrak::markdown_to_html(markdown.content(), &comrak::Options::default()),
-
front_matter:&serde_yaml::from_str(markdown.front_matter()).unwrap()}.to_string()
-
),
-
Err(..) => not_found().await,
-
}
+
}
+
pub fn not_found() -> String {
+
NotFoundTemplate{}.to_string()
}
-
pub async fn not_found() -> Html<String> {
-
Html(NotFoundTemplate{}.to_string())
+
+
fn parse_markdown(content: &str) -> String {
+
let mut options = comrak::Options::default();
+
+
options.extension.underline = true;
+
options.extension.strikethrough = true;
+
let mut plugins = comrak::Plugins::default();
+
let adapter = comrak::plugins::syntect::SyntectAdapterBuilder::new()
+
.theme("base16-mocha.dark")
+
.build();
+
+
plugins.render.codefence_syntax_highlighter = Some(&adapter);
+
comrak::markdown_to_html_with_plugins(content, &options, &plugins)
}
+59 -15
src/main.rs
···
-
use axum::{routing::get, Router};
-
use tower_http::services::{ServeDir, ServeFile};
-
+
use std::{fs::{write, read_dir, DirBuilder},path::Path};
mod handlers;
mod structs;
···
-
#[tokio::main]
-
async fn main() {
+
fn main() {
+
let output_path = "output";
+
match DirBuilder::new()
+
.recursive(true)
+
.create(output_path) {
+
Ok(()) => (),
+
Err(err) => if err.kind() == std::io::ErrorKind::AlreadyExists {
+
() // if folder already exists we can continue
+
} else {
+
panic!("Error detected: {err}")
+
}
+
}
-
let app: axum::Router = Router::new()
-
.route("/", get(handlers::index))
-
.route("/about", get(handlers::about))
-
.route("/blog",get(handlers::index))
-
.route("/blog/:blog_path",get(handlers::blog))
-
.route_service("/robots.txt", ServeFile::new("assets/robots.txt"))
-
.fallback(get(handlers::not_found))
-
.nest_service("/assets", ServeDir::new("assets"));
+
match copy_dir_all("assets", format!("{output_path}/assets")) {
+
Ok(()) => (),
+
Err(err) => println!("Couldnt copy assets directory, err: {err}"),
+
}
+
write(format!("{output_path}/index.html"), handlers::index().as_bytes()).expect("Couldnt write index file");
+
write(format!("{output_path}/about.html"), handlers::about().as_bytes()).expect("Couldnt write about file");
+
write(format!("{output_path}/404.html"), handlers::not_found().as_bytes()).expect("Couldnt write 404 file");
-
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000").await.unwrap();
-
axum::serve(listener, app).await.unwrap();
+
match DirBuilder::new()
+
.create(format!("{output_path}/blog")) {
+
Ok(()) => (),
+
Err(err) => if err.kind() == std::io::ErrorKind::AlreadyExists {
+
() // if folder already exists we can continue
+
} else {
+
panic!("Error detected: {err}")
+
}
+
}
+
+
+
let post_dir_iter = match read_dir("content/posts/") {
+
Ok(iter) => iter,
+
Err(err) => panic!("couldnt ls files, err {err}")
+
};
+
+
for entry in post_dir_iter {
+
if let Ok(entry) = entry {
+
+
let filename = entry.file_name().into_string().unwrap().split(".").collect::<Vec<_>>()[0].to_string();
+
+
write(format!("{output_path}/blog/{filename}.html"), handlers::blog(filename).as_bytes()).expect("Couldnt write blog entry");
+
};
+
+
}
+
+
}
+
fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> std::io::Result<()> {
+
std::fs::create_dir_all(&dst)?;
+
for entry in std::fs::read_dir(src)? {
+
let entry = entry?;
+
let ty = entry.file_type()?;
+
if ty.is_dir() {
+
copy_dir_all(entry.path(), dst.as_ref().join(entry.file_name()))?;
+
} else {
+
std::fs::copy(entry.path(), dst.as_ref().join(entry.file_name()))?;
+
}
+
}
+
Ok(())
}
+6 -1
src/rand_quote.rs
···
use rand::Rng;
+
/// Generates a random quote from a vec of &str present in the function body.
pub fn get_quote() -> &'static str {
+
// originally while dynamically server it would generate a new quote every time index would be
+
// reloaded, but with static serve nature a new quote is written every new build.
+
// Maybe not worth it.
+
// feel free to remove
let vs = vec![
"Silliness and tomfooler are afoot, and who am I to stop it.",
"Low entropy self replicating phenomenon that generates a binding force called compassion.",
···
"If there's a deal meant for you, any wild place on earth will do.",
"Live long and prosper.",
"Prometheus they say brought gods fire down to man and we've caught it tamed it trained it since our history began.",
-
"Oh, so, wenn PETER PARKER eine Reizรผberflutung hat, dann sind es \"Spidey-Sinne\", aber wenn ich es tue, ICH HABE AUTISM.",
"Guess we are doing Rust now",
+
"If we want the rewards of being loved we have to submit to the mortifying ordeal of being known."
];
let mut rng = rand::thread_rng();
match vs.get(rng.gen_range(0..vs.len())) {
-4
templates/about.html
···
{% block content %}
-
<h2> yepper yapper yapper</h2>
-
-
<p> this is an about page </p>
-
{{ about_content|safe }}
{% endblock %}
+4 -4
templates/layout.html
···
<link rel="stylesheet" href="https://unpkg.com/missing.css@1.1.2">
<link rel="stylesheet" href="/assets/old_style.css">
<link rel="icon" href="/assets/favicon.png" type="image/png" />
+
<link rel="me" href="https://infosec.exchange/@technoduck" />
</head>
<body>
···
<div class="table">
<div class="float:left">
<a href="/">Blog</a> |
-
<a href="https://git.technoduck.me" title="Git repository with some of my projects">Git</a> |
+
<a href="https://tangled.sh/@technoduck.me" title="Git repository with some of my projects">Git</a> |
<a href="https://cv.technoduck.me">Files</a> |
-
<a href="https://wip.technoduck.me">[WIP]</a> |
</div>
<div class="float:right">
-
<a href="/about">About</a> |
+
<a href="/about.html">About</a> |
<a href="assets/duck.asc">PGP</a> |
<a href="mailto:duck@technoduck.me">Mail</a>
</div>
···
<footer>
<h4>
-
Copyleft (c) 2022-2024 technoduck
+
Copyleft (c) 2022-2025 technoduck. Made with &#129414; in &#127464;&#127462;.
</h4>
<a href="https://yesterweb.org/no-to-web3/" target="_blank">
<img alt="a button that says 'keep the web free, say no to web3', linking to a page about web3" src="https://auzziejay.com/images/noweb32.gif">