Skip to content

Commit

Permalink
feat(forge): Add regex_replace filter to support replacing text usi…
Browse files Browse the repository at this point in the history
…ng regex. (#380)
  • Loading branch information
lquerel authored Sep 19, 2024
1 parent 2582aee commit bc8e7ec
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ What's changed

* Add `enforce_trailing_dots` into the `comment_formats` configuration. ([#XXX](...) by lquerel).
* Add support for `indent_type` in both the comment filter and the `comment_formats` configuration. ([#XXX](...) by lquerel).
* Add `regex_replace` filter to support replacing text using regex. ([#XXX](...) by lquerel).

## [0.9.2] - 2024-09-09

Expand Down
3 changes: 3 additions & 0 deletions crates/weaver_forge/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,9 @@ The following filters are available:
- `acronym`: Replaces acronyms in the input string with the full name defined in the `acronyms` section of the
`weaver.yaml` configuration file.
- `split_id`: Splits a string by '.' creating a list of nested ids.
- `regex_replace`: Replace all occurrences of a regex pattern (1st parameter) in the input string with the replacement
string (2nd parameter). Under the hood, this filter uses the `regex` crate (see
[regex](https://docs.rs/regex/latest/regex/index.html#traits) for more details)
- `comment_with_prefix(prefix)`: Outputs a multiline comment with the given prefix. This filter is deprecated, please use the more general `comment` filter.
- `comment`: A generic comment formatter that uses the `comment_formats` section of the `weaver.yaml` configuration file (more details [here](#comment-filter)).
- `flatten`: Converts a List of Lists into a single list with all elements.
Expand Down
50 changes: 50 additions & 0 deletions crates/weaver_forge/src/extensions/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::config::WeaverConfig;
use minijinja::value::Rest;
use minijinja::{Environment, ErrorKind, Value};
use regex::Regex;
use std::borrow::Cow;
use std::collections::HashMap;
use std::sync::OnceLock;

Expand All @@ -17,6 +18,7 @@ pub(crate) fn add_filters(env: &mut Environment<'_>, target_config: &WeaverConfi
);
env.add_filter("flatten", flatten);
env.add_filter("split_id", split_id);
env.add_filter("regex_replace", regex_replace);
}

/// Add utility functions to the environment.
Expand Down Expand Up @@ -66,6 +68,24 @@ fn split_id(value: Value) -> Result<Vec<Value>, minijinja::Error> {
}
}

/// Replace all occurrences of a regex pattern (1st parameter) in the input string with the
/// replacement string (2nd parameter).
fn regex_replace(
input: Cow<'_, str>,
pattern: Cow<'_, str>,
replacement: Cow<'_, str>,
) -> Result<String, minijinja::Error> {
let re = Regex::new(pattern.as_ref()).map_err(|e| {
minijinja::Error::new(
ErrorKind::InvalidOperation,
format!("Invalid regex pattern: {}", e),
)
})?;
Ok(re
.replace_all(input.as_ref(), replacement.as_ref())
.to_string())
}

/// Create a filter that replaces acronyms in the input string with the full
/// name defined in the `acronyms` list.
///
Expand Down Expand Up @@ -110,3 +130,33 @@ pub fn acronym(acronyms: Vec<String>) -> impl Fn(&str) -> String {
.collect()
}
}

#[cfg(test)]
mod tests {
use crate::extensions::util::add_filters;
use minijinja::Environment;

#[test]
fn test_regex_replace() {
let mut env = Environment::new();
let ctx = serde_json::Value::Null;
let config = crate::config::WeaverConfig::default();

add_filters(&mut env, &config);

assert_eq!(
env.render_str("{{ 'Hello World!' | regex_replace('!','?') }}", &ctx)
.unwrap(),
"Hello World?"
);

assert_eq!(
env.render_str(
"{{ \"This a test with multiple a's\" | regex_replace('a','A') }}",
&ctx
)
.unwrap(),
"This A test with multiple A's"
);
}
}

0 comments on commit bc8e7ec

Please sign in to comment.