Skip to content

Commit

Permalink
Merge pull request #9 from ourzora/cleanup
Browse files Browse the repository at this point in the history
Post-merge clean up
  • Loading branch information
ligustah authored Apr 4, 2024
2 parents 3c19251 + 42b40b8 commit 43344d7
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 38 deletions.
104 changes: 74 additions & 30 deletions src/rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ use crate::types::{Premint, PremintTypes};
pub struct RuleContext {}

#[async_trait]
trait Rule: Send + Sync {
pub trait Rule: Send + Sync {
async fn check(&self, item: PremintTypes, context: RuleContext) -> eyre::Result<bool>;
fn rule_name(&self) -> &'static str;
}

struct FnRule<T>(pub T);
pub struct FnRule<T>(pub &'static str, pub T);

#[async_trait]
impl<T, Fut> Rule for FnRule<T>
Expand All @@ -20,36 +21,49 @@ where
Fut: std::future::Future<Output = eyre::Result<bool>> + Send,
{
async fn check(&self, item: PremintTypes, context: RuleContext) -> eyre::Result<bool> {
self.0(item, context).await
self.1(item, context).await
}

fn rule_name(&self) -> &'static str {
self.0
}
}

#[macro_export]
macro_rules! rule {
($fn:tt) => {
FnRule($fn)
crate::rules::FnRule(stringify!($fn), $fn)
};
}

#[macro_export]
macro_rules! typed_rule {
($t:path, $fn:tt) => {
crate::rules::FnRule(
|item: crate::types::PremintTypes,
context: crate::rules::RuleContext|
-> std::pin::Pin<
std::boxed::Box<dyn std::future::Future<Output = eyre::Result<bool>> + Send + Sync>,
> {
std::boxed::Box::pin(async {
match item {
$t(premint) => $fn(premint, context).await,
_ => Ok(true),
}
})
},
)
};
($t:path, $fn:tt) => {{
struct TypedRule;

#[async_trait::async_trait]
impl crate::rules::Rule for TypedRule {
async fn check(
&self,
item: crate::types::PremintTypes,
context: crate::rules::RuleContext,
) -> eyre::Result<bool> {
match item {
$t(premint) => $fn(premint, context).await,
_ => Ok(true),
}
}

fn rule_name(&self) -> &'static str {
concat!(stringify!($t), "::", stringify!($fn))
}
}

TypedRule {}
}};
}

struct RulesEngine {
pub struct RulesEngine {
rules: Vec<Box<dyn Rule>>,
}

Expand All @@ -61,27 +75,42 @@ impl RulesEngine {
self.rules.push(Box::new(rule));
}

pub async fn evaluate(&self, item: PremintTypes, context: RuleContext) -> bool {
pub async fn evaluate(&self, item: PremintTypes, context: RuleContext) -> eyre::Result<bool> {
let results: Vec<_> = self
.rules
.iter()
.map(|rule| rule.check(item.clone(), context.clone()))
.collect();
let all_checks = join_all(results).await;

// TODO: handle errors
all_checks
.iter()
.all(|check| check.is_ok() && check.as_ref().unwrap().clone())
// TODO: ideally we'd want to return a list of all errors
// so that a caller could determine which rules failed and why
for error in all_checks.into_iter() {
match error {
Err(e) => {
return Err(e);
}
Ok(pass) => {
if !pass {
return Ok(false);
}
}
}
}

Ok(true)
}
}

#[cfg(test)]
mod test {
use super::*;
use crate::types::SimplePremint;
use alloy_primitives::U256;

use crate::premints::zora_premint_v2::types::ZoraPremintV2;
use crate::types::SimplePremint;

use super::*;

async fn simple_rule(item: PremintTypes, context: RuleContext) -> eyre::Result<bool> {
Ok(true)
}
Expand All @@ -97,6 +126,13 @@ mod test {
Ok(true)
}

async fn simple_typed_zora_rule(
item: ZoraPremintV2,
context: RuleContext,
) -> eyre::Result<bool> {
Ok(true)
}

#[tokio::test]
async fn test_simple_rule() {
let context = RuleContext {};
Expand All @@ -119,7 +155,7 @@ mod test {
.evaluate(PremintTypes::Simple(Default::default()), context)
.await;

assert!(result);
assert!(result.unwrap());
}

#[tokio::test]
Expand All @@ -128,13 +164,21 @@ mod test {
let context = RuleContext {};

let rule = typed_rule!(PremintTypes::Simple, simple_typed_rule);
let rule2 = typed_rule!(PremintTypes::ZoraV2, simple_typed_zora_rule);

assert_eq!(rule.rule_name(), "PremintTypes::Simple::simple_typed_rule");
assert_eq!(
rule2.rule_name(),
"PremintTypes::ZoraV2::simple_typed_zora_rule"
);

re.add_rule(rule);
re.add_rule(rule2);

let result = re
.evaluate(PremintTypes::Simple(Default::default()), context)
.await;

assert!(result);
assert!(result.unwrap());
}
}
8 changes: 0 additions & 8 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use std::fmt::Debug;

// use crate::rules::RulesEngine;

#[derive(Debug)]
pub struct PremintName(pub String);

Expand Down Expand Up @@ -38,13 +36,7 @@ pub struct PremintMetadata {
#[async_trait]
pub trait Premint: Serialize + DeserializeOwned + Debug + Clone {
fn metadata(&self) -> PremintMetadata;

fn guid(&self) -> String;

// async fn validate(&self, engine: RulesEngine<Self>) -> bool {
// engine.validate(self).await
// }

fn check_filter(chain_id: u64) -> Option<Filter>;
fn map_claim(chain_id: u64, log: Log) -> eyre::Result<InclusionClaim>;
async fn verify_claim(chain_id: u64, tx: Transaction, log: Log, claim: InclusionClaim) -> bool;
Expand Down

0 comments on commit 43344d7

Please sign in to comment.