mirror of
https://github.com/scsibug/nostr-rs-relay.git
synced 2024-11-14 15:09:07 -05:00
wip: field parsing
This commit is contained in:
parent
cf997e0ffb
commit
0ae6292c1c
|
@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize};
|
||||||
//use serde_json::Number;
|
//use serde_json::Number;
|
||||||
//use std::collections::HashMap;
|
//use std::collections::HashMap;
|
||||||
//use std::collections::HashSet;
|
//use std::collections::HashSet;
|
||||||
//use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
//use tracing::{debug, info};
|
//use tracing::{debug, info};
|
||||||
|
|
||||||
// This handles everything related to delegation, in particular the
|
// This handles everything related to delegation, in particular the
|
||||||
|
@ -38,26 +38,24 @@ use serde::{Deserialize, Serialize};
|
||||||
// condition string. We will then map that with a deserializer that
|
// condition string. We will then map that with a deserializer that
|
||||||
// maps to a ConditionQuery.
|
// maps to a ConditionQuery.
|
||||||
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
|
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
|
||||||
pub enum Field {
|
pub enum Field {
|
||||||
Kind,
|
Kind,
|
||||||
CreatedAt,
|
CreatedAt,
|
||||||
}
|
}
|
||||||
impl TryFrom<&str> for Field {
|
impl FromStr for Field {
|
||||||
type Error = Error;
|
type Err = Error;
|
||||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
fn from_str(value: &str) -> Result<Self, Self::Err> {
|
||||||
if value=="kind" {
|
if value == "kind" {
|
||||||
Ok(Field::Kind)
|
Ok(Field::Kind)
|
||||||
} else if value=="created_at" {
|
} else if value == "created_at" {
|
||||||
Ok(Field::CreatedAt)
|
Ok(Field::CreatedAt)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::DelegationParseError)
|
Err(Error::DelegationParseError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
|
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
|
||||||
pub enum Operator {
|
pub enum Operator {
|
||||||
LessThan,
|
LessThan,
|
||||||
|
@ -85,7 +83,6 @@ pub struct Delegation {
|
||||||
pub(crate) signature: String,
|
pub(crate) signature: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Parsed delegation condition
|
/// Parsed delegation condition
|
||||||
/// see https://github.com/nostr-protocol/nips/pull/28#pullrequestreview-1084903800
|
/// see https://github.com/nostr-protocol/nips/pull/28#pullrequestreview-1084903800
|
||||||
/// An example complex condition would be: kind=1,2,3&created_at<1665265999
|
/// An example complex condition would be: kind=1,2,3&created_at<1665265999
|
||||||
|
@ -99,35 +96,34 @@ pub struct Condition {
|
||||||
fn str_to_condition(cs: &str) -> Option<Condition> {
|
fn str_to_condition(cs: &str) -> Option<Condition> {
|
||||||
// a condition is a string (alphanum+underscore), an operator (<>=!), and values (num+comma)
|
// a condition is a string (alphanum+underscore), an operator (<>=!), and values (num+comma)
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref RE: Regex = Regex::new("([[:word:]])([<>=!]+)([,[[:digit:]]]+))").unwrap();
|
static ref RE: Regex = Regex::new("([[:word:]])([<>=!]+)([,[[:digit:]]]+)").unwrap();
|
||||||
}
|
}
|
||||||
// match against the regex
|
// match against the regex
|
||||||
let caps = RE.captures(cs)?;
|
let caps = RE.captures(cs)?;
|
||||||
let field = caps.get(1)?.as_str().try_into().ok()?;
|
let field = caps.get(1)?.as_str().parse::<Field>().ok()?;
|
||||||
let _op = caps.get(2)?.as_str();
|
let _op = caps.get(2)?.as_str();
|
||||||
let _vals = caps.get(3)?.as_str();
|
let _vals = caps.get(3)?.as_str();
|
||||||
// convert field string into Field
|
// convert field string into Field
|
||||||
|
|
||||||
Some(Condition {field: field, operator: Operator::GreaterThan, values: vec![]})
|
Some(Condition {
|
||||||
|
field,
|
||||||
|
operator: Operator::GreaterThan,
|
||||||
|
values: vec![],
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// Parse a condition query from a string slice
|
/// Parse a condition query from a string slice
|
||||||
impl TryFrom<&str> for ConditionQuery {
|
impl FromStr for ConditionQuery {
|
||||||
type Error = Error;
|
type Err = Error;
|
||||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
fn from_str(value: &str) -> Result<Self, Self::Err> {
|
||||||
// split the string with '&'
|
// split the string with '&'
|
||||||
let conds = value.split('&');
|
let conds = value.split_terminator('&');
|
||||||
// parse each individual condition
|
// parse each individual condition
|
||||||
for c in conds.into_iter() {
|
for c in conds {
|
||||||
str_to_condition(c).ok_or(Error::DelegationParseError)?;
|
str_to_condition(c).ok_or(Error::DelegationParseError)?;
|
||||||
}
|
}
|
||||||
Ok(ConditionQuery{conditions: vec![]})
|
Ok(ConditionQuery { conditions: vec![] })
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -136,8 +132,11 @@ mod tests {
|
||||||
|
|
||||||
// parse condition strings
|
// parse condition strings
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_empty() {
|
fn parse_empty() -> Result<()> {
|
||||||
// given an empty condition query, produce an empty vector
|
// given an empty condition query, produce an empty vector
|
||||||
assert_eq!(Delegation::from(""), vec![]);
|
let empty_cq = ConditionQuery { conditions: vec![] };
|
||||||
|
let parsed = "".parse::<ConditionQuery>()?;
|
||||||
|
assert_eq!(parsed, empty_cq);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user