From 9b89311c44dd1d956f5e146cefb0467ba11e288f Mon Sep 17 00:00:00 2001 From: Izzy Swart Date: Sat, 3 Jul 2021 17:21:54 -0700 Subject: [PATCH] Prefer combinators to pattern matching, handle errors idiomatically --- Cargo.lock | 414 +++++++++++++++++++++++++++++++++++++++++++++-- Cargo.toml | 3 + src/bot.rs | 34 ++-- src/generator.rs | 12 +- src/main.rs | 96 +++++------ src/publish.rs | 45 +++--- src/selection.rs | 26 +-- 7 files changed, 507 insertions(+), 123 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3047f89..b62de08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,6 +30,110 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97be891acc47ca214468e09425d02cef3af2c94d0d82081cd02061f996802f14" +[[package]] +name = "async-channel" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2114d64672151c0c5eaa5e131ec84a74f06e1e559830dabba01ca30605d66319" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-executor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "once_cell", + "slab", +] + +[[package]] +name = "async-fs" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b3ca4f8ff117c37c278a2f7415ce9be55560b846b5bc4412aaa5d29c1c3dae2" +dependencies = [ + "async-lock", + "blocking", + "futures-lite", +] + +[[package]] +name = "async-io" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a811e6a479f2439f0c04038796b5cfb3d2ad56c230e0f2d3f7b04d68cfee607b" +dependencies = [ + "concurrent-queue", + "futures-lite", + "libc", + "log 0.4.14", + "once_cell", + "parking", + "polling", + "slab", + "socket2", + "waker-fn", + "winapi 0.3.9", +] + +[[package]] +name = "async-lock" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6a8ea61bf9947a1007c5cada31e647dbc77b103c679858150003ba697ea798b" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-net" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5373304df79b9b4395068fb080369ec7178608827306ce4d081cba51cac551df" +dependencies = [ + "async-io", + "blocking", + "futures-lite", +] + +[[package]] +name = "async-process" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f38756dd9ac84671c428afbf7c9f7495feff9ec5b0710f17100098e5b354ac" +dependencies = [ + "async-io", + "blocking", + "cfg-if 1.0.0", + "event-listener", + "futures-lite", + "libc", + "once_cell", + "signal-hook", + "winapi 0.3.9", +] + +[[package]] +name = "async-task" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0" + +[[package]] +name = "atomic-waker" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" + [[package]] name = "autocfg" version = "0.1.7" @@ -115,6 +219,20 @@ dependencies = [ "byte-tools", ] +[[package]] +name = "blocking" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e170dbede1f740736619b776d7251cb1b9095c435c34d8ca9f57fcd2f335e9" +dependencies = [ + "async-channel", + "async-task", + "atomic-waker", + "fastrand", + "futures-lite", + "once_cell", +] + [[package]] name = "buf_redux" version = "0.8.4" @@ -172,6 +290,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" +[[package]] +name = "cache-padded" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba" + [[package]] name = "cargo-platform" version = "0.1.1" @@ -247,6 +371,15 @@ dependencies = [ "bitflags", ] +[[package]] +name = "concurrent-queue" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3" +dependencies = [ + "cache-padded", +] + [[package]] name = "cookie" version = "0.12.0" @@ -425,6 +558,12 @@ dependencies = [ "version_check 0.9.3", ] +[[package]] +name = "event-listener" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59" + [[package]] name = "failure" version = "0.1.8" @@ -453,6 +592,15 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" +[[package]] +name = "fastrand" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77b705829d1e87f762c2df6da140b26af5839e1033aa84aa5f56bb688e4e1bdb" +dependencies = [ + "instant", +] + [[package]] name = "flate2" version = "1.0.20" @@ -537,16 +685,131 @@ version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" +[[package]] +name = "futures" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7e43a803dae2fa37c1f6a8fe121e1f7bf9548b4dfc0522a42f34145dadfc27" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e682a68b29a882df0545c143dc3646daefe80ba479bcdede94d5a703de2871e2" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1" + [[package]] name = "futures-cpupool" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" dependencies = [ - "futures", + "futures 0.1.31", "num_cpus", ] +[[package]] +name = "futures-executor" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "badaa6a909fac9e7236d0620a2f57f7664640c56575b71a7552fbd68deafab79" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acc499defb3b348f8d8f3f66415835a9131856ff7714bf10dadfc4ec4bdb29a1" + +[[package]] +name = "futures-lite" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-macro" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c40298486cdf52cc00cd6d6987892ba502c7656a16a4192a9992b1ccedd121" +dependencies = [ + "autocfg 1.0.1", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a57bead0ceff0d6dde8f465ecd96c9338121bb7717d3e7b108059531870c4282" + +[[package]] +name = "futures-task" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a16bef9fc1a4dddb5bee51c989e3fbba26569cbb0e31f5b303c184e3dd33dae" + +[[package]] +name = "futures-timer" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" + +[[package]] +name = "futures-util" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967" +dependencies = [ + "autocfg 1.0.1", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", +] + [[package]] name = "generic-array" version = "0.12.4" @@ -605,7 +868,7 @@ dependencies = [ "byteorder", "bytes 0.4.12", "fnv", - "futures", + "futures 0.1.31", "http 0.1.21", "indexmap", "log 0.4.14", @@ -658,7 +921,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" dependencies = [ "bytes 0.4.12", - "futures", + "futures 0.1.31", "http 0.1.21", "tokio-buf", ] @@ -695,7 +958,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c843caf6296fc1f93444735205af9ed4e109a539005abb2564ae1d6fad34c52" dependencies = [ "bytes 0.4.12", - "futures", + "futures 0.1.31", "futures-cpupool", "h2", "http 0.1.21", @@ -742,7 +1005,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" dependencies = [ "bytes 0.4.12", - "futures", + "futures 0.1.31", "hyper 0.12.36", "native-tls", "tokio-io", @@ -789,6 +1052,15 @@ dependencies = [ "bytes 0.5.6", ] +[[package]] +name = "instant" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" +dependencies = [ + "cfg-if 1.0.0", +] + [[package]] name = "iovec" version = "0.1.4" @@ -838,9 +1110,12 @@ dependencies = [ "chrono", "elefren", "frankenstein", + "futures 0.3.15", + "futures-timer", "rand 0.8.4", "serde", "serde_json", + "smol", ] [[package]] @@ -1183,6 +1458,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "parking" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" + [[package]] name = "parking_lot" version = "0.9.0" @@ -1269,6 +1550,18 @@ dependencies = [ "unicase 1.4.2", ] +[[package]] +name = "pin-project-lite" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" + +[[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.19" @@ -1284,12 +1577,37 @@ dependencies = [ "typemap", ] +[[package]] +name = "polling" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92341d779fa34ea8437ef4d82d440d5e1ce3f3ff7f824aa64424cd481f9a1f25" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "log 0.4.14", + "wepoll-ffi", + "winapi 0.3.9", +] + [[package]] name = "ppv-lite86" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro-nested" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" + [[package]] name = "proc-macro2" version = "1.0.27" @@ -1584,7 +1902,7 @@ dependencies = [ "cookie_store", "encoding_rs", "flate2", - "futures", + "futures 0.1.31", "http 0.1.21", "hyper 0.12.36", "hyper-tls", @@ -1832,6 +2150,25 @@ dependencies = [ "opaque-debug", ] +[[package]] +name = "signal-hook" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "470c5a6397076fae0094aaf06a08e6ba6f37acb77d3b1b91ea92b4d6c8650c39" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +dependencies = [ + "libc", +] + [[package]] name = "siphasher" version = "0.2.3" @@ -1868,6 +2205,34 @@ dependencies = [ "maybe-uninit", ] +[[package]] +name = "smol" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85cf3b5351f3e783c1d79ab5fc604eeed8b8ae9abd36b166e8b87a089efd85e4" +dependencies = [ + "async-channel", + "async-executor", + "async-fs", + "async-io", + "async-lock", + "async-net", + "async-process", + "blocking", + "futures-lite", + "once_cell", +] + +[[package]] +name = "socket2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2" +dependencies = [ + "libc", + "winapi 0.3.9", +] + [[package]] name = "spin" version = "0.5.2" @@ -1971,7 +2336,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" dependencies = [ "bytes 0.4.12", - "futures", + "futures 0.1.31", "mio", "num_cpus", "tokio-current-thread", @@ -1991,7 +2356,7 @@ checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" dependencies = [ "bytes 0.4.12", "either", - "futures", + "futures 0.1.31", ] [[package]] @@ -2000,7 +2365,7 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1de0e32a83f131e002238d7ccde18211c0a5397f60cbfffcb112868c2e0e20e" dependencies = [ - "futures", + "futures 0.1.31", "tokio-executor", ] @@ -2011,7 +2376,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671" dependencies = [ "crossbeam-utils", - "futures", + "futures 0.1.31", ] [[package]] @@ -2021,7 +2386,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" dependencies = [ "bytes 0.4.12", - "futures", + "futures 0.1.31", "log 0.4.14", ] @@ -2032,7 +2397,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09bc590ec4ba8ba87652da2068d150dcada2cfa2e07faae270a5e0409aa51351" dependencies = [ "crossbeam-utils", - "futures", + "futures 0.1.31", "lazy_static", "log 0.4.14", "mio", @@ -2051,7 +2416,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edfe50152bc8164fcc456dab7891fa9bf8beaf01c5ee7e1dd43a397c3cf87dee" dependencies = [ "fnv", - "futures", + "futures 0.1.31", ] [[package]] @@ -2061,7 +2426,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98df18ed66e3b72e742f185882a9e201892407957e45fbff8da17ae7a7c51f72" dependencies = [ "bytes 0.4.12", - "futures", + "futures 0.1.31", "iovec", "mio", "tokio-io", @@ -2077,7 +2442,7 @@ dependencies = [ "crossbeam-deque", "crossbeam-queue", "crossbeam-utils", - "futures", + "futures 0.1.31", "lazy_static", "log 0.4.14", "num_cpus", @@ -2092,7 +2457,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93044f2d313c95ff1cb7809ce9a7a05735b012288a888b62d4434fd58c94f296" dependencies = [ "crossbeam-utils", - "futures", + "futures 0.1.31", "slab", "tokio-executor", ] @@ -2312,6 +2677,12 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + [[package]] name = "walkdir" version = "2.3.2" @@ -2329,7 +2700,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" dependencies = [ - "futures", + "futures 0.1.31", "log 0.4.14", "try-lock", ] @@ -2429,6 +2800,15 @@ dependencies = [ "webpki", ] +[[package]] +name = "wepoll-ffi" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" +dependencies = [ + "cc", +] + [[package]] name = "winapi" version = "0.2.8" diff --git a/Cargo.toml b/Cargo.toml index e0b4135..0d65047 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,9 @@ edition = "2018" chrono = "0.4.19" elefren = { version = "0.22.0", features = ["toml"] } frankenstein = "0.4.0" +futures = "0.3.15" +futures-timer = "3.0.2" rand = "0.8.4" serde = "1.0.126" serde_json = "1.0.64" +smol = "1.2.5" diff --git a/src/bot.rs b/src/bot.rs index f8b3b9d..f22e058 100644 --- a/src/bot.rs +++ b/src/bot.rs @@ -1,10 +1,7 @@ use rand::Rng; -use std::{error::Error, io}; +use std::error::Error; -use crate::{ - generator, model, publish, - selection::{self, Selector}, -}; +use crate::{generator, model, publish, selection}; pub struct IzzilisBot { generator: generator::Generator, @@ -32,25 +29,18 @@ where } } - pub fn generate_samples(&mut self) -> Option { - let lines_result = self.generator.generate_sample_lines(); - let lines = match lines_result { - Ok(res) => res, - Err(err) => return Some(err), - }; + pub fn generate_samples(&mut self) -> Result<(), Box> { + let lines = self.generator.generate_sample_lines()?; for line in lines { - match self.selector.send_for_review(line) { - Some(err) => panic!("Failed selector read, yes shit error I know, help me"), // Yes, I know this is *abysmal* but idk how to deal with errors - // yet, so for the time being I have to suffer through this bad shit. Please help me, looking at this is suffering. I want it to end. - None => (), - } + self.selector.send_for_review(line)?; } + self.loaded_samples = self.selector.collect_selected_samples(); // wtf happens to the original self.loaded_samples??????? - None + Ok(()) } - pub fn publish(&mut self) -> Option> { + pub fn publish(&mut self) -> Result<(), U::Error> { if self.loaded_samples.len() == 0 { // Refresh samples. Either none have been generated so far, // or generated ones are stale. @@ -58,16 +48,14 @@ where // This is a shit solution, but I'm going with it for v1 // purely because I don't know the language well enough to be // confident in doing this via threads. Yet. - self.generate_samples(); + // TODO handle errors here + let _ = self.generate_samples(); } let sample_index = rand::thread_rng().gen_range(0..self.loaded_samples.len() - 1); let content = self.loaded_samples[sample_index].clone(); self.loaded_samples.remove(sample_index); - match self.publisher.publish(content) { - Some(err) => Some(err), - None => None, - } + self.publisher.publish(content) } } diff --git a/src/generator.rs b/src/generator.rs index e32ab80..cccff00 100644 --- a/src/generator.rs +++ b/src/generator.rs @@ -18,15 +18,13 @@ where } pub fn generate_sample_lines(&self) -> Result, io::Error> { - let unwashed_sample = self.model.get_sample()?; - // Cursed, I just wanted a Select - let mut washed_sample: Vec = Vec::new(); - unwashed_sample + Ok(self + .model + .get_sample()? .replace(SAMPLE_SAMPLE_LINE, "") .split(SAMPLE_SPLIT_WORD) .into_iter() - .for_each(|elem| washed_sample.push(elem.trim().to_string())); - - Ok(washed_sample) + .map(|elem| elem.trim().to_owned()) + .collect::>()) } } diff --git a/src/main.rs b/src/main.rs index 514c242..c0eb556 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -use std::{error::Error, process, thread, time::Duration}; +use std::{error::Error, process, time::Duration}; use chrono::Local; use rand::Rng; @@ -7,6 +7,8 @@ use crate::{ bot::IzzilisBot, generator::Generator, publish::FediversePublisher, selection::ConsoleSelector, }; +use futures_timer::Delay; + mod bot; mod config; mod generator; @@ -17,53 +19,55 @@ mod selection; const CONFIG_PATH: &str = "bot_config.json"; fn main() -> Result<(), Box> { - let cfg = match config::Config::from(CONFIG_PATH.to_string()) { - Ok(cfg) => cfg, - Err(_) => { - println!( - "Failed reading config at [{}], writing default", - CONFIG_PATH - ); - match config::Config::default().save(CONFIG_PATH.to_string()) { - Some(err) => println!("Failed writing file to {}: {}", CONFIG_PATH, err), - None => (), + smol::block_on(async { + let cfg = match config::Config::from(CONFIG_PATH.to_string()) { + Ok(cfg) => cfg, + Err(_) => { + println!( + "Failed reading config at [{}], writing default", + CONFIG_PATH + ); + match config::Config::default().save(CONFIG_PATH.to_string()) { + Some(err) => println!("Failed writing file to {}: {}", CONFIG_PATH, err), + None => (), + } + process::exit(1); } - process::exit(1); - } - }; + }; - let gpt_model = model::GPTSampleModel::new( - cfg.python_path(), - cfg.gpt_code_path(), - vec![ - "generate_unconditional_samples.py".to_string(), - "--model_name".to_string(), - cfg.model_name(), - "--temperature".to_string(), - cfg.temperature(), - "--top_k".to_string(), - cfg.top_k(), - "--nsamples".to_string(), - "1".to_string(), - ], - ); - let publisher = FediversePublisher::new(cfg.fediverse_base_url())?; - // let publisher = ConsolePublisher::new(); - let gen = Generator::new(gpt_model); - let console_selector = ConsoleSelector::new(); - let mut bot = IzzilisBot::new(gen, publisher, console_selector); - bot.generate_samples(); + let gpt_model = model::GPTSampleModel::new( + cfg.python_path(), + cfg.gpt_code_path(), + vec![ + "generate_unconditional_samples.py".to_string(), + "--model_name".to_string(), + cfg.model_name(), + "--temperature".to_string(), + cfg.temperature(), + "--top_k".to_string(), + cfg.top_k(), + "--nsamples".to_string(), + "1".to_string(), + ], + ); + let publisher = FediversePublisher::new(cfg.fediverse_base_url())?; + // let publisher = ConsolePublisher::new(); + let gen = Generator::new(gpt_model); + let console_selector = ConsoleSelector::new(); + let mut bot = IzzilisBot::new(gen, publisher, console_selector); + bot.generate_samples(); - let cfg_interval = cfg.interval_seconds(); - loop { - let wait_seconds = rand::thread_rng().gen_range(cfg_interval.min()..cfg_interval.max()); - let wait_time = Duration::from_secs(wait_seconds); - let now = Local::now(); - println!("[{}] Next post is in [{}] seconds", now, wait_seconds); - thread::sleep(wait_time); - match bot.publish() { - Some(err) => println!("Got error from publish: [{}]; continuing", err), - None => println!("publish() call successful"), + let cfg_interval = cfg.interval_seconds(); + loop { + let wait_seconds = rand::thread_rng().gen_range(cfg_interval.min()..cfg_interval.max()); + let wait_time = Duration::from_secs(wait_seconds); + let now = Local::now(); + println!("[{}] Next post is in [{}] seconds", now, wait_seconds); + Delay::new(wait_time).await; + match bot.publish() { + Err(err) => println!("Got error from publish: [{}]; continuing", err), + Ok(()) => println!("publish() call successful"), + } } - } + }) } diff --git a/src/publish.rs b/src/publish.rs index 9fa1f26..ff0c006 100644 --- a/src/publish.rs +++ b/src/publish.rs @@ -1,4 +1,4 @@ -use std::error::Error; +use std::{convert::Infallible, error::Error}; use elefren::{ helpers::{cli, toml}, @@ -10,7 +10,9 @@ use elefren::{ const FEDIVERSE_TOML_PATH: &str = "fediverse.toml"; pub trait Publisher { - fn publish(&self, content: String) -> Option>; + type Error; + + fn publish(&self, content: String) -> Result<(), Self::Error>; } pub struct FediversePublisher { @@ -20,9 +22,11 @@ pub struct FediversePublisher { pub struct ConsolePublisher; impl Publisher for ConsolePublisher { - fn publish(&self, content: String) -> Option> { + type Error = Infallible; + + fn publish(&self, content: String) -> Result<(), Self::Error> { println!("Publishing content to stdout: {}", content); - None + Ok(()) } } @@ -34,35 +38,34 @@ impl ConsolePublisher { impl FediversePublisher { pub fn new(fedi_url: String) -> Result> { - let fedi = if let Ok(data) = toml::from_file(FEDIVERSE_TOML_PATH.to_string()) { - Mastodon::from(data) - } else { - register(fedi_url)? - }; - Ok(Self { client: fedi }) + Ok(Self { + client: toml::from_file(FEDIVERSE_TOML_PATH) + .map(|data| Ok(Mastodon::from(data))) + .unwrap_or_else(|_| register(fedi_url))?, + }) } } impl Publisher for FediversePublisher { - fn publish(&self, content: String) -> Option> { - let status_build_result = StatusBuilder::new() + type Error = Box; + + fn publish(&self, content: String) -> Result<(), Self::Error> { + let status = StatusBuilder::new() .status(&content) // .visibility(Visibility::Direct) .visibility(Visibility::Public) .sensitive(false) .language(Language::Eng) - .build(); + .build() + .map_err(|e| Box::new(e) as Box)?; - let status = match status_build_result { - Ok(status) => status, - Err(err) => return Some(Box::new(err)), - }; println!("Posting status [{}] to fediverse", &content); - match self.client.new_status(status) { - Ok(_) => None, - Err(err) => Some(Box::new(err)), - } + self.client + .new_status(status) + .map_err(|e| Box::new(e) as Box)?; + + Ok(()) } } diff --git a/src/selection.rs b/src/selection.rs index ab80b7c..4645ac9 100644 --- a/src/selection.rs +++ b/src/selection.rs @@ -1,13 +1,21 @@ use frankenstein::{ Api, GetUpdatesParams, KeyboardButton, ReplyKeyboardMarkup, ReplyMarkup, TelegramApi, }; +use futures::Future; use std::{error::Error, io, thread::JoinHandle}; pub trait Selector { - fn send_for_review(&mut self, message: String) -> Option>; + fn send_for_review(&mut self, message: String) -> Result<(), Box>; fn collect_selected_samples(&mut self) -> Vec; } +// pub trait Selector { +// type Error; +// type Response: Future>; + +// fn review(self, data: String) -> Self::Response; +// } + pub struct TelegramSelector { client: frankenstein::Api, dest_chat_id: String, @@ -19,7 +27,7 @@ pub struct ConsoleSelector { } impl Selector for ConsoleSelector { - fn send_for_review(&mut self, message: String) -> Option> { + fn send_for_review(&mut self, message: String) -> Result<(), Box> { println!("generated sample [y+enter to accept]: {}", &message); let mut choice = String::new(); io::stdin().read_line(&mut choice).expect("cum"); @@ -27,7 +35,7 @@ impl Selector for ConsoleSelector { println!("accepted"); self.selected_samples.push(message); } - return None; + Ok(()) } fn collect_selected_samples(&mut self) -> Vec { @@ -49,7 +57,7 @@ const KEEP_BUTTON: &str = "Keep"; const TOSS_BUTTON: &str = "Toss"; impl Selector for TelegramSelector { - fn send_for_review(&mut self, message: String) -> Option> { + fn send_for_review(&mut self, message: String) -> Result<(), Box> { todo!(); if !self.listener_handle.is_none() { todo!(); @@ -64,12 +72,12 @@ impl Selector for TelegramSelector { KeyboardButton::new(TOSS_BUTTON.to_string()), ]), )); - let result = match self.client.send_message(&message_def) { - Ok(_) => None, - Err(_) => todo!(), - }; - result + self.client + .send_message(&message_def) + .expect("TODO handle this properly (doesn't implement std error for some reason)"); + + Ok(()) } fn collect_selected_samples(&mut self) -> Vec {