Skip to content

Commit

Permalink
parse site block rules into 'HostRankings' instead.
Browse files Browse the repository at this point in the history
they are still executed as exactly the same tantivy queries, but this allows us to correctly import the sites from exported optics.
  • Loading branch information
mikkeldenker committed Feb 29, 2024
1 parent 5c7278a commit 3239e21
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 2 deletions.
14 changes: 14 additions & 0 deletions crates/core/src/query/optic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1720,6 +1720,20 @@ mod tests {
.webpages;
assert_eq!(res.len(), 1);
assert_eq!(res[0].url, "https://example.com/test");

let res = searcher
.search(&SearchQuery {
query: "example".to_string(),
optic: Some(
Optic::parse("Rule { Matches { Site(\"|example.com|\") }, Action(Discard) }")
.unwrap(),
),
..Default::default()
})
.unwrap()
.webpages;
assert_eq!(res.len(), 1);
assert_eq!(res[0].url, "https://another-example.com/");
}

#[test]
Expand Down
29 changes: 27 additions & 2 deletions crates/optics/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,15 @@ impl TryFrom<RawOptic> for Optic {

fn try_from(raw: RawOptic) -> Result<Self> {
let mut rules = Vec::new();
let mut blocked = Vec::new();

for rule in raw.rules {
rules.push(Rule::try_from(rule)?);
let rule = Rule::try_from(rule)?;

match rule.as_blocked_site() {
Some(site) => blocked.push(site),
None => rules.push(rule),
}
}

let mut liked_hosts = Vec::new();
Expand All @@ -99,7 +105,7 @@ impl TryFrom<RawOptic> for Optic {
host_rankings: HostRankings {
liked: liked_hosts,
disliked: disliked_hosts,
blocked: Vec::new(), // blocked hosts are handled by `$discard` syntax.
blocked,
},
})
}
Expand Down Expand Up @@ -349,6 +355,25 @@ pub struct Rule {
/// What action to take if the rule matches.
pub action: Action,
}
impl Rule {
/// If the rule is on the form `Rule { Matches { Site("|...|") }, Action(Discard) }`, return the site to block.
fn as_blocked_site(&self) -> Option<String> {
if self.action == Action::Discard {
let matching = self.matches.first()?.first()?;

if matching.location == MatchLocation::Site
&& matching.pattern.first()? == &PatternPart::Anchor
&& matching.pattern.get(2)? == &PatternPart::Anchor
{
if let PatternPart::Raw(site) = matching.pattern.get(1)? {
return Some(site.clone());
}
}
}

None
}
}

impl Display for Rule {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Expand Down

0 comments on commit 3239e21

Please sign in to comment.