From 3d26773a2b6297c5833667a7d71ebe33f700cac8 Mon Sep 17 00:00:00 2001 From: shouya <526598+shouya@users.noreply.github.com> Date: Mon, 23 Sep 2024 17:47:10 +0900 Subject: [PATCH] wrap FilterConfig enum in a struct --- src/filter.rs | 54 ++++++++++++++++++++++++++++++++++------- src/otf_filter.rs | 4 +-- src/server/inspector.rs | 6 ++--- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/src/filter.rs b/src/filter.rs index 9344b29..0406447 100644 --- a/src/filter.rs +++ b/src/filter.rs @@ -13,6 +13,7 @@ pub(crate) mod select; pub(crate) mod simplify_html; use std::collections::{HashMap, HashSet}; +use std::ops::Deref; use std::sync::Arc; use schemars::JsonSchema; @@ -153,12 +154,44 @@ impl BoxedFilter { } } +type Span = std::ops::Range; + +#[derive( + JsonSchema, Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Hash, +)] +pub struct FilterConfig { + pub value: FilterConfigEnum, + pub span: Option, +} + +impl Deref for FilterConfig { + type Target = FilterConfigEnum; + + fn deref(&self) -> &Self::Target { + &self.value + } +} + +impl FilterConfig { + pub async fn build(self) -> Result { + self.value.build().await + } + + pub fn parse_yaml_value( + key: &str, + value: serde_yaml::Value, + ) -> Result { + let value = FilterConfigEnum::parse_yaml_value(key, value)?; + Ok(Self { value, span: None }) + } +} + macro_rules! define_filters { ($($variant:ident => $config:ty, $desc:literal);* ;) => { paste::paste! { #[derive(JsonSchema, Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Hash)] #[serde(rename_all = "snake_case")] - pub enum FilterConfig { + pub enum FilterConfigEnum { $( #[doc = "# " $variant:snake "\n\n" $desc "\n"] $variant($config), @@ -167,13 +200,13 @@ macro_rules! define_filters { } - impl FilterConfig { + impl FilterConfigEnum { // currently only used in tests #[cfg(test)] pub fn parse_yaml_variant(input: &str) -> Result> { - let config: FilterConfig = Self::parse_yaml(input)?; + let config: FilterConfigEnum = Self::parse_yaml(input)?; match config { - $(FilterConfig::$variant(config) => { + $(FilterConfigEnum::$variant(config) => { Ok(Box::new(config)) })* } @@ -184,18 +217,21 @@ macro_rules! define_filters { #[derive(Deserialize)] struct Dummy { #[serde(flatten)] - config: FilterConfig + config: FilterConfigEnum } let dummy: Dummy = serde_yaml::from_str(input).map_err(ConfigError::from)?; Ok(dummy.config) } - pub fn parse_yaml_value(key: &str, value: serde_yaml::Value) -> Result { + pub fn parse_yaml_value( + key: &str, + value: serde_yaml::Value + ) -> Result { #[derive(Deserialize)] struct Dummy { #[serde(flatten)] - config: FilterConfig + config: FilterConfigEnum } use serde_yaml::{Value, Mapping, value::{Tag, TaggedValue}}; @@ -214,7 +250,7 @@ macro_rules! define_filters { pub async fn build(self) -> Result { match self { - $(FilterConfig::$variant(config) => { + $(FilterConfigEnum::$variant(config) => { let filter = config.build().await?; Ok(BoxedFilter::from(filter)) })* @@ -227,7 +263,7 @@ macro_rules! define_filters { pub fn name(&self) -> &'static str { match self { - $(FilterConfig::$variant(_) => paste::paste! {stringify!([<$variant:snake>])},)* + $(FilterConfigEnum::$variant(_) => paste::paste! {stringify!([<$variant:snake>])},)* } } diff --git a/src/otf_filter.rs b/src/otf_filter.rs index ffb4ae6..e678e73 100644 --- a/src/otf_filter.rs +++ b/src/otf_filter.rs @@ -4,7 +4,7 @@ use tracing::warn; use crate::{ feed::Feed, - filter::{FilterConfig, FilterContext}, + filter::{FilterConfig, FilterConfigEnum, FilterContext}, filter_pipeline::{FilterPipeline, FilterPipelineConfig}, util::{ConfigError, Error}, }; @@ -25,7 +25,7 @@ impl OnTheFlyFilterQuery { filter_name = param; } - if FilterConfig::is_valid_key(filter_name) { + if FilterConfigEnum::is_valid_key(filter_name) { query.push(param.to_string()); } } diff --git a/src/server/inspector.rs b/src/server/inspector.rs index fade56c..06041d9 100644 --- a/src/server/inspector.rs +++ b/src/server/inspector.rs @@ -11,7 +11,7 @@ use http::{StatusCode, Uri}; use schemars::schema::RootSchema; use serde_json::json; -use crate::filter::FilterConfig; +use crate::filter::FilterConfigEnum; use crate::util::Error; use super::auth::{handle_login, handle_logout, Auth}; @@ -99,12 +99,12 @@ async fn filter_schema_handler( _auth: Auth, ) -> Result>, BadRequest> { if params.filters == "all" { - return Ok(Json(FilterConfig::schema_for_all())); + return Ok(Json(FilterConfigEnum::schema_for_all())); } let mut schemas = HashMap::new(); for filter in params.filters.split(',') { - let Some(schema) = FilterConfig::schema_for(filter) else { + let Some(schema) = FilterConfigEnum::schema_for(filter) else { return Err(BadRequest(format!("unknown filter: {}", filter))); }; schemas.insert(filter.to_string(), schema);