Reorganized modules, made rules a separate struct

Rules are now a separate struct, and the `rules` member of
`settings::Settings` is now a `Vec<settings::rule::Rule`.

Several elements were made private, now can be accessed through
dedicated methods
This commit is contained in:
2020-04-04 22:44:08 +02:00
parent dbbb1616dd
commit 5f30c6d636
5 changed files with 139 additions and 58 deletions

94
src/settings/rule/mod.rs Normal file
View File

@@ -0,0 +1,94 @@
extern crate serde;
extern crate serde_json;
extern crate serde_yaml;
use serde::{Deserialize, Serialize};
mod regex_wrapper;
use regex_wrapper::Regex;
/// Representation of a rule in LangEvolveRs
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Rule {
/// Regex that should match the input text
from: Regex,
/// Text to replace matched text
to: String,
}
impl Rule {
/// Create new rule
///
/// # Arguments
///
/// * `from` - literal string that represents the regex that should match
/// the input text
/// * `to` - literal string that represents the regex text that should
/// replaced the text matched by `from`
pub fn new(from: &str, to: &str) -> Self {
Rule {
from: Regex::new(from),
to: String::from(to),
}
}
// TODO break categories in different rules
pub fn update(
&self,
categories: &std::collections::HashMap<String, String>,
) -> std::result::Result<Rule, String> {
let mut rule = self.clone();
let re = Regex::new("%\\D");
let from_match = re.is_match(&self.from.as_str());
let to_match = re.is_match(&self.to.as_str());
if from_match && !to_match {
for (category, content) in categories {
rule.from = Regex::new(
rule.from
.to_string()
.replace(
format!("%{}", category).as_str(),
format!("[{}]", content).as_str(),
)
.as_str(),
);
}
}
Ok(rule)
}
pub fn get_from(&self) -> &Regex {
&self.from
}
pub fn get_to(&self) -> String {
self.to.clone()
}
}
impl From<String> for Rule {
fn from(source: String) -> Self {
let components: Vec<&str> = source.split_terminator(">").collect();
Self {
from: Regex::new(components[0]),
to: String::from(components[1]),
}
}
}
impl PartialEq for Rule {
fn eq(&self, other: &Self) -> bool {
self.from == other.from && self.to == other.to
}
}
impl Eq for Rule {}
#[test]
fn rule_new() {
let rule1 = Rule::new("([ae]+)i", "${1}i");
let rule2 = Rule {
from: Regex::new("([ae]+)i"),
to: String::from("${1}i"),
};
assert_eq!(rule1, rule2);
}

View File

@@ -0,0 +1,77 @@
use std::{fmt, ops};
#[derive(Clone, Debug)]
pub struct Regex(regex::Regex);
impl Regex {
pub fn new(s: &str) -> Self {
Self(regex::Regex::new(s).unwrap())
}
pub fn as_str(&self) -> &str {
self.0.as_str()
}
pub fn to_string(&self) -> String {
self.0.to_string()
}
}
use std::hash::{Hash, Hasher};
impl Hash for Regex {
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.as_str().hash(state);
}
}
impl ops::Deref for Regex {
type Target = regex::Regex;
fn deref(&self) -> &regex::Regex {
&self.0
}
}
impl<'de> serde::Deserialize<'de> for Regex {
fn deserialize<D>(de: D) -> Result<Regex, D::Error>
where
D: serde::Deserializer<'de>,
{
use serde::de::{Error, Visitor};
struct RegexVisitor;
impl<'de> Visitor<'de> for RegexVisitor {
type Value = Regex;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("a regular expression pattern")
}
fn visit_str<E: Error>(self, v: &str) -> Result<Regex, E> {
regex::Regex::new(v)
.map(Regex)
.map_err(|err| E::custom(err.to_string()))
}
}
de.deserialize_str(RegexVisitor)
}
}
use serde::{Serialize, Serializer};
impl Serialize for Regex {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(self.0.as_str())
}
}
impl PartialEq for Regex {
fn eq(&self, other: &Self) -> bool {
self.0.to_string() == other.0.to_string()
}
}
impl Eq for Regex {}