Skip to content

Commit

Permalink
refactor hash
Browse files Browse the repository at this point in the history
  • Loading branch information
tu6ge committed Sep 4, 2023
1 parent b010f98 commit da57a4e
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 30 deletions.
123 changes: 95 additions & 28 deletions src/register/field_name.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{convert::Infallible, fmt::Display, slice::Iter};
use std::{convert::Infallible, fmt::Display, hash::Hash, slice::Iter};

use super::{
lexer::{Cursor, Token, TokenKind},
Expand Down Expand Up @@ -36,32 +36,83 @@ impl Display for FieldName {
}
}

#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub struct FieldNames(Vec<FieldName>);
fn names_to_string(vec: &Vec<FieldName>) -> String {
let mut string = String::new();
for item in vec.iter() {
match item {
FieldName::Literal(s) => {
if !string.is_empty() {
string.push('.');
}
string.push_str(s);
}
FieldName::Array(n) => {
string.push('[');
string.push_str(&n.to_string());
string.push(']');
}
FieldName::Tuple(n) => {
if !string.is_empty() {
string.push('.');
}
string.push_str(&n.to_string());
}
FieldName::StructVariant(s) => {
string.push('[');
string.push_str(&s.to_string());
string.push(']');
}
}
}
string
}

#[derive(Debug, PartialEq, Eq, Clone)]
pub struct FieldNames {
string: String,
vec: Vec<FieldName>,
}

impl Hash for FieldNames {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.string.hash(state)
}
}

impl FieldNames {
pub(crate) fn new() -> Self {
Self(Vec::new())
Self {
string: String::new(),
vec: Vec::new(),
}
}

pub fn iter(&self) -> Iter<'_, FieldName> {
self.0.iter()
self.vec.iter()
}
}

impl From<Vec<FieldName>> for FieldNames {
fn from(value: Vec<FieldName>) -> Self {
Self(value)
Self {
string: names_to_string(&value),
vec: value,
}
}
}
impl From<FieldName> for FieldNames {
fn from(value: FieldName) -> Self {
Self(vec![value])
let vec = vec![value];
Self {
string: names_to_string(&vec),
vec,
}
}
}
impl<const N: usize> From<[FieldName; N]> for FieldNames {
fn from(value: [FieldName; N]) -> Self {
Self(value.into_iter().collect())
let vec: Vec<_> = value.into_iter().collect();
Self::from(vec)
}
}

Expand All @@ -74,38 +125,50 @@ pub trait IntoFieldName {
impl IntoFieldName for &str {
type Error = String;
fn into_field(self) -> Result<FieldNames, Self::Error> {
Ok(FieldNames(parse(self)?))
Ok(FieldNames {
string: self.to_string(),
vec: parse(self)?,
})
}
}
impl IntoFieldName for u8 {
type Error = Infallible;
fn into_field(self) -> Result<FieldNames, Self::Error> {
Ok(FieldNames(vec![FieldName::Tuple(self)]))
Ok(FieldNames {
string: self.to_string(),
vec: vec![FieldName::Tuple(self)],
})
}
}
impl IntoFieldName for (u8, u8) {
type Error = Infallible;
fn into_field(self) -> Result<FieldNames, Self::Error> {
Ok(FieldNames(vec![
FieldName::Tuple(self.0),
FieldName::Tuple(self.1),
]))
Ok(FieldNames {
string: format!("{}.{}", self.0, self.1),
vec: vec![FieldName::Tuple(self.0), FieldName::Tuple(self.1)],
})
}
}
impl IntoFieldName for (u8, u8, u8) {
type Error = Infallible;
fn into_field(self) -> Result<FieldNames, Self::Error> {
Ok(FieldNames(vec![
FieldName::Tuple(self.0),
FieldName::Tuple(self.1),
FieldName::Tuple(self.2),
]))
Ok(FieldNames {
string: format!("{}.{}.{}", self.0, self.1, self.2),
vec: vec![
FieldName::Tuple(self.0),
FieldName::Tuple(self.1),
FieldName::Tuple(self.2),
],
})
}
}
impl IntoFieldName for [usize; 1] {
type Error = Infallible;
fn into_field(self) -> Result<FieldNames, Self::Error> {
Ok(FieldNames(vec![FieldName::Array(self[0])]))
Ok(FieldNames {
string: format!("[{}]", self[0]),
vec: vec![FieldName::Array(self[0])],
})
}
}
// impl IntoFieldName for [&str; 1] {
Expand Down Expand Up @@ -268,14 +331,18 @@ pub fn parse(source: &str) -> Result<Vec<FieldName>, String> {
}

pub fn parse_message(source: &str) -> Result<MessageKey, String> {
let mut names = parse(source)?;

if let Some(name) = names.pop() {
if let FieldName::Literal(s) = name {
return Ok(MessageKey::new(FieldNames(names), s));
}
}
Err("not found validate rule name".into())
let (name, string) = source
.rsplit_once('.')
.ok_or("not found message".to_owned())?;
let mut names = parse(name)?;

Ok(MessageKey::new(
FieldNames {
string: source.to_string(),
vec: names,
},
string.to_string(),
))
}

#[test]
Expand Down
11 changes: 9 additions & 2 deletions src/register/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! register rules

use std::{collections::HashMap, ops::Deref};
use std::{collections::HashMap, hash::Hash, ops::Deref};

use crate::{
rule::{IntoRuleList, RuleList},
Expand Down Expand Up @@ -152,12 +152,19 @@ impl From<Response> for Result<(), Response> {
}
}

#[derive(Debug, PartialEq, Eq, Hash, Clone)]
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct MessageKey {
fields: FieldNames,
rule: String,
}

impl Hash for MessageKey {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.fields.hash(state);
self.rule.hash(state);
}
}

impl MessageKey {
pub(crate) fn new(fields: FieldNames, rule: String) -> Self {
Self { fields, rule }
Expand Down

0 comments on commit da57a4e

Please sign in to comment.