mirror of
https://github.com/JockeTF/fimfareader.git
synced 2024-11-30 08:57:59 +01:00
Simplify field declarations in query parser
This commit is contained in:
parent
f2c09e14a6
commit
e87b1932e9
7 changed files with 162 additions and 188 deletions
147
Cargo.lock
generated
147
Cargo.lock
generated
|
@ -34,9 +34,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.83"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3"
|
||||
checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
|
@ -46,9 +46,9 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
|||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.5.0"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
|
@ -64,9 +64,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.97"
|
||||
version = "1.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4"
|
||||
checksum = "324c74f2155653c90b04f25b2a47a8a631360cb908f92a772695f430c7e31052"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
|
@ -97,9 +97,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clipboard-win"
|
||||
version = "5.3.1"
|
||||
version = "5.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79f4473f5144e20d9aceaf2972478f06ddf687831eafeeb434fbaf0acc4144ad"
|
||||
checksum = "15efe7a882b08f34e38556b14f2fb3daa98769d06c7f0c1b076dfd0d983bc892"
|
||||
dependencies = [
|
||||
"error-code",
|
||||
]
|
||||
|
@ -112,9 +112,9 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
|
|||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.4.0"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa"
|
||||
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
@ -140,9 +140,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.19"
|
||||
version = "0.8.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
|
||||
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
||||
|
||||
[[package]]
|
||||
name = "dateparser"
|
||||
|
@ -158,20 +158,20 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
version = "0.99.17"
|
||||
version = "0.99.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
|
||||
checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.11.0"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2"
|
||||
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||
|
||||
[[package]]
|
||||
name = "error-code"
|
||||
|
@ -270,27 +270,27 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.154"
|
||||
version = "0.2.155"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346"
|
||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.21"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.2"
|
||||
version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
|
@ -300,9 +300,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
|||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.2"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
|
||||
checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
|
@ -346,9 +346,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.82"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b"
|
||||
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
@ -384,9 +384,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.4"
|
||||
version = "1.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
|
||||
checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
|
@ -396,9 +396,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.6"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
|
||||
checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
|
@ -407,9 +407,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.3"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
|
||||
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
|
||||
|
||||
[[package]]
|
||||
name = "rustyline"
|
||||
|
@ -438,29 +438,29 @@ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.201"
|
||||
version = "1.0.204"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c"
|
||||
checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.201"
|
||||
version = "1.0.204"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865"
|
||||
checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.61",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.117"
|
||||
version = "1.0.120"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
|
||||
checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
@ -469,20 +469,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
version = "2.0.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9"
|
||||
checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -503,15 +492,15 @@ checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
|
|||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.12"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6"
|
||||
checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
|
@ -534,7 +523,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.61",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
|
@ -556,7 +545,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.61",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
@ -587,9 +576,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
|
@ -603,51 +592,51 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "zip"
|
||||
|
|
|
@ -4,6 +4,11 @@ version = "0.1.0"
|
|||
authors = ["Joakim Soderlund <joakim.soderlund@gmail.com>"]
|
||||
edition = "2021"
|
||||
|
||||
[dependencies.derive_more]
|
||||
default-features = false
|
||||
features = ["from"]
|
||||
version = "0.99.17"
|
||||
|
||||
[dependencies.fimfareader]
|
||||
path = ".."
|
||||
|
||||
|
|
|
@ -2,25 +2,17 @@
|
|||
|
||||
use chrono::prelude::*;
|
||||
use dateparser::parse_with_timezone;
|
||||
|
||||
use regex::escape;
|
||||
use regex::RegexBuilder;
|
||||
|
||||
use fimfareader::archive::Story;
|
||||
use fimfareader::error::Error;
|
||||
use fimfareader::error::Result;
|
||||
|
||||
use super::parser::Operator;
|
||||
use super::parser::Source;
|
||||
|
||||
use Operator::*;
|
||||
use Source::*;
|
||||
|
||||
type Filter = Box<dyn Fn(&Story) -> bool + Sync>;
|
||||
|
||||
type IntFn = Box<dyn Fn(&Story) -> i64 + Sync>;
|
||||
type StrFn = Box<dyn Fn(&Story) -> &str + Sync>;
|
||||
type DtuFn = Box<dyn Fn(&Story) -> &Option<DateTime<Utc>> + Sync>;
|
||||
use crate::parser::DateOpt;
|
||||
use crate::parser::Field;
|
||||
use crate::parser::Filter;
|
||||
use crate::parser::Op;
|
||||
use crate::parser::Source;
|
||||
|
||||
macro_rules! ok {
|
||||
($func:expr) => {
|
||||
|
@ -28,16 +20,16 @@ macro_rules! ok {
|
|||
};
|
||||
}
|
||||
|
||||
pub fn optimize(src: Source, op: Operator, value: &str) -> Result<Filter> {
|
||||
pub fn optimize(src: Source, op: Op, value: &str) -> Result<Filter> {
|
||||
match src {
|
||||
StrFn(f) => strfn(f, op, value),
|
||||
IntFn(f) => intfn(f, op, value),
|
||||
DtuFn(f) => dtufn(f, op, value),
|
||||
Source::Str(f) => str(f, op, value),
|
||||
Source::Int(f) => int(f, op, value),
|
||||
Source::Dto(f) => dto(f, op, value),
|
||||
}
|
||||
}
|
||||
|
||||
fn strfn(f: StrFn, op: Operator, value: &str) -> Result<Filter> {
|
||||
let exact: String = value.into();
|
||||
fn str(f: Field<Box<str>>, op: Op, value: &str) -> Result<Filter> {
|
||||
let exact: Box<str> = value.into();
|
||||
|
||||
let result = RegexBuilder::new(&escape(value))
|
||||
.case_insensitive(true)
|
||||
|
@ -49,44 +41,44 @@ fn strfn(f: StrFn, op: Operator, value: &str) -> Result<Filter> {
|
|||
};
|
||||
|
||||
match op {
|
||||
Exact => ok!(move |s| f(s) == exact),
|
||||
Fuzzy => ok!(move |s| regex.is_match(f(s))),
|
||||
Op::Exact => ok!(move |s| *f(s) == exact),
|
||||
Op::Fuzzy => ok!(move |s| regex.is_match(f(s))),
|
||||
_ => Err(Error::query("Invalid operation for text type")),
|
||||
}
|
||||
}
|
||||
|
||||
fn intfn(f: IntFn, op: Operator, value: &str) -> Result<Filter> {
|
||||
fn int(f: Field<i32>, op: Op, value: &str) -> Result<Filter> {
|
||||
let Ok(value) = value.parse() else {
|
||||
return Err(Error::query("Invalid value for number type"));
|
||||
};
|
||||
|
||||
match op {
|
||||
Exact => ok!(move |s| f(s) == value),
|
||||
Fuzzy => ok!(move |s| f(s) == value),
|
||||
LessThan => ok!(move |s| f(s) < value),
|
||||
MoreThan => ok!(move |s| f(s) > value),
|
||||
Op::Exact => ok!(move |s| *f(s) == value),
|
||||
Op::Fuzzy => ok!(move |s| *f(s) == value),
|
||||
Op::LessThan => ok!(move |s| *f(s) < value),
|
||||
Op::MoreThan => ok!(move |s| *f(s) > value),
|
||||
}
|
||||
}
|
||||
|
||||
fn dtufn(f: DtuFn, op: Operator, value: &str) -> Result<Filter> {
|
||||
fn dto(f: Field<DateOpt>, op: Op, value: &str) -> Result<Filter> {
|
||||
let Ok(value) = parse_with_timezone(value, &Local) else {
|
||||
return Err(Error::query("Invalid value for date type"));
|
||||
};
|
||||
|
||||
match op {
|
||||
Exact => ok!(move |s| match f(s) {
|
||||
Op::Exact => ok!(move |s| match f(s) {
|
||||
Some(dt) => *dt == value,
|
||||
None => false,
|
||||
}),
|
||||
Fuzzy => ok!(move |s| match f(s) {
|
||||
Op::Fuzzy => ok!(move |s| match f(s) {
|
||||
Some(dt) => dt.date_naive() == value.date_naive(),
|
||||
None => false,
|
||||
}),
|
||||
LessThan => ok!(move |s| match f(s) {
|
||||
Op::LessThan => ok!(move |s| match f(s) {
|
||||
Some(dt) => *dt < value,
|
||||
None => false,
|
||||
}),
|
||||
MoreThan => ok!(move |s| match f(s) {
|
||||
Op::MoreThan => ok!(move |s| match f(s) {
|
||||
Some(dt) => *dt > value,
|
||||
None => false,
|
||||
}),
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
use chrono::DateTime;
|
||||
use chrono::Utc;
|
||||
use derive_more::From;
|
||||
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::escaped;
|
||||
|
@ -27,94 +28,82 @@ use nom::IResult;
|
|||
use fimfareader::archive::Story;
|
||||
use fimfareader::error::*;
|
||||
|
||||
use super::optimizer::optimize;
|
||||
use crate::optimizer::optimize;
|
||||
|
||||
type Filter = Box<dyn Fn(&Story) -> bool + Sync>;
|
||||
pub(crate) type DateOpt = Option<DateTime<Utc>>;
|
||||
pub(crate) type Field<T> = &'static (dyn Fn(&Story) -> &T + Sync);
|
||||
pub(crate) type Filter = Box<dyn Fn(&Story) -> bool + Sync>;
|
||||
|
||||
pub enum Source {
|
||||
IntFn(Box<dyn Fn(&Story) -> i64 + Sync>),
|
||||
StrFn(Box<dyn Fn(&Story) -> &str + Sync>),
|
||||
DtuFn(Box<dyn Fn(&Story) -> &Option<DateTime<Utc>> + Sync>),
|
||||
#[derive(From)]
|
||||
pub(crate) enum Source {
|
||||
Int(Field<i32>),
|
||||
Str(Field<Box<str>>),
|
||||
Dto(Field<DateOpt>),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum Operator {
|
||||
pub(crate) enum Op {
|
||||
Exact,
|
||||
Fuzzy,
|
||||
LessThan,
|
||||
MoreThan,
|
||||
}
|
||||
|
||||
macro_rules! sfn {
|
||||
($tag:expr => $func:expr) => {
|
||||
preceded(tag($tag), |input| {
|
||||
Ok((input, Source::StrFn(Box::new($func))))
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! ifn {
|
||||
($tag:expr => $func:expr) => {{
|
||||
preceded(tag($tag), |input| {
|
||||
Ok((input, Source::IntFn(Box::new($func))))
|
||||
})
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! dfn {
|
||||
($tag:expr => $func:expr) => {
|
||||
preceded(tag($tag), |input| {
|
||||
Ok((input, Source::DtuFn(Box::new($func))))
|
||||
})
|
||||
macro_rules! ext {
|
||||
($($tag:literal => $($path:ident).+),+,) => {
|
||||
alt(($(preceded(tag($tag), |input| {
|
||||
let field: Field<_> = &|story| &story.$($path).+;
|
||||
Ok((input, Source::from(field)))
|
||||
})),+))
|
||||
};
|
||||
}
|
||||
|
||||
fn source(input: &str) -> IResult<&str, Source> {
|
||||
let story = alt((
|
||||
ifn!("id" => |s| s.id),
|
||||
sfn!("story" => |s| &s.title),
|
||||
sfn!("title" => |s| &s.title),
|
||||
sfn!("description" => |s| &s.description_html),
|
||||
sfn!("short description" => |s| &s.short_description),
|
||||
sfn!("url" => |s| &s.url),
|
||||
dfn!("modified" => |s| &s.date_modified),
|
||||
dfn!("published" => |s| &s.date_published),
|
||||
dfn!("updated" => |s| &s.date_updated),
|
||||
ifn!("chapters" => |s| i64::from(s.num_chapters)),
|
||||
ifn!("comments" => |s| i64::from(s.num_comments)),
|
||||
ifn!("dislikes" => |s| i64::from(s.num_dislikes)),
|
||||
ifn!("likes" => |s| i64::from(s.num_likes)),
|
||||
ifn!("total views" => |s| i64::from(s.total_num_views)),
|
||||
ifn!("views" => |s| i64::from(s.num_views)),
|
||||
ifn!("words" => |s| i64::from(s.num_words)),
|
||||
));
|
||||
let story = ext! {
|
||||
"id" => id,
|
||||
"url" => url,
|
||||
"story" => title,
|
||||
"title" => title,
|
||||
"description" => description_html,
|
||||
"short description" => short_description,
|
||||
"modified" => date_modified,
|
||||
"published" => date_published,
|
||||
"updated" => date_updated,
|
||||
"chapters" => num_chapters,
|
||||
"comments" => num_comments,
|
||||
"dislikes" => num_dislikes,
|
||||
"likes" => num_likes,
|
||||
"total views" => total_num_views,
|
||||
"views" => num_views,
|
||||
"words" => num_words,
|
||||
};
|
||||
|
||||
let author = alt((
|
||||
sfn!("author" => |s| &s.author.name),
|
||||
sfn!("author name" => |s| &s.author.name),
|
||||
ifn!("author id" => |s| s.author.id),
|
||||
dfn!("author joined" => |s| &s.author.date_joined),
|
||||
));
|
||||
let author = ext! {
|
||||
"author" => author.name,
|
||||
"author name" => author.name,
|
||||
"author id" => author.id,
|
||||
"author joined" => author.date_joined,
|
||||
};
|
||||
|
||||
let archive = alt((
|
||||
sfn!("path" => |s| &s.archive.path),
|
||||
sfn!("archive" => |s| &s.archive.path),
|
||||
sfn!("archive path" => |s| &s.archive.path),
|
||||
dfn!("entry checked" => |s| &s.archive.date_checked),
|
||||
dfn!("entry created" => |s| &s.archive.date_created),
|
||||
dfn!("entry fetched" => |s| &s.archive.date_fetched),
|
||||
dfn!("entry updated" => |s| &s.archive.date_updated),
|
||||
));
|
||||
let archive = ext! {
|
||||
"path" => archive.path,
|
||||
"archive" => archive.path,
|
||||
"archive path" => archive.path,
|
||||
"entry checked" => archive.date_checked,
|
||||
"entry created" => archive.date_created,
|
||||
"entry fetched" => archive.date_fetched,
|
||||
"entry updated" => archive.date_updated,
|
||||
};
|
||||
|
||||
preceded(space0, alt((story, author, archive)))(input)
|
||||
}
|
||||
|
||||
fn operator(input: &str) -> IResult<&str, Operator> {
|
||||
fn operator(input: &str) -> IResult<&str, Op> {
|
||||
let operator = alt((
|
||||
value(Operator::Exact, char('=')),
|
||||
value(Operator::Fuzzy, char(':')),
|
||||
value(Operator::LessThan, char('<')),
|
||||
value(Operator::MoreThan, char('>')),
|
||||
value(Op::Exact, char('=')),
|
||||
value(Op::Fuzzy, char(':')),
|
||||
value(Op::LessThan, char('<')),
|
||||
value(Op::MoreThan, char('>')),
|
||||
));
|
||||
|
||||
preceded(space0, operator)(input)
|
||||
|
|
|
@ -9,7 +9,6 @@ use std::path::Path;
|
|||
use std::sync::Mutex;
|
||||
|
||||
use rayon::prelude::*;
|
||||
|
||||
use zip::read::ZipArchive;
|
||||
use zip::result::ZipError;
|
||||
|
||||
|
@ -74,7 +73,7 @@ impl<T: Read + Seek> Fetcher<T> {
|
|||
result
|
||||
}
|
||||
|
||||
pub fn fetch(&self, key: i64) -> Option<&Story> {
|
||||
pub fn fetch(&self, key: i32) -> Option<&Story> {
|
||||
match self.index.binary_search_by_key(&key, |story| story.id) {
|
||||
Ok(i) => self.index.get(i),
|
||||
Err(_) => None,
|
||||
|
|
|
@ -95,7 +95,7 @@ fn deserialize(line: String) -> Result<Story> {
|
|||
|
||||
let story: Story = from_str(json)?;
|
||||
|
||||
let Ok(key) = skey.parse::<i64>() else {
|
||||
let Ok(key) = skey.parse::<i32>() else {
|
||||
return Err(Error::custom("Invalid line key"));
|
||||
};
|
||||
|
||||
|
|
|
@ -32,14 +32,14 @@ pub struct Story {
|
|||
pub date_updated: Option<DateTime<Utc>>,
|
||||
#[serde(deserialize_with = "null_to_html")]
|
||||
pub description_html: Box<str>,
|
||||
pub id: i64,
|
||||
pub id: i32,
|
||||
pub num_chapters: i32,
|
||||
pub num_comments: i32,
|
||||
pub num_dislikes: i32,
|
||||
pub num_likes: i32,
|
||||
pub num_views: i32,
|
||||
pub num_words: i32,
|
||||
pub prequel: Option<i64>,
|
||||
pub prequel: Option<i32>,
|
||||
pub published: bool,
|
||||
pub rating: i32,
|
||||
#[serde(deserialize_with = "null_to_text")]
|
||||
|
@ -71,7 +71,7 @@ pub struct Author {
|
|||
pub bio_html: Option<Box<str>>,
|
||||
pub date_joined: Option<DateTime<Utc>>,
|
||||
#[serde(deserialize_with = "string_to_id")]
|
||||
pub id: i64,
|
||||
pub id: i32,
|
||||
pub name: Box<str>,
|
||||
pub num_blog_posts: Option<i32>,
|
||||
pub num_followers: Option<i32>,
|
||||
|
@ -114,7 +114,7 @@ pub struct Chapter {
|
|||
pub chapter_number: i32,
|
||||
pub date_modified: Option<DateTime<Utc>>,
|
||||
pub date_published: Option<DateTime<Utc>>,
|
||||
pub id: i64,
|
||||
pub id: i32,
|
||||
pub num_views: i32,
|
||||
pub num_words: i32,
|
||||
pub published: bool,
|
||||
|
@ -169,7 +169,7 @@ pub enum Status {
|
|||
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Tag {
|
||||
pub id: i64,
|
||||
pub id: i32,
|
||||
pub name: Box<str>,
|
||||
pub old_id: Box<str>,
|
||||
pub r#type: Box<str>,
|
||||
|
@ -196,16 +196,16 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
fn string_to_id<'de, D>(d: D) -> Result<i64, D::Error>
|
||||
fn string_to_id<'de, D>(d: D) -> Result<i32, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
match Value::deserialize(d)? {
|
||||
Value::Number(value) => match value.as_i64() {
|
||||
Some(value) => Ok(value),
|
||||
Value::Number(value) => match value.as_i64().map(i32::try_from) {
|
||||
Some(Ok(value)) => Ok(value),
|
||||
_ => Err(Error::custom("Could not parse ID number")),
|
||||
},
|
||||
Value::String(value) => match value.parse::<i64>() {
|
||||
Value::String(value) => match value.parse::<i32>() {
|
||||
Ok(value) => Ok(value),
|
||||
_ => Err(Error::custom("Could not parse ID string")),
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue