Skip to content

Commit 9667c97

Browse files
committed
More work on representing filter where its different for different
languages
1 parent 59beb4b commit 9667c97

File tree

3 files changed

+103
-69
lines changed

3 files changed

+103
-69
lines changed

function-grep/src/filter.rs

Lines changed: 89 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use general_filters::{FunctionInImpl, FunctionInLines, FunctionWithParameter};
1+
use general_filters::{FunctionInImpl, FunctionInLines, FunctionWithParameterRust};
22
use std::{collections::HashMap, fmt, hash::Hash};
33

44
mod filter_parsers;
@@ -38,49 +38,56 @@ pub trait Filter: HasFilterInformation {
3838
// TODO: make way to parse from hashmap of attribute to string
3939
fn to_filter(&self, s: &str) -> Result<InstantiatedFilter, String> {
4040
let filter = self.parse_filter(s)?;
41+
let info = self.filter_info();
42+
let info = FilterInformation {
43+
supported_languages: info.supported_languages.into(),
44+
description: info.description,
45+
attributes: info.attributes,
46+
filter_name: info.filter_name,
47+
};
4148
Ok(InstantiatedFilter {
42-
filter_information: self.filter_info(),
49+
filter_information: info,
4350
filter_function: filter,
4451
})
4552
}
4653
}
4754

4855
#[derive(Debug, Clone)]
49-
pub struct FilterInformation {
56+
pub struct FilterInformation<Supports> {
5057
/// the name of the filter (so users can find the filter)
5158
filter_name: String,
5259
/// describes what the filter does and how it parses
5360
description: String,
5461
/// what languages this filter works on
55-
supported_languages: SupportedLanguages,
62+
supported_languages: Supports,
5663

5764
attributes: HashMap<Attribute, AttributeType>,
5865
}
5966

60-
impl fmt::Display for FilterInformation {
67+
impl<Supports> fmt::Display for FilterInformation<Supports> {
6168
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6269
write!(f, "filter {}", self.filter_name)
6370
}
6471
}
6572

66-
impl Hash for FilterInformation {
73+
impl<Supports: Hash> Hash for FilterInformation<Supports> {
6774
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
6875
self.filter_name.hash(state);
6976
self.description.hash(state);
7077
self.supported_languages.hash(state);
7178
}
7279
}
73-
impl PartialEq for FilterInformation {
80+
impl<Supports: PartialEq> PartialEq for FilterInformation<Supports> {
7481
fn eq(&self, other: &Self) -> bool {
7582
self.filter_name == other.filter_name
7683
&& self.description == other.description
7784
&& self.supported_languages == other.supported_languages
7885
}
7986
}
80-
impl Eq for FilterInformation {}
81-
impl FilterInformation {
87+
impl<Supports: PartialEq> Eq for FilterInformation<Supports> {}
88+
impl<Supports> FilterInformation<Supports> {
8289
#[must_use]
83-
pub const fn supported_languages(&self) -> &SupportedLanguages {
90+
pub const fn supported_languages(&self) -> &Supports {
8491
&self.supported_languages
8592
}
8693

@@ -100,20 +107,21 @@ impl FilterInformation {
100107
}
101108
}
102109
pub trait HasFilterInformation {
110+
type Supports: Into<SupportedLanguages>;
103111
/// the name of the filter (so users can find the filter)
104112
fn filter_name(&self) -> String;
105113
/// describes what the filter does and how it parses
106114
fn description(&self) -> String;
107115
/// what languages this filter works on
108-
fn supported_languages(&self) -> SupportedLanguages;
116+
fn supports(&self) -> Self::Supports;
109117
fn attributes(&self) -> HashMap<Attribute, AttributeType>;
110118
// TODO: have filter creation informaton about types and fields for uis
111-
fn filter_info(&self) -> FilterInformation {
119+
fn filter_info(&self) -> FilterInformation<Self::Supports> {
112120
FilterInformation {
113121
filter_name: self.filter_name(),
114122
attributes: self.attributes(),
115123
description: self.description(),
116-
supported_languages: self.supported_languages(),
124+
supported_languages: self.supports(),
117125
}
118126
}
119127
}
@@ -123,7 +131,7 @@ type FilterFunction = Box<dyn Fn(&Node<'_>) -> bool + Send + Sync>;
123131
// filter has and their type so that we can make macro that creates parser, and also so that we can
124132
// communicate to a gui (or tui) that labels, and types of each input
125133
pub struct InstantiatedFilter {
126-
filter_information: FilterInformation,
134+
filter_information: FilterInformation<SupportedLanguages>,
127135
filter_function: FilterFunction,
128136
}
129137

@@ -174,14 +182,44 @@ impl InstantiatedFilter {
174182
}
175183
}
176184

185+
pub struct All;
186+
impl From<All> for SupportedLanguages {
187+
fn from(_: All) -> Self {
188+
Self::All
189+
}
190+
// add code here
191+
}
192+
pub struct Language(String);
193+
impl From<Language> for SupportedLanguages {
194+
fn from(value: Language) -> Self {
195+
Self::Single(value.0)
196+
}
197+
}
198+
// impl Language for
177199
macro_rules! default_filters {
178-
($($filter:ident),*) => {
200+
($($filter:ident),*) => {S
179201
HashMap::from([$(($filter.filter_info().filter_name().to_string(), &$filter as &'static dyn Filter)),*])
180202
};
181203
}
204+
pub struct Many<'a> {
205+
pub name: String,
206+
pub filters: HashMap<String, &'a dyn Filter<Supports = Language>>,
207+
}
208+
182209
pub enum FilterType<'a> {
183-
All(&'a dyn Filter),
184-
Many(HashMap<String, &'a dyn Filter>),
210+
All(&'a dyn Filter<Supports = All>),
211+
Many(Many<'a>),
212+
}
213+
impl<'a> FilterType<'a> {
214+
fn filter_name(&self) -> String {
215+
todo!()
216+
}
217+
218+
fn supports(&self) -> SupportedLanguages {
219+
todo!()
220+
}
221+
222+
// add code here
185223
}
186224
pub struct Filters<'a> {
187225
filters: HashMap<String, FilterType<'a>>,
@@ -193,67 +231,59 @@ impl Filters<'static> {
193231
filters: HashMap::from([
194232
(
195233
FunctionInLines.filter_info().filter_name().to_string(),
196-
FilterType::All(&FunctionInLines as &'static dyn Filter),
234+
FilterType::All(&FunctionInLines as &'static dyn Filter<Supports = All>),
197235
),
198236
(
199237
FunctionInImpl.filter_info().filter_name().to_string(),
200-
FilterType::Many(HashMap::from([(
201-
"Rust".to_string(),
202-
&FunctionInImpl as &'static dyn Filter,
203-
)])),
238+
FilterType::Many(Many {
239+
name: "function_in_impl".to_string(),
240+
filters: HashMap::from([(
241+
"Rust".to_string(),
242+
&FunctionInImpl as &'static dyn Filter<Supports = Language>,
243+
)]),
244+
}),
204245
),
205246
(
206-
FunctionWithParameter
247+
FunctionWithParameterRust
207248
.filter_info()
208249
.filter_name()
209250
.to_string(),
210-
FilterType::Many(
211-
match FunctionWithParameter.filter_info().supported_languages() {
212-
SupportedLanguages::All => unreachable!(),
213-
SupportedLanguages::Many(vec) => {
214-
HashMap::from_iter(vec.into_iter().map(|lang| {
215-
(
216-
lang.to_string(),
217-
&FunctionWithParameter as &'static dyn Filter,
218-
)
219-
}))
220-
}
221-
SupportedLanguages::Single(_) => unreachable!(),
222-
},
223-
),
251+
FilterType::Many(Many {
252+
name: "function_with_parameter".to_string(),
253+
filters: HashMap::from([(
254+
FunctionWithParameterRust.supports().0,
255+
&FunctionWithParameterRust as &'static dyn Filter<Supports = Language>,
256+
)]),
257+
}),
224258
),
225259
]),
226260
}
227261
}
228262
}
263+
229264
impl<'a> Filters<'a> {
230-
pub fn add_filter(&mut self, filter: &'a dyn Filter) -> Result<(), String> {
231-
let result = self
232-
.filters
233-
.get_mut(&filter.filter_name())
234-
.map(|filters| match filters {
235-
FilterType::All(_) => Err("cannot add to an all filter".to_string()),
236-
FilterType::Many(hash_map) => merge_filters(hash_map, filter),
237-
})
238-
.or_else(|| {
239-
self.filters
240-
.insert(filter.filter_name(), to_filter_type(filter));
241-
Some(Ok(()))
242-
});
243-
match result {
244-
Some(res) => res,
245-
None => Ok(()),
265+
pub fn add_filter(&mut self, filter: impl Into<FilterType<'a>>) -> Result<(), String> {
266+
let filter = filter.into();
267+
let name = filter.filter_name().clone();
268+
{
269+
let this = self.filters.get_mut(&name);
270+
match this {
271+
Some(filters) => match filters {
272+
FilterType::All(_) => Err("cannot add to an all filter".to_string()),
273+
FilterType::Many(Many { filters, .. }) => merge_filters(filters, filter),
274+
},
275+
None => {
276+
self.filters.insert(name, filter);
277+
Ok(())
278+
}
279+
}
246280
}
247281
}
248282
}
249283

250284
fn merge_filters<'a>(
251-
hash_map: &mut HashMap<String, &'a dyn Filter>,
252-
filter: &'a dyn Filter,
285+
hash_map: &mut HashMap<String, &'a dyn Filter<Supports = Language>>,
286+
filter: FilterType<'a>,
253287
) -> Result<(), String> {
254288
todo!()
255289
}
256-
257-
fn to_filter_type<'a>(filter: &'a dyn Filter) -> FilterType<'a> {
258-
todo!()
259-
}

function-grep/src/filter/general_filters.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::SupportedLanguages;
66

77
use super::{
88
filter_parsers::{extra, label, number},
9-
Attribute, AttributeType, Filter, FilterFunction, HasFilterInformation,
9+
All, Attribute, AttributeType, Filter, FilterFunction, HasFilterInformation, Language,
1010
};
1111

1212
pub struct FunctionInLines;
@@ -52,11 +52,12 @@ impl Filter for FunctionInLines {
5252
}
5353
}
5454
impl HasFilterInformation for FunctionInLines {
55+
type Supports = All;
5556
fn filter_name(&self) -> String {
5657
"function_in_lines".to_string()
5758
}
58-
fn supported_languages(&self) -> SupportedLanguages {
59-
SupportedLanguages::All
59+
fn supports(&self) -> Self::Supports {
60+
All
6061
}
6162
fn description(&self) -> String {
6263
"filter: function_in_lines
@@ -94,6 +95,7 @@ impl Filter for FunctionInImpl {
9495
}
9596

9697
impl HasFilterInformation for FunctionInImpl {
98+
type Supports = Language;
9799
fn filter_name(&self) -> String {
98100
"function_in_impl".to_string()
99101
}
@@ -102,18 +104,18 @@ impl HasFilterInformation for FunctionInImpl {
102104
"find if any functions are in an impl block".to_string()
103105
}
104106

105-
fn supported_languages(&self) -> SupportedLanguages {
106-
SupportedLanguages::Single("Rust".to_string())
107+
fn supports(&self) -> Self::Supports {
108+
Language("Rust".to_string())
107109
}
108110

109111
fn attributes(&self) -> HashMap<Attribute, AttributeType> {
110112
HashMap::new()
111113
}
112114
}
113115

114-
pub struct FunctionWithParameter;
116+
pub struct FunctionWithParameterRust;
115117

116-
impl HasFilterInformation for FunctionWithParameter {
118+
impl HasFilterInformation for FunctionWithParameterRust {
117119
fn filter_name(&self) -> String {
118120
todo!()
119121
}
@@ -122,16 +124,18 @@ impl HasFilterInformation for FunctionWithParameter {
122124
todo!()
123125
}
124126

125-
fn supported_languages(&self) -> SupportedLanguages {
127+
fn supports(&self) -> Self::Supports {
126128
todo!()
127129
}
128130

129131
fn attributes(&self) -> HashMap<Attribute, AttributeType> {
130132
todo!()
131133
}
134+
135+
type Supports = Language;
132136
}
133137

134-
impl Filter for FunctionWithParameter {
138+
impl Filter for FunctionWithParameterRust {
135139
fn parse_filter(&self, s: &str) -> Result<FilterFunction, String> {
136140
todo!()
137141
}

function-grep/src/supported_languages.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ construct_language!(Java(tree_sitter_java::LANGUAGE).[java]?="method-name" =>
469469
);
470470

471471
#[cfg(feature = "ocaml")]
472-
construct_language!(OCaml(tree_sitter_ocaml::language_ocaml()).[ml]?="method-name" =>
472+
construct_language!(OCaml(tree_sitter_ocaml::LANGUAGE_OCAML).[ml]?="method-name" =>
473473
"((value_definition
474474
(let_binding pattern: (value_name) @method-name (parameter)))
475475
@method-defintion

0 commit comments

Comments
 (0)