1diff --git a/.gitignore b/.gitignore
2new file mode 100644
3index 0000000000000000000000000000000000000000..96ef862d54e5aa15d99a496109dfeca5def1163e
4--- /dev/null
5+++ b/.gitignore
6@@ -0,0 +1,2 @@
7+target/
8+.idea/
9diff --git a/Cargo.lock b/Cargo.lock
10new file mode 100644
11index 0000000000000000000000000000000000000000..d51075fd2fc1d0216c8a83c4629de538bf0762b3
12--- /dev/null
13+++ b/Cargo.lock
14@@ -0,0 +1,666 @@
15+# This file is automatically @generated by Cargo.
16+# It is not intended for manual editing.
17+version = 3
18+
19+[[package]]
20+name = "autocfg"
21+version = "1.1.0"
22+source = "registry+https://github.com/rust-lang/crates.io-index"
23+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
24+
25+[[package]]
26+name = "bitflags"
27+version = "1.3.2"
28+source = "registry+https://github.com/rust-lang/crates.io-index"
29+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
30+
31+[[package]]
32+name = "bytes"
33+version = "1.1.0"
34+source = "registry+https://github.com/rust-lang/crates.io-index"
35+checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
36+
37+[[package]]
38+name = "cfg-if"
39+version = "1.0.0"
40+source = "registry+https://github.com/rust-lang/crates.io-index"
41+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
42+
43+[[package]]
44+name = "filetime"
45+version = "0.2.16"
46+source = "registry+https://github.com/rust-lang/crates.io-index"
47+checksum = "c0408e2626025178a6a7f7ffc05a25bc47103229f19c113755de7bf63816290c"
48+dependencies = [
49+ "cfg-if",
50+ "libc",
51+ "redox_syscall",
52+ "winapi",
53+]
54+
55+[[package]]
56+name = "fnv"
57+version = "1.0.7"
58+source = "registry+https://github.com/rust-lang/crates.io-index"
59+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
60+
61+[[package]]
62+name = "futures-channel"
63+version = "0.3.21"
64+source = "registry+https://github.com/rust-lang/crates.io-index"
65+checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010"
66+dependencies = [
67+ "futures-core",
68+]
69+
70+[[package]]
71+name = "futures-core"
72+version = "0.3.21"
73+source = "registry+https://github.com/rust-lang/crates.io-index"
74+checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3"
75+
76+[[package]]
77+name = "futures-sink"
78+version = "0.3.21"
79+source = "registry+https://github.com/rust-lang/crates.io-index"
80+checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868"
81+
82+[[package]]
83+name = "futures-task"
84+version = "0.3.21"
85+source = "registry+https://github.com/rust-lang/crates.io-index"
86+checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a"
87+
88+[[package]]
89+name = "futures-util"
90+version = "0.3.21"
91+source = "registry+https://github.com/rust-lang/crates.io-index"
92+checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a"
93+dependencies = [
94+ "futures-core",
95+ "futures-task",
96+ "pin-project-lite",
97+ "pin-utils",
98+]
99+
100+[[package]]
101+name = "h2"
102+version = "0.3.13"
103+source = "registry+https://github.com/rust-lang/crates.io-index"
104+checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57"
105+dependencies = [
106+ "bytes",
107+ "fnv",
108+ "futures-core",
109+ "futures-sink",
110+ "futures-util",
111+ "http",
112+ "indexmap",
113+ "slab",
114+ "tokio",
115+ "tokio-util",
116+ "tracing",
117+]
118+
119+[[package]]
120+name = "hashbrown"
121+version = "0.11.2"
122+source = "registry+https://github.com/rust-lang/crates.io-index"
123+checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
124+
125+[[package]]
126+name = "hermit-abi"
127+version = "0.1.19"
128+source = "registry+https://github.com/rust-lang/crates.io-index"
129+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
130+dependencies = [
131+ "libc",
132+]
133+
134+[[package]]
135+name = "home"
136+version = "0.5.3"
137+source = "registry+https://github.com/rust-lang/crates.io-index"
138+checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654"
139+dependencies = [
140+ "winapi",
141+]
142+
143+[[package]]
144+name = "http"
145+version = "0.2.7"
146+source = "registry+https://github.com/rust-lang/crates.io-index"
147+checksum = "ff8670570af52249509a86f5e3e18a08c60b177071826898fde8997cf5f6bfbb"
148+dependencies = [
149+ "bytes",
150+ "fnv",
151+ "itoa",
152+]
153+
154+[[package]]
155+name = "http-body"
156+version = "0.4.4"
157+source = "registry+https://github.com/rust-lang/crates.io-index"
158+checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6"
159+dependencies = [
160+ "bytes",
161+ "http",
162+ "pin-project-lite",
163+]
164+
165+[[package]]
166+name = "httparse"
167+version = "1.7.1"
168+source = "registry+https://github.com/rust-lang/crates.io-index"
169+checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c"
170+
171+[[package]]
172+name = "httpdate"
173+version = "1.0.2"
174+source = "registry+https://github.com/rust-lang/crates.io-index"
175+checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
176+
177+[[package]]
178+name = "hyper"
179+version = "0.14.18"
180+source = "registry+https://github.com/rust-lang/crates.io-index"
181+checksum = "b26ae0a80afebe130861d90abf98e3814a4f28a4c6ffeb5ab8ebb2be311e0ef2"
182+dependencies = [
183+ "bytes",
184+ "futures-channel",
185+ "futures-core",
186+ "futures-util",
187+ "h2",
188+ "http",
189+ "http-body",
190+ "httparse",
191+ "httpdate",
192+ "itoa",
193+ "pin-project-lite",
194+ "socket2",
195+ "tokio",
196+ "tower-service",
197+ "tracing",
198+ "want",
199+]
200+
201+[[package]]
202+name = "indexmap"
203+version = "1.8.1"
204+source = "registry+https://github.com/rust-lang/crates.io-index"
205+checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee"
206+dependencies = [
207+ "autocfg",
208+ "hashbrown",
209+]
210+
211+[[package]]
212+name = "itoa"
213+version = "1.0.1"
214+source = "registry+https://github.com/rust-lang/crates.io-index"
215+checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
216+
217+[[package]]
218+name = "itoap"
219+version = "1.0.1"
220+source = "registry+https://github.com/rust-lang/crates.io-index"
221+checksum = "9028f49264629065d057f340a86acb84867925865f73bbf8d47b4d149a7e88b8"
222+
223+[[package]]
224+name = "lazy_static"
225+version = "1.4.0"
226+source = "registry+https://github.com/rust-lang/crates.io-index"
227+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
228+
229+[[package]]
230+name = "libc"
231+version = "0.2.125"
232+source = "registry+https://github.com/rust-lang/crates.io-index"
233+checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b"
234+
235+[[package]]
236+name = "lock_api"
237+version = "0.4.7"
238+source = "registry+https://github.com/rust-lang/crates.io-index"
239+checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53"
240+dependencies = [
241+ "autocfg",
242+ "scopeguard",
243+]
244+
245+[[package]]
246+name = "log"
247+version = "0.4.17"
248+source = "registry+https://github.com/rust-lang/crates.io-index"
249+checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
250+dependencies = [
251+ "cfg-if",
252+]
253+
254+[[package]]
255+name = "macroblog"
256+version = "0.1.0"
257+dependencies = [
258+ "hyper",
259+ "sailfish",
260+ "tokio",
261+]
262+
263+[[package]]
264+name = "memchr"
265+version = "2.5.0"
266+source = "registry+https://github.com/rust-lang/crates.io-index"
267+checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
268+
269+[[package]]
270+name = "mio"
271+version = "0.8.2"
272+source = "registry+https://github.com/rust-lang/crates.io-index"
273+checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9"
274+dependencies = [
275+ "libc",
276+ "log",
277+ "miow",
278+ "ntapi",
279+ "wasi",
280+ "winapi",
281+]
282+
283+[[package]]
284+name = "miow"
285+version = "0.3.7"
286+source = "registry+https://github.com/rust-lang/crates.io-index"
287+checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
288+dependencies = [
289+ "winapi",
290+]
291+
292+[[package]]
293+name = "ntapi"
294+version = "0.3.7"
295+source = "registry+https://github.com/rust-lang/crates.io-index"
296+checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f"
297+dependencies = [
298+ "winapi",
299+]
300+
301+[[package]]
302+name = "num_cpus"
303+version = "1.13.1"
304+source = "registry+https://github.com/rust-lang/crates.io-index"
305+checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
306+dependencies = [
307+ "hermit-abi",
308+ "libc",
309+]
310+
311+[[package]]
312+name = "once_cell"
313+version = "1.10.0"
314+source = "registry+https://github.com/rust-lang/crates.io-index"
315+checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
316+
317+[[package]]
318+name = "parking_lot"
319+version = "0.12.0"
320+source = "registry+https://github.com/rust-lang/crates.io-index"
321+checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58"
322+dependencies = [
323+ "lock_api",
324+ "parking_lot_core",
325+]
326+
327+[[package]]
328+name = "parking_lot_core"
329+version = "0.9.3"
330+source = "registry+https://github.com/rust-lang/crates.io-index"
331+checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929"
332+dependencies = [
333+ "cfg-if",
334+ "libc",
335+ "redox_syscall",
336+ "smallvec",
337+ "windows-sys",
338+]
339+
340+[[package]]
341+name = "pin-project-lite"
342+version = "0.2.9"
343+source = "registry+https://github.com/rust-lang/crates.io-index"
344+checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
345+
346+[[package]]
347+name = "pin-utils"
348+version = "0.1.0"
349+source = "registry+https://github.com/rust-lang/crates.io-index"
350+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
351+
352+[[package]]
353+name = "proc-macro2"
354+version = "1.0.36"
355+source = "registry+https://github.com/rust-lang/crates.io-index"
356+checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
357+dependencies = [
358+ "unicode-xid",
359+]
360+
361+[[package]]
362+name = "quote"
363+version = "1.0.18"
364+source = "registry+https://github.com/rust-lang/crates.io-index"
365+checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
366+dependencies = [
367+ "proc-macro2",
368+]
369+
370+[[package]]
371+name = "redox_syscall"
372+version = "0.2.13"
373+source = "registry+https://github.com/rust-lang/crates.io-index"
374+checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
375+dependencies = [
376+ "bitflags",
377+]
378+
379+[[package]]
380+name = "ryu"
381+version = "1.0.9"
382+source = "registry+https://github.com/rust-lang/crates.io-index"
383+checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
384+
385+[[package]]
386+name = "sailfish"
387+version = "0.4.0"
388+source = "registry+https://github.com/rust-lang/crates.io-index"
389+checksum = "948a7edfc2f03d7c58a097dda25ed29440a72e8528894a6e182fe9171195fed1"
390+dependencies = [
391+ "itoap",
392+ "ryu",
393+ "sailfish-macros",
394+ "version_check",
395+]
396+
397+[[package]]
398+name = "sailfish-compiler"
399+version = "0.4.0"
400+source = "registry+https://github.com/rust-lang/crates.io-index"
401+checksum = "3f0a01133d6ce146020e6416ac6a823f813f1cbb30ff77548b4fa20749524947"
402+dependencies = [
403+ "filetime",
404+ "home",
405+ "memchr",
406+ "proc-macro2",
407+ "quote",
408+ "serde",
409+ "syn",
410+ "toml",
411+]
412+
413+[[package]]
414+name = "sailfish-macros"
415+version = "0.4.0"
416+source = "registry+https://github.com/rust-lang/crates.io-index"
417+checksum = "86326c1f1dce0b316e0a47071f683b185417dc64e1a704380b5c706b09e871b1"
418+dependencies = [
419+ "proc-macro2",
420+ "sailfish-compiler",
421+]
422+
423+[[package]]
424+name = "scopeguard"
425+version = "1.1.0"
426+source = "registry+https://github.com/rust-lang/crates.io-index"
427+checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
428+
429+[[package]]
430+name = "serde"
431+version = "1.0.137"
432+source = "registry+https://github.com/rust-lang/crates.io-index"
433+checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
434+dependencies = [
435+ "serde_derive",
436+]
437+
438+[[package]]
439+name = "serde_derive"
440+version = "1.0.137"
441+source = "registry+https://github.com/rust-lang/crates.io-index"
442+checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be"
443+dependencies = [
444+ "proc-macro2",
445+ "quote",
446+ "syn",
447+]
448+
449+[[package]]
450+name = "signal-hook-registry"
451+version = "1.4.0"
452+source = "registry+https://github.com/rust-lang/crates.io-index"
453+checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
454+dependencies = [
455+ "libc",
456+]
457+
458+[[package]]
459+name = "slab"
460+version = "0.4.6"
461+source = "registry+https://github.com/rust-lang/crates.io-index"
462+checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32"
463+
464+[[package]]
465+name = "smallvec"
466+version = "1.8.0"
467+source = "registry+https://github.com/rust-lang/crates.io-index"
468+checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
469+
470+[[package]]
471+name = "socket2"
472+version = "0.4.4"
473+source = "registry+https://github.com/rust-lang/crates.io-index"
474+checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0"
475+dependencies = [
476+ "libc",
477+ "winapi",
478+]
479+
480+[[package]]
481+name = "syn"
482+version = "1.0.92"
483+source = "registry+https://github.com/rust-lang/crates.io-index"
484+checksum = "7ff7c592601f11445996a06f8ad0c27f094a58857c2f89e97974ab9235b92c52"
485+dependencies = [
486+ "proc-macro2",
487+ "quote",
488+ "unicode-xid",
489+]
490+
491+[[package]]
492+name = "tokio"
493+version = "1.18.1"
494+source = "registry+https://github.com/rust-lang/crates.io-index"
495+checksum = "dce653fb475565de9f6fb0614b28bca8df2c430c0cf84bcd9c843f15de5414cc"
496+dependencies = [
497+ "bytes",
498+ "libc",
499+ "memchr",
500+ "mio",
501+ "num_cpus",
502+ "once_cell",
503+ "parking_lot",
504+ "pin-project-lite",
505+ "signal-hook-registry",
506+ "socket2",
507+ "tokio-macros",
508+ "winapi",
509+]
510+
511+[[package]]
512+name = "tokio-macros"
513+version = "1.7.0"
514+source = "registry+https://github.com/rust-lang/crates.io-index"
515+checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7"
516+dependencies = [
517+ "proc-macro2",
518+ "quote",
519+ "syn",
520+]
521+
522+[[package]]
523+name = "tokio-util"
524+version = "0.7.1"
525+source = "registry+https://github.com/rust-lang/crates.io-index"
526+checksum = "0edfdeb067411dba2044da6d1cb2df793dd35add7888d73c16e3381ded401764"
527+dependencies = [
528+ "bytes",
529+ "futures-core",
530+ "futures-sink",
531+ "pin-project-lite",
532+ "tokio",
533+ "tracing",
534+]
535+
536+[[package]]
537+name = "toml"
538+version = "0.5.9"
539+source = "registry+https://github.com/rust-lang/crates.io-index"
540+checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
541+dependencies = [
542+ "serde",
543+]
544+
545+[[package]]
546+name = "tower-service"
547+version = "0.3.1"
548+source = "registry+https://github.com/rust-lang/crates.io-index"
549+checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
550+
551+[[package]]
552+name = "tracing"
553+version = "0.1.34"
554+source = "registry+https://github.com/rust-lang/crates.io-index"
555+checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09"
556+dependencies = [
557+ "cfg-if",
558+ "pin-project-lite",
559+ "tracing-attributes",
560+ "tracing-core",
561+]
562+
563+[[package]]
564+name = "tracing-attributes"
565+version = "0.1.21"
566+source = "registry+https://github.com/rust-lang/crates.io-index"
567+checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c"
568+dependencies = [
569+ "proc-macro2",
570+ "quote",
571+ "syn",
572+]
573+
574+[[package]]
575+name = "tracing-core"
576+version = "0.1.26"
577+source = "registry+https://github.com/rust-lang/crates.io-index"
578+checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f"
579+dependencies = [
580+ "lazy_static",
581+]
582+
583+[[package]]
584+name = "try-lock"
585+version = "0.2.3"
586+source = "registry+https://github.com/rust-lang/crates.io-index"
587+checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
588+
589+[[package]]
590+name = "unicode-xid"
591+version = "0.2.3"
592+source = "registry+https://github.com/rust-lang/crates.io-index"
593+checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
594+
595+[[package]]
596+name = "version_check"
597+version = "0.9.4"
598+source = "registry+https://github.com/rust-lang/crates.io-index"
599+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
600+
601+[[package]]
602+name = "want"
603+version = "0.3.0"
604+source = "registry+https://github.com/rust-lang/crates.io-index"
605+checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
606+dependencies = [
607+ "log",
608+ "try-lock",
609+]
610+
611+[[package]]
612+name = "wasi"
613+version = "0.11.0+wasi-snapshot-preview1"
614+source = "registry+https://github.com/rust-lang/crates.io-index"
615+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
616+
617+[[package]]
618+name = "winapi"
619+version = "0.3.9"
620+source = "registry+https://github.com/rust-lang/crates.io-index"
621+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
622+dependencies = [
623+ "winapi-i686-pc-windows-gnu",
624+ "winapi-x86_64-pc-windows-gnu",
625+]
626+
627+[[package]]
628+name = "winapi-i686-pc-windows-gnu"
629+version = "0.4.0"
630+source = "registry+https://github.com/rust-lang/crates.io-index"
631+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
632+
633+[[package]]
634+name = "winapi-x86_64-pc-windows-gnu"
635+version = "0.4.0"
636+source = "registry+https://github.com/rust-lang/crates.io-index"
637+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
638+
639+[[package]]
640+name = "windows-sys"
641+version = "0.36.1"
642+source = "registry+https://github.com/rust-lang/crates.io-index"
643+checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
644+dependencies = [
645+ "windows_aarch64_msvc",
646+ "windows_i686_gnu",
647+ "windows_i686_msvc",
648+ "windows_x86_64_gnu",
649+ "windows_x86_64_msvc",
650+]
651+
652+[[package]]
653+name = "windows_aarch64_msvc"
654+version = "0.36.1"
655+source = "registry+https://github.com/rust-lang/crates.io-index"
656+checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
657+
658+[[package]]
659+name = "windows_i686_gnu"
660+version = "0.36.1"
661+source = "registry+https://github.com/rust-lang/crates.io-index"
662+checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
663+
664+[[package]]
665+name = "windows_i686_msvc"
666+version = "0.36.1"
667+source = "registry+https://github.com/rust-lang/crates.io-index"
668+checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
669+
670+[[package]]
671+name = "windows_x86_64_gnu"
672+version = "0.36.1"
673+source = "registry+https://github.com/rust-lang/crates.io-index"
674+checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
675+
676+[[package]]
677+name = "windows_x86_64_msvc"
678+version = "0.36.1"
679+source = "registry+https://github.com/rust-lang/crates.io-index"
680+checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
681diff --git a/Cargo.toml b/Cargo.toml
682new file mode 100644
683index 0000000000000000000000000000000000000000..ecaba6d87d613106a7d5a542fd9e75529569d9f9
684--- /dev/null
685+++ b/Cargo.toml
686@@ -0,0 +1,16 @@
687+[package]
688+name = "macroblog"
689+version = "0.1.0"
690+edition = "2021"
691+
692+[dependencies]
693+sailfish = "0.4.0"
694+hyper = { version = "0.14", features = ["full"] }
695+tokio = { version = "1", features = ["full"] }
696+
697+[profile.release]
698+opt-level = 'z'
699+lto = true
700+codegen-units = 1
701+panic = 'abort'
702+strip = true
703diff --git a/README.md b/README.md
704new file mode 100644
705index 0000000000000000000000000000000000000000..d2a4851dcc7ef2757fc7d53f4dbab56708e565f0
706--- /dev/null
707+++ b/README.md
708@@ -0,0 +1,11 @@
709+# A single binary blob
710+
711+After reading [this article](https://www.andreinc.net/2022/04/10/a-blog-that-is-a-single-executable-binary) by Andrei
712+Ciobanu it sparkled in me to do the same thing but with rust.
713+
714+To achieve that I'll be using the following:
715+
716+- Sailfish for templating
717+- hyper for http server
718+- rust-embed for adding the files into the binary.
719+
720diff --git a/assets/pico.min.css b/assets/pico.min.css
721new file mode 100644
722index 0000000000000000000000000000000000000000..1179471453b3bb57f3935f37166f7f8a05655fb3
723--- /dev/null
724+++ b/assets/pico.min.css
725@@ -0,0 +1,888 @@
726+@charset "UTF-8";
727+:root {
728+ --font-family: system-ui, -apple-system, "Segoe UI", "Roboto", "Ubuntu", "Cantarell", "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
729+ --line-height: 1.5;
730+ --font-weight: 400;
731+ --font-size: 16px;
732+ --border-radius: 0.25rem;
733+ --border-width: 1px;
734+ --outline-width: 3px;
735+ --spacing: 1rem;
736+ --typography-spacing-vertical: 1.5rem;
737+ --block-spacing-vertical: calc(var(--spacing) * 2);
738+ --block-spacing-horizontal: var(--spacing);
739+ --grid-spacing-vertical: 0;
740+ --grid-spacing-horizontal: var(--spacing);
741+ --form-element-spacing-vertical: 0.75rem;
742+ --form-element-spacing-horizontal: 1rem;
743+ --nav-element-spacing-vertical: 1rem;
744+ --nav-element-spacing-horizontal: 0.5rem;
745+ --nav-link-spacing-vertical: 0.5rem;
746+ --nav-link-spacing-horizontal: 0.5rem;
747+ --form-label-font-weight: var(--font-weight);
748+ --transition: 0.2s ease-in-out
749+}
750+
751+@media (min-width: 576px) {
752+ :root {
753+ --font-size: 17px
754+ }
755+}
756+
757+@media (min-width: 768px) {
758+ :root {
759+ --font-size: 18px
760+ }
761+}
762+
763+@media (min-width: 992px) {
764+ :root {
765+ --font-size: 19px
766+ }
767+}
768+
769+@media (min-width: 1200px) {
770+ :root {
771+ --font-size: 20px
772+ }
773+}
774+
775+@media (min-width: 576px) {
776+ body > footer, body > header, body > main, section {
777+ --block-spacing-vertical: calc(var(--spacing) * 2.5)
778+ }
779+}
780+
781+@media (min-width: 768px) {
782+ body > footer, body > header, body > main, section {
783+ --block-spacing-vertical: calc(var(--spacing) * 3)
784+ }
785+}
786+
787+@media (min-width: 992px) {
788+ body > footer, body > header, body > main, section {
789+ --block-spacing-vertical: calc(var(--spacing) * 3.5)
790+ }
791+}
792+
793+@media (min-width: 1200px) {
794+ body > footer, body > header, body > main, section {
795+ --block-spacing-vertical: calc(var(--spacing) * 4)
796+ }
797+}
798+
799+@media (min-width: 576px) {
800+ article {
801+ --block-spacing-horizontal: calc(var(--spacing) * 1.25)
802+ }
803+}
804+
805+@media (min-width: 768px) {
806+ article {
807+ --block-spacing-horizontal: calc(var(--spacing) * 1.5)
808+ }
809+}
810+
811+@media (min-width: 992px) {
812+ article {
813+ --block-spacing-horizontal: calc(var(--spacing) * 1.75)
814+ }
815+}
816+
817+@media (min-width: 1200px) {
818+ article {
819+ --block-spacing-horizontal: calc(var(--spacing) * 2)
820+ }
821+}
822+
823+a {
824+ --text-decoration: none
825+}
826+
827+h1, h2, h3, h4, h5, h6 {
828+ --font-weight: 700
829+}
830+
831+h1 {
832+ --font-size: 2rem;
833+ --typography-spacing-vertical: 3rem
834+}
835+
836+h2 {
837+ --font-size: 1.75rem;
838+ --typography-spacing-vertical: 2.625rem
839+}
840+
841+h3 {
842+ --font-size: 1.5rem;
843+ --typography-spacing-vertical: 2.25rem
844+}
845+
846+h4 {
847+ --font-size: 1.25rem;
848+ --typography-spacing-vertical: 1.874rem
849+}
850+
851+h5 {
852+ --font-size: 1.125rem;
853+ --typography-spacing-vertical: 1.6875rem
854+}
855+
856+:root:not([data-theme=dark]), [data-theme=light] {
857+ color-scheme: light;
858+ --background-color: #fff;
859+ --color: #415462;
860+ --h1-color: #1b2832;
861+ --h2-color: #24333e;
862+ --h3-color: #2c3d49;
863+ --h4-color: #374956;
864+ --h5-color: #415462;
865+ --h6-color: #4d606d;
866+ --muted-color: #73828c;
867+ --muted-border-color: #edf0f3;
868+ --primary: #1095c1;
869+ --primary-hover: #08769b;
870+ --primary-focus: rgba(16, 149, 193, 0.125);
871+ --primary-inverse: #fff;
872+ --secondary: #596b78;
873+ --secondary-hover: #415462;
874+ --secondary-focus: rgba(89, 107, 120, 0.125);
875+ --secondary-inverse: #fff;
876+ --contrast: #1b2832;
877+ --contrast-hover: #000;
878+ --contrast-focus: rgba(89, 107, 120, 0.125);
879+ --contrast-inverse: #fff;
880+ --mark-background-color: #fff2ca;
881+ --mark-color: #543a26;
882+ --ins-color: #388e3c;
883+ --del-color: #c62828;
884+ --blockquote-border-color: var(--muted-border-color);
885+ --blockquote-footer-color: var(--muted-color);
886+ --button-box-shadow: 0 0 0 rgba(0, 0, 0, 0);
887+ --button-hover-box-shadow: 0 0 0 rgba(0, 0, 0, 0);
888+ --form-element-background-color: transparent;
889+ --form-element-border-color: #a2afb9;
890+ --form-element-color: var(--color);
891+ --form-element-placeholder-color: var(--muted-color);
892+ --form-element-active-background-color: transparent;
893+ --form-element-active-border-color: var(--primary);
894+ --form-element-focus-color: var(--primary-focus);
895+ --form-element-disabled-background-color: #d5dce2;
896+ --form-element-disabled-border-color: #a2afb9;
897+ --form-element-disabled-opacity: 0.5;
898+ --form-element-invalid-border-color: #c62828;
899+ --form-element-invalid-active-border-color: #d32f2f;
900+ --form-element-invalid-focus-color: rgba(211, 47, 47, 0.125);
901+ --form-element-valid-border-color: #388e3c;
902+ --form-element-valid-active-border-color: #43a047;
903+ --form-element-valid-focus-color: rgba(67, 160, 71, 0.125);
904+ --switch-background-color: #bbc6ce;
905+ --switch-color: var(--primary-inverse);
906+ --switch-checked-background-color: var(--primary);
907+ --range-border-color: #d5dce2;
908+ --range-active-border-color: #bbc6ce;
909+ --range-thumb-border-color: var(--background-color);
910+ --range-thumb-color: var(--secondary);
911+ --range-thumb-hover-color: var(--secondary-hover);
912+ --range-thumb-active-color: var(--primary);
913+ --table-border-color: var(--muted-border-color);
914+ --table-row-stripped-background-color: #f6f8f9;
915+ --code-background-color: #edf0f3;
916+ --code-color: var(--muted-color);
917+ --code-kbd-background-color: var(--contrast);
918+ --code-kbd-color: var(--contrast-inverse);
919+ --code-tag-color: #b34d80;
920+ --code-property-color: #3d888f;
921+ --code-value-color: #998866;
922+ --code-comment-color: #a2afb9;
923+ --accordion-border-color: var(--muted-border-color);
924+ --accordion-close-summary-color: var(--color);
925+ --accordion-open-summary-color: var(--muted-color);
926+ --card-background-color: var(--background-color);
927+ --card-border-color: var(--muted-border-color);
928+ --card-box-shadow: 0 0.125rem 1rem rgba(27, 40, 50, 0.04), 0 0.125rem 2rem rgba(27, 40, 50, 0.08), 0 0 0 0.0625rem rgba(27, 40, 50, 0.024);
929+ --card-sectionning-background-color: #fbfbfc;
930+ --dropdown-background-color: #fbfbfc;
931+ --dropdown-border-color: #e1e6eb;
932+ --dropdown-box-shadow: var(--card-box-shadow);
933+ --dropdown-color: var(--color);
934+ --dropdown-hover-background-color: #edf0f3;
935+ --modal-overlay-background-color: rgba(213, 220, 226, 0.8);
936+ --progress-background-color: #d5dce2;
937+ --progress-color: var(--primary);
938+ --loading-spinner-opacity: 0.5;
939+ --tooltip-background-color: var(--contrast);
940+ --tooltip-color: var(--contrast-inverse);
941+ --icon-checkbox: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23FFF' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E");
942+ --icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgba(65, 84, 98, 0.999)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
943+ --icon-chevron-button: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgba(255, 255, 255, 0.999)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
944+ --icon-chevron-button-inverse: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgba(255, 255, 255, 0.999)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
945+ --icon-close: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgba(115, 130, 140, 0.999)' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'%3E%3C/line%3E%3Cline x1='6' y1='6' x2='18' y2='18'%3E%3C/line%3E%3C/svg%3E");
946+ --icon-date: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgba(65, 84, 98, 0.999)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E");
947+ --icon-invalid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgba(198, 40, 40, 0.999)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E");
948+ --icon-minus: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23FFF' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='5' y1='12' x2='19' y2='12'%3E%3C/line%3E%3C/svg%3E");
949+ --icon-search: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgba(65, 84, 98, 0.999)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E");
950+ --icon-time: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgba(65, 84, 98, 0.999)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cpolyline points='12 6 12 12 16 14'%3E%3C/polyline%3E%3C/svg%3E");
951+ --icon-valid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgba(56, 142, 60, 0.999)' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E")
952+}
953+
954+*, ::after, ::before {
955+ box-sizing: border-box;
956+ background-repeat: no-repeat
957+}
958+
959+::after, ::before {
960+ text-decoration: inherit;
961+ vertical-align: inherit
962+}
963+
964+:where(:root) {
965+ -webkit-tap-highlight-color: transparent;
966+ -webkit-text-size-adjust: 100%;
967+ -moz-text-size-adjust: 100%;
968+ text-size-adjust: 100%;
969+ text-rendering: optimizeLegibility;
970+ background-color: var(--background-color);
971+ color: var(--color);
972+ font-weight: var(--font-weight);
973+ font-size: var(--font-size);
974+ line-height: var(--line-height);
975+ font-family: var(--font-family);
976+ overflow-wrap: break-word;
977+ cursor: default;
978+ -moz-tab-size: 4;
979+ -o-tab-size: 4;
980+ tab-size: 4
981+}
982+
983+main {
984+ display: block
985+}
986+
987+body {
988+ width: 100%;
989+ margin: 0
990+}
991+
992+body > footer, body > header, body > main {
993+ width: 100%;
994+ margin-right: auto;
995+ margin-left: auto;
996+ padding: 1rem
997+}
998+
999+.container, .container-fluid {
1000+ width: 100%;
1001+ margin-right: auto;
1002+ margin-left: auto;
1003+ padding-right: var(--spacing);
1004+ padding-left: var(--spacing)
1005+}
1006+
1007+@media (min-width: 576px) {
1008+ .container {
1009+ max-width: 510px;
1010+ padding-right: 0;
1011+ padding-left: 0
1012+ }
1013+}
1014+
1015+@media (min-width: 768px) {
1016+ .container {
1017+ max-width: 700px
1018+ }
1019+}
1020+
1021+@media (min-width: 992px) {
1022+ .container {
1023+ max-width: 800px
1024+ }
1025+}
1026+
1027+section {
1028+ margin-bottom: var(--block-spacing-vertical)
1029+}
1030+
1031+.grid {
1032+ grid-column-gap: var(--grid-spacing-horizontal);
1033+ grid-row-gap: var(--grid-spacing-vertical);
1034+ display: grid;
1035+ grid-template-columns:1fr;
1036+ margin: 0
1037+}
1038+
1039+@media (min-width: 992px) {
1040+ .grid {
1041+ grid-template-columns:repeat(auto-fit, minmax(0%, 1fr))
1042+ }
1043+}
1044+
1045+.grid > * {
1046+ min-width: 0
1047+}
1048+
1049+b, strong {
1050+ font-weight: bolder
1051+}
1052+
1053+address, blockquote, dl, figure, form, ol, p, pre, table, ul {
1054+ margin-top: 0;
1055+ margin-bottom: var(--typography-spacing-vertical);
1056+ color: var(--color);
1057+ font-style: normal;
1058+ font-weight: var(--font-weight);
1059+ font-size: var(--font-size)
1060+}
1061+
1062+[role=link], a {
1063+ --color: var(--primary);
1064+ --background-color: transparent;
1065+ outline: 0;
1066+ background-color: var(--background-color);
1067+ color: var(--color);
1068+ -webkit-text-decoration: var(--text-decoration);
1069+ text-decoration: var(--text-decoration);
1070+ transition: background-color var(--transition), color var(--transition), box-shadow var(--transition), -webkit-text-decoration var(--transition);
1071+ transition: background-color var(--transition), color var(--transition), text-decoration var(--transition), box-shadow var(--transition);
1072+ transition: background-color var(--transition), color var(--transition), text-decoration var(--transition), box-shadow var(--transition), -webkit-text-decoration var(--transition)
1073+}
1074+
1075+[role=link]:is([aria-current],:hover,:active,:focus), a:is([aria-current],:hover,:active,:focus) {
1076+ --color: var(--primary-hover);
1077+ --text-decoration: underline
1078+}
1079+
1080+[role=link]:focus, a:focus {
1081+ --background-color: var(--primary-focus)
1082+}
1083+
1084+[role=link].secondary, a.secondary {
1085+ --color: var(--secondary)
1086+}
1087+
1088+[role=link].secondary:is([aria-current],:hover,:active,:focus), a.secondary:is([aria-current],:hover,:active,:focus) {
1089+ --color: var(--secondary-hover)
1090+}
1091+
1092+[role=link].secondary:focus, a.secondary:focus {
1093+ --background-color: var(--secondary-focus)
1094+}
1095+
1096+[role=link].contrast, a.contrast {
1097+ --color: var(--contrast)
1098+}
1099+
1100+[role=link].contrast:is([aria-current],:hover,:active,:focus), a.contrast:is([aria-current],:hover,:active,:focus) {
1101+ --color: var(--contrast-hover)
1102+}
1103+
1104+[role=link].contrast:focus, a.contrast:focus {
1105+ --background-color: var(--contrast-focus)
1106+}
1107+
1108+h1, h2, h3, h4, h5, h6 {
1109+ margin-top: 0;
1110+ margin-bottom: var(--typography-spacing-vertical);
1111+ color: var(--color);
1112+ font-weight: var(--font-weight);
1113+ font-size: var(--font-size);
1114+ font-family: var(--font-family)
1115+}
1116+
1117+h1 {
1118+ --color: var(--h1-color)
1119+}
1120+
1121+h2 {
1122+ --color: var(--h2-color)
1123+}
1124+
1125+h3 {
1126+ --color: var(--h3-color)
1127+}
1128+
1129+h4 {
1130+ --color: var(--h4-color)
1131+}
1132+
1133+h5 {
1134+ --color: var(--h5-color)
1135+}
1136+
1137+h6 {
1138+ --color: var(--h6-color)
1139+}
1140+
1141+:where(address,blockquote,dl,figure,form,ol,p,pre,table,ul) ~ :is(h1,h2,h3,h4,h5,h6) {
1142+ margin-top: var(--typography-spacing-vertical)
1143+}
1144+
1145+.headings, hgroup {
1146+ margin-bottom: var(--typography-spacing-vertical)
1147+}
1148+
1149+.headings > *, hgroup > * {
1150+ margin-bottom: 0
1151+}
1152+
1153+.headings > :last-child, hgroup > :last-child {
1154+ --color: var(--muted-color);
1155+ --font-weight: unset;
1156+ font-size: 1rem;
1157+ font-family: unset
1158+}
1159+
1160+p {
1161+ margin-bottom: var(--typography-spacing-vertical)
1162+}
1163+
1164+:where(dl,ol,ul) {
1165+ padding-right: 0;
1166+ padding-left: var(--spacing);
1167+ -webkit-padding-start: var(--spacing);
1168+ padding-inline-start: var(--spacing);
1169+ -webkit-padding-end: 0;
1170+ padding-inline-end: 0
1171+}
1172+
1173+:where(dl,ol,ul) li {
1174+ margin-bottom: calc(var(--typography-spacing-vertical) * .25)
1175+}
1176+
1177+:where(dl,ol,ul):is(dl,ol,ul) {
1178+ margin: calc(var(--typography-spacing-vertical) * .25) 0 0
1179+}
1180+
1181+ul li {
1182+ list-style: none
1183+}
1184+
1185+mark {
1186+ padding: 0.125rem 0.25rem;
1187+ background-color: var(--mark-background-color);
1188+ color: var(--mark-color);
1189+ vertical-align: baseline
1190+}
1191+
1192+abbr[title] {
1193+ border-bottom: 1px dotted;
1194+ text-decoration: none;
1195+ cursor: help
1196+}
1197+
1198+::-moz-selection {
1199+ background-color: var(--primary-focus)
1200+}
1201+
1202+::selection {
1203+ background-color: var(--primary-focus)
1204+}
1205+
1206+:where(audio,canvas,iframe,img,svg,video) {
1207+ vertical-align: middle
1208+}
1209+
1210+legend {
1211+ max-width: 100%;
1212+ padding: 0;
1213+ color: inherit;
1214+ white-space: normal
1215+}
1216+
1217+::-webkit-inner-spin-button, ::-webkit-outer-spin-button {
1218+ height: auto
1219+}
1220+
1221+fieldset legend, label {
1222+ display: block;
1223+ margin-bottom: calc(var(--spacing) * .25);
1224+ font-weight: var(--form-label-font-weight, var(--font-weight))
1225+}
1226+
1227+[type=color]::-webkit-color-swatch-wrapper {
1228+ padding: 0
1229+}
1230+
1231+code, kbd, pre, samp {
1232+ font-size: 0.875em;
1233+ font-family: var(--font-family)
1234+}
1235+
1236+pre {
1237+ -ms-overflow-style: scrollbar;
1238+ overflow: auto
1239+}
1240+
1241+code, kbd, pre {
1242+ border-radius: var(--border-radius);
1243+ background: var(--code-background-color);
1244+ color: var(--code-color);
1245+ font-weight: var(--font-weight);
1246+ line-height: initial
1247+}
1248+
1249+code, kbd {
1250+ display: inline-block;
1251+ padding: 0.375rem 0.5rem
1252+}
1253+
1254+pre {
1255+ display: block;
1256+ margin-bottom: var(--spacing);
1257+ overflow-x: auto
1258+}
1259+
1260+pre > code {
1261+ display: block;
1262+ padding: var(--spacing);
1263+ background: 0 0;
1264+ font-size: 14px;
1265+ line-height: var(--line-height)
1266+}
1267+
1268+code b {
1269+ color: var(--code-tag-color);
1270+ font-weight: var(--font-weight)
1271+}
1272+
1273+code i {
1274+ color: var(--code-property-color);
1275+ font-style: normal
1276+}
1277+
1278+code u {
1279+ color: var(--code-value-color);
1280+ text-decoration: none
1281+}
1282+
1283+code em {
1284+ color: var(--code-comment-color);
1285+ font-style: normal
1286+}
1287+
1288+kbd {
1289+ background-color: var(--code-kbd-background-color);
1290+ color: var(--code-kbd-color);
1291+ vertical-align: baseline
1292+}
1293+
1294+hr {
1295+ height: 0;
1296+ border: 0;
1297+ border-top: 1px solid var(--muted-border-color);
1298+ color: inherit
1299+}
1300+
1301+[hidden], template {
1302+ display: none !important
1303+}
1304+
1305+article {
1306+ margin: var(--block-spacing-vertical) 0;
1307+ padding: var(--block-spacing-vertical) var(--block-spacing-horizontal);
1308+ border-radius: var(--border-radius);
1309+ background: var(--card-background-color);
1310+ box-shadow: var(--card-box-shadow)
1311+}
1312+
1313+article > footer, article > header {
1314+ margin-right: calc(var(--block-spacing-horizontal) * -1);
1315+ margin-left: calc(var(--block-spacing-horizontal) * -1);
1316+ padding: calc(var(--block-spacing-vertical) * .66) var(--block-spacing-horizontal);
1317+ background-color: var(--card-sectionning-background-color)
1318+}
1319+
1320+article > header {
1321+ margin-top: calc(var(--block-spacing-vertical) * -1);
1322+ margin-bottom: var(--block-spacing-vertical);
1323+ border-bottom: var(--border-width) solid var(--card-border-color)
1324+}
1325+
1326+article > footer {
1327+ margin-top: var(--block-spacing-vertical);
1328+ margin-bottom: calc(var(--block-spacing-vertical) * -1);
1329+ border-top: var(--border-width) solid var(--card-border-color)
1330+}
1331+
1332+:root {
1333+ --scrollbar-width: 0
1334+}
1335+
1336+dialog article {
1337+ max-height: calc(100vh - var(--spacing) * 2);
1338+ overflow: auto
1339+}
1340+
1341+@media (min-width: 576px) {
1342+ dialog article {
1343+ max-width: 510px
1344+ }
1345+}
1346+
1347+@media (min-width: 768px) {
1348+ dialog article {
1349+ max-width: 700px
1350+ }
1351+}
1352+
1353+dialog article > footer, dialog article > header {
1354+ padding: calc(var(--block-spacing-vertical) * .5) var(--block-spacing-horizontal)
1355+}
1356+
1357+dialog article > header .close {
1358+ margin: 0 0 0 var(--spacing);
1359+ float: right
1360+}
1361+
1362+dialog article > footer {
1363+ text-align: right
1364+}
1365+
1366+dialog article > footer [role=button] {
1367+ margin-bottom: 0
1368+}
1369+
1370+dialog article > footer [role=button]:not(:first-of-type) {
1371+ margin-left: calc(var(--spacing) * .5)
1372+}
1373+
1374+dialog article p:last-of-type {
1375+ margin: 0
1376+}
1377+
1378+dialog article .close {
1379+ display: block;
1380+ width: 1rem;
1381+ height: 1rem;
1382+ margin-top: calc(var(--block-spacing-vertical) * -.5);
1383+ margin-bottom: var(--typography-spacing-vertical);
1384+ margin-left: auto;
1385+ background-image: var(--icon-close);
1386+ background-position: center;
1387+ background-size: auto 1rem;
1388+ background-repeat: no-repeat;
1389+ opacity: 0.5;
1390+ transition: opacity var(--transition)
1391+}
1392+
1393+dialog article .close:is([aria-current],:hover,:active,:focus) {
1394+ opacity: 1
1395+}
1396+
1397+dialog:not([open]), dialog[open=false] {
1398+ display: none
1399+}
1400+
1401+.modal-is-open {
1402+ padding-right: var(--scrollbar-width, 0);
1403+ overflow: hidden;
1404+ pointer-events: none
1405+}
1406+
1407+.modal-is-open dialog {
1408+ pointer-events: auto
1409+}
1410+
1411+:where(.modal-is-opening,.modal-is-closing) dialog, :where(.modal-is-opening,.modal-is-closing) dialog > article {
1412+ -webkit-animation-duration: 0.2s;
1413+ animation-duration: 0.2s;
1414+ -webkit-animation-timing-function: ease-in-out;
1415+ animation-timing-function: ease-in-out;
1416+ -webkit-animation-fill-mode: both;
1417+ animation-fill-mode: both
1418+}
1419+
1420+:where(.modal-is-opening,.modal-is-closing) dialog {
1421+ -webkit-animation-duration: 0.8s;
1422+ animation-duration: 0.8s;
1423+ -webkit-animation-name: fadeIn;
1424+ animation-name: fadeIn
1425+}
1426+
1427+:where(.modal-is-opening,.modal-is-closing) dialog > article {
1428+ -webkit-animation-delay: 0.2s;
1429+ animation-delay: 0.2s;
1430+ -webkit-animation-name: slideInDown;
1431+ animation-name: slideInDown
1432+}
1433+
1434+.modal-is-closing dialog, .modal-is-closing dialog > article {
1435+ -webkit-animation-delay: 0s;
1436+ animation-delay: 0s;
1437+ animation-direction: reverse
1438+}
1439+
1440+:where(nav li)::before {
1441+ float: left;
1442+ content: ""
1443+}
1444+
1445+nav, nav ul {
1446+ display: flex
1447+}
1448+
1449+nav {
1450+ justify-content: space-between
1451+}
1452+
1453+nav ol, nav ul {
1454+ align-items: center;
1455+ margin-bottom: 0;
1456+ padding: 0;
1457+ list-style: none
1458+}
1459+
1460+nav ol:first-of-type, nav ul:first-of-type {
1461+ margin-left: calc(var(--nav-element-spacing-horizontal) * -1)
1462+}
1463+
1464+nav ol:last-of-type, nav ul:last-of-type {
1465+ margin-right: calc(var(--nav-element-spacing-horizontal) * -1)
1466+}
1467+
1468+nav li {
1469+ display: inline-block;
1470+ margin: 0;
1471+ padding: var(--nav-element-spacing-vertical) var(--nav-element-spacing-horizontal)
1472+}
1473+
1474+nav li > * {
1475+ --spacing: 0
1476+}
1477+
1478+nav:where(a,[role=link]) {
1479+ display: inline-block;
1480+ margin: calc(var(--nav-link-spacing-vertical) * -1) calc(var(--nav-link-spacing-horizontal) * -1);
1481+ padding: var(--nav-link-spacing-vertical) var(--nav-link-spacing-horizontal);
1482+ border-radius: var(--border-radius);
1483+ text-decoration: none
1484+}
1485+
1486+nav:where(a,[role=link]):is([aria-current],:hover,:active,:focus) {
1487+ text-decoration: none
1488+}
1489+
1490+nav [role=button] {
1491+ margin-right: inherit;
1492+ margin-left: inherit;
1493+ padding: var(--nav-link-spacing-vertical) var(--nav-link-spacing-horizontal)
1494+}
1495+
1496+details[role=list], li[role=list] {
1497+ position: relative
1498+}
1499+
1500+details[role=list] summary + ul, li[role=list] > ul {
1501+ display: flex;
1502+ z-index: 99;
1503+ position: absolute;
1504+ top: auto;
1505+ right: 0;
1506+ left: 0;
1507+ flex-direction: column;
1508+ margin: 0;
1509+ padding: 0;
1510+ border: var(--border-width) solid var(--dropdown-border-color);
1511+ border-radius: var(--border-radius);
1512+ border-top-right-radius: 0;
1513+ border-top-left-radius: 0;
1514+ background-color: var(--dropdown-background-color);
1515+ box-shadow: var(--card-box-shadow);
1516+ color: var(--dropdown-color);
1517+ white-space: nowrap
1518+}
1519+
1520+details[role=list] summary + ul li, li[role=list] > ul li {
1521+ width: 100%;
1522+ margin-bottom: 0;
1523+ padding: calc(var(--form-element-spacing-vertical) * .5) var(--form-element-spacing-horizontal);
1524+ list-style: none
1525+}
1526+
1527+details[role=list] summary + ul li:first-of-type, li[role=list] > ul li:first-of-type {
1528+ margin-top: calc(var(--form-element-spacing-vertical) * .5)
1529+}
1530+
1531+details[role=list] summary + ul li:last-of-type, li[role=list] > ul li:last-of-type {
1532+ margin-bottom: calc(var(--form-element-spacing-vertical) * .5)
1533+}
1534+
1535+details[role=list] summary + ul li a, li[role=list] > ul li a {
1536+ display: block;
1537+ margin: calc(var(--form-element-spacing-vertical) * -.5) calc(var(--form-element-spacing-horizontal) * -1);
1538+ padding: calc(var(--form-element-spacing-vertical) * .5) var(--form-element-spacing-horizontal);
1539+ overflow: hidden;
1540+ color: var(--dropdown-color);
1541+ text-decoration: none;
1542+ text-overflow: ellipsis
1543+}
1544+
1545+details[role=list] summary + ul li a:hover, li[role=list] > ul li a:hover {
1546+ background-color: var(--dropdown-hover-background-color)
1547+}
1548+
1549+details[role=list] summary::after, li[role=list] > a::after {
1550+ display: block;
1551+ width: 1rem;
1552+ height: calc(1rem * var(--line-height, 1.5));
1553+ -webkit-margin-start: 0.5rem;
1554+ margin-inline-start: 0.5rem;
1555+ float: right;
1556+ transform: rotate(0);
1557+ background-position: right center;
1558+ background-size: 1rem auto;
1559+ background-repeat: no-repeat;
1560+ content: ""
1561+}
1562+
1563+nav details[role=list] summary + ul, nav li[role=list] > ul {
1564+ min-width: -webkit-fit-content;
1565+ min-width: -moz-fit-content;
1566+ min-width: fit-content;
1567+ border-radius: var(--border-radius)
1568+}
1569+
1570+nav details[role=list] summary + ul li a, nav li[role=list] > ul li a {
1571+ border-radius: 0
1572+}
1573+
1574+nav details[role=list] summary, nav details[role=list] summary:not([role]) {
1575+ height: auto;
1576+ padding: var(--nav-link-spacing-vertical) var(--nav-link-spacing-horizontal)
1577+}
1578+
1579+nav details[role=list][open] summary {
1580+ border-radius: var(--border-radius)
1581+}
1582+
1583+nav details[role=list] summary + ul {
1584+ margin-top: var(--outline-width);
1585+ -webkit-margin-start: 0;
1586+ margin-inline-start: 0
1587+}
1588+
1589+nav details[role=list] summary[role=link] {
1590+ margin-bottom: calc(var(--nav-link-spacing-vertical) * -1);
1591+ line-height: var(--line-height)
1592+}
1593+
1594+nav details[role=list] summary[role=link] + ul {
1595+ margin-top: calc(var(--nav-link-spacing-vertical) + var(--outline-width));
1596+ -webkit-margin-start: calc(var(--nav-link-spacing-horizontal) * -1);
1597+ margin-inline-start: calc(var(--nav-link-spacing-horizontal) * -1)
1598+}
1599+
1600+li[role=list] a:active ~ ul, li[role=list] a:focus ~ ul, li[role=list]:hover > ul {
1601+ display: flex
1602+}
1603+
1604+li[role=list] > ul {
1605+ display: none;
1606+ margin-top: calc(var(--nav-link-spacing-vertical) + var(--outline-width));
1607+ -webkit-margin-start: calc(var(--nav-element-spacing-horizontal) - var(--nav-link-spacing-horizontal));
1608+ margin-inline-start: calc(var(--nav-element-spacing-horizontal) - var(--nav-link-spacing-horizontal))
1609+}
1610+
1611+li[role=list] > a::after {
1612+ background-image: var(--icon-chevron)
1613+}
1614diff --git a/src/main.rs b/src/main.rs
1615new file mode 100644
1616index 0000000000000000000000000000000000000000..0c3565b8c097ceeabcf97b10987859bfa6e793b5
1617--- /dev/null
1618+++ b/src/main.rs
1619@@ -0,0 +1,45 @@
1620+use std::convert::Infallible;
1621+use std::{include_str};
1622+use std::net::SocketAddr;
1623+use hyper::{Body, Request, Response, Server};
1624+use hyper::service::{make_service_fn, service_fn};
1625+use sailfish::TemplateOnce;
1626+
1627+
1628+#[derive(TemplateOnce)]
1629+#[template(path = "index.html")]
1630+struct IndexTemplate {
1631+ pico: &'static str,
1632+}
1633+
1634+const PICO_CSS: &str = include_str!("../assets/pico.min.css");
1635+
1636+async fn hello_world(_req: Request<Body>) -> Result<Response<Body>, Infallible> {
1637+ let body = IndexTemplate { pico: PICO_CSS }
1638+ .render_once()
1639+ .unwrap();
1640+
1641+ let resp: Response<Body> = Response::builder()
1642+ .status(200)
1643+ .header("content-type", "text/html")
1644+ .body(body.into())
1645+ .unwrap();
1646+
1647+ Ok(resp)
1648+}
1649+
1650+
1651+#[tokio::main]
1652+async fn main() {
1653+ let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
1654+
1655+ let make_svc = make_service_fn(|_conn| async {
1656+ Ok::<_, Infallible>(service_fn(hello_world))
1657+ });
1658+
1659+ let server = Server::bind(&addr).serve(make_svc);
1660+
1661+ if let Err(e) = server.await {
1662+ eprintln!("server error: {}", e);
1663+ }
1664+}
1665diff --git a/templates/index.html b/templates/index.html
1666new file mode 100644
1667index 0000000000000000000000000000000000000000..90826de8e10534c0ce4fd7e9d947d98225630fe8
1668--- /dev/null
1669+++ b/templates/index.html
1670@@ -0,0 +1,49 @@
1671+<!DOCTYPE html>
1672+<html data-theme="light" lang="en">
1673+<head>
1674+ <meta charset="UTF-8">
1675+ <meta name="viewport" content="width=device-width, initial-scale=1">
1676+ <title>Yet Another Blog</title>
1677+ <style>
1678+ <%- pico %>
1679+ </style>
1680+</head>
1681+<body>
1682+<header class="container">
1683+ <nav class="container-fluid">
1684+ <ul>
1685+ <li><strong>Yet Another Blog</strong></li>
1686+ </ul>
1687+ <ul>
1688+ <li><a class="secondary">Posts</a></li>
1689+ <li><a class="secondary">Projects</a></li>
1690+ <li><a class="secondary">Resume</a></li>
1691+ </ul>
1692+ </nav>
1693+ <hgroup>
1694+ <h2>
1695+ A gathering of information about some things I do on my spare time. You can find me on gitlab , twitter and
1696+ linkedin .
1697+ </h2>
1698+ </hgroup>
1699+</header>
1700+
1701+<main class="container">
1702+ <section>
1703+ <ul>
1704+ <li><a>K8S private gitlab registry using podman</a></li>
1705+ <li><a>K8S private gitlab registry using podman</a></li>
1706+ </ul>
1707+ </section>
1708+ <section>
1709+ <h2>Title</h2>
1710+ <p>
1711+ Nice content
1712+ <code>
1713+ My code here
1714+ </code>
1715+ </p>
1716+ </section>
1717+</main>
1718+</body>
1719+</html>
1720\ No newline at end of file
1721diff --git a/watch b/watch
1722new file mode 100755
1723index 0000000000000000000000000000000000000000..9f5acdb892dd59d940fab9a5b32a6539b2f79c2f
1724--- /dev/null
1725+++ b/watch
1726@@ -0,0 +1,16 @@
1727+#!/bin/sh
1728+
1729+sigint_handler()
1730+{
1731+ kill $PID
1732+ exit
1733+}
1734+
1735+trap sigint_handler SIGINT
1736+
1737+while true; do
1738+ cargo run &
1739+ PID=$!
1740+ inotifywait -e modify -e move -e create -e delete -e attrib -r src/ templates/ assets/
1741+ kill $PID
1742+done