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:
94
src/settings/rule/mod.rs
Normal file
94
src/settings/rule/mod.rs
Normal 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);
|
||||
}
|
||||
77
src/settings/rule/regex_wrapper.rs
Normal file
77
src/settings/rule/regex_wrapper.rs
Normal 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) -> ®ex::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 {}
|
||||
Reference in New Issue
Block a user