Simplify field declarations in query parser

This commit is contained in:
Joakim Soderlund 2024-05-09 16:40:15 +02:00
parent f2c09e14a6
commit e87b1932e9
7 changed files with 162 additions and 188 deletions

147
Cargo.lock generated
View file

@ -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"

View file

@ -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 = ".."

View file

@ -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,
}),

View file

@ -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)

View file

@ -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,

View file

@ -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"));
};

View file

@ -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")),
},