commit 33855940894a9dbffe233deae9fe76ece87ce938 Author: xdrm-brackets Date: Fri Oct 11 19:31:46 2019 +0200 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..53eaa21 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +**/*.rs.bk diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..ba9cb07 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,58 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "aho-corasick" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "clifmt" +version = "0.1.0" +dependencies = [ + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "memchr" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "regex" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "thread_local" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[metadata] +"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" +"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" +"checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" +"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" +"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..b9d8a8e --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "clifmt" +version = "0.1.0" +authors = ["xdrm-brackets "] +edition = "2018" + +[dependencies] +regex = "1" \ No newline at end of file diff --git a/src/transform/errors.rs b/src/transform/errors.rs new file mode 100644 index 0000000..e9b3a7a --- /dev/null +++ b/src/transform/errors.rs @@ -0,0 +1,39 @@ +use std::fmt; + +pub struct Error { + kind: Kind, +} + +impl fmt::Debug for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&self.kind, f) + } +} +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&self.kind, f) + } +} + +pub fn new(kind: Kind) -> Error { + Error { kind } +} + +pub enum Kind { + InvalidFormat, +} + +impl fmt::Debug for Kind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Kind::InvalidFormat => fmt::Debug::fmt("invalid format", f), + } + } +} +impl fmt::Display for Kind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Kind::InvalidFormat => fmt::Debug::fmt("invalid format", f), + } + } +} \ No newline at end of file diff --git a/src/transform/mod.rs b/src/transform/mod.rs new file mode 100644 index 0000000..3488751 --- /dev/null +++ b/src/transform/mod.rs @@ -0,0 +1,53 @@ +use regex; + +pub mod errors; +pub mod registry; + +pub struct Transformer { + // the regex matching text to replace + pub matcher: regex::Regex, + + // transform is called to replace a match by its transformation + // it takes as arguments the matched string chunks from the regex + pub transform: fn(®ex::Captures) -> Option +} + +impl Transformer { + // execute 1 given transformer @t with its @input string and returns the output, + // and the error if one. + fn execute(&self, input: &mut String) -> Option { + let mut cursor = 0; + let original = input.to_owned(); + + // reset input as we have @original + input.clear(); + + // apply transformatione for each match + for re_match in self.matcher.find_iter(&original) { + + // 1. append gap between input start OR previous match + input.push_str( &original[cursor..re_match.start()] ); + cursor = re_match.end(); + + // 2. execute transformation on captures + for re_captures in self.matcher.captures(re_match.as_str()) { + + if let Some(transformed) = (self.transform)(&re_captures) { + // 3. apply transformation + input.push_str(&transformed); + } + + } + + } + + // add end of input (if not covered by matches) + if cursor < original.len() { + input.push_str( &original[cursor..] ); + } + + return None; + } +} + + diff --git a/src/transform/registry.rs b/src/transform/registry.rs new file mode 100644 index 0000000..adb595f --- /dev/null +++ b/src/transform/registry.rs @@ -0,0 +1,44 @@ +use crate::transform::Transformer; +use crate::transform::errors; +use std::vec; + +pub fn new() -> Registry { + Registry { + transformers: vec!(), + } +} + +// used to apply a stack of transformations on an input string +pub struct Registry { + // Transformers represents the transformer stack + // ; each one will be executed in ascending order + transformers: vec::Vec +} + + +impl Registry { + + pub fn add(&mut self, transformer: Transformer) { + self.transformers.push(transformer); + } + + // transform executes each transformer of the stack in ascending order feeding + // each one with the output of its predecessor (@input for the first). Note that if one returns an error + // the process stops here and the error is directly returned. + pub fn transform(&self, input: &String) -> Result { + let mut transformed = input.to_owned(); + + // execute each transformer by order + for transformer in self.transformers.iter() { + + // execute ; dispatch error on failure + if let Some(err) = transformer.execute(&mut transformed) { + return Err(err); + } + + } + + Result::Ok( String::from(transformed) ) + } + +}