diff --git a/Cargo.lock b/Cargo.lock index 35ca012..9bb7abf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1042,11 +1042,11 @@ dependencies = [ "r2d2", "r2d2_sqlite", "rand 0.8.5", + "regex", "rusqlite", "secp256k1", "serde", "serde_json", - "serde_urlencoded", "thiserror", "tokio", "tokio-tungstenite", @@ -1767,18 +1767,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - [[package]] name = "sha-1" version = "0.10.0" diff --git a/Cargo.toml b/Cargo.toml index ff9624f..fc44f21 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,7 @@ http = { version = "0.2" } parse_duration = "2" rand = "0.8" const_format = "0.2.28" -serde_urlencoded = "0.7" +regex = "1" [dev-dependencies] anyhow = "1" diff --git a/src/delegation.rs b/src/delegation.rs index 8e93381..d2f4f33 100644 --- a/src/delegation.rs +++ b/src/delegation.rs @@ -1,11 +1,12 @@ //! Event parsing and validation -//use crate::error::Error::*; -//use crate::error::Result; +use crate::error::Error; +use crate::error::Result; //use crate::utils::unix_time; //use bitcoin_hashes::{sha256, Hash}; -//use lazy_static::lazy_static; +use lazy_static::lazy_static; +use regex::Regex; //use secp256k1::{schnorr, Secp256k1, VerifyOnly, XOnlyPublicKey}; -use serde::{Deserializer, Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; //use serde_json::value::Value; //use serde_json::Number; //use std::collections::HashMap; @@ -58,35 +59,11 @@ pub enum Value { Number(u64), } -#[derive(Serialize, PartialEq, Eq, Debug, Clone)] +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] pub struct ConditionQuery { pub(crate) conditions: Vec, } -impl <'de> Deserialize<'de> for ConditionQuery { - fn deserialize(d: D) -> Result - where - D: Deserializer<'de>, - { - // recv'd is an array of pairs. - let _recvd: Value = d.deserialize_seq - let cond_list = recvd.as_object().ok_or_else(|| { - serde::de::Error::invalid_type( - Unexpected::Other("reqfilter is not an object"), - &"a json object", - ) - })?; - - // all valid conditions will be put into this vec - let conditions : Vec = vec![]; - // loop through the parsed value, and identify if they are - // known attributes. unknown attributes will trigger failure, - // since we can't respect those restrictions. - Ok(ConditionQuery{conditions}) - } - -} - /// Parsed delegation statement #[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] pub struct Delegation { @@ -95,6 +72,7 @@ pub struct Delegation { pub(crate) signature: String, } + /// Parsed delegation condition /// see https://github.com/nostr-protocol/nips/pull/28#pullrequestreview-1084903800 /// An example complex condition would be: kind=1,2,3&created_at<1665265999 @@ -105,6 +83,36 @@ pub struct Condition { pub(crate) values: Vec, } +fn str_to_condition(cs: &str) -> Option { + // a condition is a string (alphanum+underscore), an operator (<>=!), and values (num+comma) + lazy_static! { + static ref RE: Regex = Regex::new("([[:word:]])([<>=!]+)([,[[:digit:]]]+))").unwrap(); + } + // match against the regex + let caps = RE.captures(cs)?; + let _field =caps.get(0)?; + Some(Condition {field: Field::Kind, operator: Operator::LessThan, values: vec![]}) +} + + + +/// Parse a condition query from a string slice +impl TryFrom<&str> for ConditionQuery { + type Error = Error; + fn try_from(value: &str) -> Result { + // split the string with '&' + let conds = value.split('&'); + // parse each individual condition + for c in conds.into_iter() { + str_to_condition(c).ok_or(Error::DelegationParseError)?; + } + Ok(ConditionQuery{conditions: vec![]}) + + } + + +} + #[cfg(test)] mod tests { use super::*; @@ -114,6 +122,5 @@ mod tests { fn parse_empty() { // given an empty condition query, produce an empty vector assert_eq!(Delegation::from(""), vec![]); - assert_eq!(serde_urlencoded::from_str::>(""), vec![]); } } diff --git a/src/error.rs b/src/error.rs index 5a0c992..bca9fc6 100644 --- a/src/error.rs +++ b/src/error.rs @@ -50,6 +50,8 @@ pub enum Error { HyperError(hyper::Error), #[error("Hex encoding error")] HexError(hex::FromHexError), + #[error("Delegation parse error")] + DelegationParseError, #[error("Unknown/Undocumented")] UnknownError, }