Skip to content

Commit

Permalink
Added Serialize trait for engine.
Browse files Browse the repository at this point in the history
  • Loading branch information
boocmp committed Jan 29, 2025
1 parent d2f45e5 commit 09b7b88
Show file tree
Hide file tree
Showing 18 changed files with 122 additions and 48 deletions.
2 changes: 1 addition & 1 deletion benches/bench_matching.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use adblock::blocker::{Blocker, BlockerOptions};
use adblock::request::Request;
use adblock::resources::ResourceStorage;
use adblock::url_parser::parse_url;
use adblock::Engine;
use adblock::{Engine, Serialize as _};

#[path = "../tests/test_utils.rs"]
mod test_utils;
Expand Down
2 changes: 1 addition & 1 deletion examples/deserialization.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use adblock::{request::Request, Engine};
use adblock::{request::Request, Engine, Serialize};

use serde::Deserialize;

Expand Down
13 changes: 4 additions & 9 deletions examples/example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,7 @@ use adblock::{
};

fn main() {
let rules = vec![
String::from("-advertisement-icon."),
String::from("-advertisement-management/"),
String::from("-advertisement."),
String::from("-advertisement/script."),
];
let rules = vec![String::from("||yandex.*/clck/$~ping")];

let debug_info = true;
let mut filter_set = FilterSet::new(debug_info);
Expand All @@ -19,9 +14,9 @@ fn main() {
let engine = Engine::from_filter_set(filter_set, true);

let request = Request::new(
"http://example.com/-advertisement-icon.",
"http://example.com/helloworld",
"image",
"https://yandex.ru/clck/counter",
"https://www.yandex.ru/",
"other",
)
.unwrap();
let blocker_result = engine.check_network_request(&request);
Expand Down
2 changes: 1 addition & 1 deletion examples/generate-dat.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use adblock::{request::Request, Engine};
use adblock::{request::Request, Engine, Serialize};

use std::fs::File;
use std::io::prelude::*;
Expand Down
2 changes: 1 addition & 1 deletion examples/use-dat.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use adblock::{request::Request, Engine};
use adblock::{request::Request, Engine, Serialize};

use std::fs::File;
use std::io::prelude::*;
Expand Down
11 changes: 11 additions & 0 deletions js/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions js/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::cell::RefCell;
use std::sync::Mutex;
use std::path::Path;
use adblock::Engine as EngineInternal;
use adblock::Serialize as SerializeInternal;
use adblock::lists::{RuleTypes, FilterFormat, FilterListMetadata, FilterSet as FilterSetInternal, ParseOptions};
use adblock::resources::Resource;
use adblock::resources::resource_assembler::assemble_web_accessible_resources;
Expand Down
8 changes: 6 additions & 2 deletions src/blocker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ use std::ops::DerefMut;
use thiserror::Error;

use crate::filters::network::{NetworkFilter, NetworkFilterMaskHelper};
pub(crate) use crate::network_filter_list::{NetworkFilterList, NetworkFilterListTrait};
pub(crate) use crate::network_filter_list::NetworkFilterListTrait;

#[allow(unused_imports)]
pub(crate) use crate::network_filter_list::NetworkFilterList;

use crate::regex_manager::{RegexManager, RegexManagerDiscardPolicy};
use crate::request::Request;
use crate::resources::ResourceStorage;
Expand Down Expand Up @@ -88,7 +92,7 @@ pub enum BlockerError {
static NO_TAGS: Lazy<HashSet<String>> = Lazy::new(HashSet::new);

#[cfg(feature = "flatbuffers")]
pub type Blocker = GenericBlocker<crate::network_filter_list::NetworkFilterList>;
pub type Blocker = GenericBlocker<crate::network_filter_list::FlatNetworkFilterList>;

#[cfg(not(feature = "flatbuffers"))]
pub type Blocker = GenericBlocker<crate::network_filter_list::NetworkFilterList>;
Expand Down
2 changes: 2 additions & 0 deletions src/cosmetic_filter_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
//! cosmetic filters and allows them to be queried efficiently at runtime for any which may be
//! relevant to a particular page.
#![allow(dead_code)]

use crate::filters::cosmetic::{
CosmeticFilter, CosmeticFilterAction, CosmeticFilterMask, CosmeticFilterOperator,
};
Expand Down
2 changes: 2 additions & 0 deletions src/data_format/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
//! serialization/deserialization implementations and can automatically dispatch to the appropriate
//! one.
#![allow(dead_code)]

mod v0;

pub(crate) mod utils;
Expand Down
32 changes: 4 additions & 28 deletions src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use crate::regex_manager::RegexManagerDiscardPolicy;
use crate::request::Request;
use crate::resources::{Resource, ResourceStorage};

pub use crate::engine_serializer::Serialize;

use std::collections::HashSet;

/// Drives high-level blocking logic and is responsible for loading filter lists into an optimized
Expand Down Expand Up @@ -43,8 +45,8 @@ use std::collections::HashSet;
/// [`Engine::hidden_class_id_selectors`] on an ongoing basis to determine additional elements that
/// should be hidden dynamically.
pub struct Engine {
blocker: Blocker,
cosmetic_cache: CosmeticFilterCache,
pub(crate) blocker: Blocker,
pub(crate) cosmetic_cache: CosmeticFilterCache,
resources: ResourceStorage,
}

Expand Down Expand Up @@ -121,32 +123,6 @@ impl Engine {
}
}

/// Serializes the `Engine` into a binary format so that it can be quickly reloaded later.
pub fn serialize_raw(&self) -> Result<Vec<u8>, crate::data_format::SerializationError> {
use crate::data_format::SerializeFormat;

let serialize_format = SerializeFormat::build(&self.blocker, &self.cosmetic_cache);

serialize_format.serialize()
}

/// Deserialize the `Engine` from the binary format generated by `Engine::serialize_raw`. The
/// method will automatically select the correct deserialization implementation.
pub fn deserialize(
&mut self,
serialized: &[u8],
) -> Result<(), crate::data_format::DeserializationError> {
use crate::data_format::DeserializeFormat;
let current_tags = self.blocker.tags_enabled();
let deserialize_format = DeserializeFormat::deserialize(serialized)?;
let (blocker, cosmetic_cache) = deserialize_format.build();
self.blocker = blocker;
self.blocker
.use_tags(&current_tags.iter().map(|s| &**s).collect::<Vec<_>>());
self.cosmetic_cache = cosmetic_cache;
Ok(())
}

/// Check if a request for a network resource from `url`, of type `request_type`, initiated by
/// `source_url`, should be blocked.
pub fn check_network_request(&self, request: &Request) -> BlockerResult {
Expand Down
76 changes: 76 additions & 0 deletions src/engine_serializer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use crate::engine::Engine;

#[derive(Debug)]
pub enum SerializeError {
#[cfg(not(feature = "flatbuffers"))]
DataFormatError(crate::data_format::SerializationError),

#[cfg(feature = "flatbuffers")]
FlatbuffersError(),
}

#[derive(Debug)]
pub enum DeserializeError {
#[cfg(not(feature = "flatbuffers"))]
DataFormatError(crate::data_format::DeserializationError),

#[cfg(feature = "flatbuffers")]
FlatbuffersError(),
}

#[cfg(not(feature = "flatbuffers"))]
impl From<crate::data_format::SerializationError> for SerializeError {
fn from(value: crate::data_format::SerializationError) -> Self {
SerializeError::DataFormatError(value)
}
}

#[cfg(not(feature = "flatbuffers"))]
impl From<crate::data_format::DeserializationError> for DeserializeError {
fn from(value: crate::data_format::DeserializationError) -> Self {
DeserializeError::DataFormatError(value)
}
}

pub trait Serialize {
fn serialize_raw(&self) -> Result<Vec<u8>, SerializeError>;
fn deserialize(&mut self, serialized: &[u8]) -> Result<(), DeserializeError>;
}

#[cfg(feature = "flatbuffers")]
impl Serialize for Engine {
fn serialize_raw(&self) -> Result<Vec<u8>, SerializeError> {
Err(SerializeError::FlatbuffersError())
}

fn deserialize(&mut self, _serialized: &[u8]) -> Result<(), DeserializeError> {
Err(DeserializeError::FlatbuffersError())
}
}

#[cfg(not(feature = "flatbuffers"))]
impl Serialize for Engine {
/// Serializes the `Engine` into a binary format so that it can be quickly reloaded later.
fn serialize_raw(&self) -> Result<Vec<u8>, SerializeError> {
use crate::data_format::SerializeFormat;

let serialize_format = SerializeFormat::build(&self.blocker, &self.cosmetic_cache);

let result = serialize_format.serialize()?;
Ok(result)
}

/// Deserialize the `Engine` from the binary format generated by `Engine::serialize_raw`. The
/// method will automatically select the correct deserialization implementation.
fn deserialize(&mut self, serialized: &[u8]) -> Result<(), DeserializeError> {
use crate::data_format::DeserializeFormat;
let current_tags = self.blocker.tags_enabled();
let deserialize_format = DeserializeFormat::deserialize(serialized)?;
let (blocker, cosmetic_cache) = deserialize_format.build();
self.blocker = blocker;
self.blocker
.use_tags(&current_tags.iter().map(|s| &**s).collect::<Vec<_>>());
self.cosmetic_cache = cosmetic_cache;
Ok(())
}
}
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ pub mod blocker;
#[cfg(feature = "content-blocking")]
pub mod content_blocking;
pub mod cosmetic_filter_cache;
#[cfg(not(feature = "flatbuffers"))]
mod data_format;
mod engine;
mod engine_serializer;
pub mod filters;
pub mod lists;
pub mod network_filter_list;
Expand All @@ -35,6 +37,7 @@ pub mod utils;

#[doc(inline)]
pub use engine::Engine;
pub use engine_serializer::Serialize;
#[doc(inline)]
pub use lists::FilterSet;

Expand Down
4 changes: 4 additions & 0 deletions src/network_filter_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,12 @@ pub trait NetworkFilterListTrait {

#[derive(Serialize, Deserialize, Default)]
pub struct NetworkFilterList {
#[cfg(not(feature = "flatbuffers"))]
#[serde(serialize_with = "crate::data_format::utils::stabilize_hashmap_serialization")]
pub(crate) filter_map: HashMap<Hash, Vec<Arc<NetworkFilter>>>,

#[cfg(feature = "flatbuffers")]
pub(crate) filter_map: HashMap<Hash, Vec<Arc<NetworkFilter>>>,
}

impl NetworkFilterListTrait for NetworkFilterList {
Expand Down
2 changes: 1 addition & 1 deletion tests/deserialization.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use adblock::request::Request;
use adblock::Engine;
use adblock::{Engine, Serialize};

use serde::Deserialize;

Expand Down
4 changes: 2 additions & 2 deletions tests/legacy_harness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ mod legacy_test_filters {

mod legacy_check_match {
use adblock::request::Request;
use adblock::Engine;
use adblock::{Engine, Serialize};

fn check_match<'a>(
rules: &[&'a str],
Expand Down Expand Up @@ -854,7 +854,7 @@ mod legacy_check_options {
mod legacy_misc_tests {
use adblock::filters::network::NetworkFilter;
use adblock::request::Request;
use adblock::Engine;
use adblock::{Engine, Serialize};

#[test]
fn demo_app() {
Expand Down
2 changes: 1 addition & 1 deletion tests/live.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use adblock::request::Request;
use adblock::Engine;
use adblock::{Engine, Serialize};

use serde::Deserialize;
use tokio::runtime::Runtime;
Expand Down
2 changes: 1 addition & 1 deletion tests/ublock-coverage.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use adblock::request::Request;
use adblock::Engine;
use adblock::{Engine, Serialize};

use serde::Deserialize;

Expand Down

0 comments on commit 09b7b88

Please sign in to comment.