#[inline]
pub fn apply_index_shift(source: &str, by: i32) -> String {
let mut i = 0;
while i < source.len() {
if crate::adversarial::mutations::catalog::lexical::is_code_index(source, i)
&& source[i..].starts_with('[')
{
let left_ok = i
.checked_sub(1)
.and_then(|j| source.get(j..=j))
.map(|s| {
let c = s.chars().next().unwrap();
c.is_alphanumeric() || c == '_' || c == ']'
})
.unwrap_or(false);
if left_ok {
let start = i + 1;
let mut depth = 1;
let mut j = start;
while let Some(c) = source.get(j..).and_then(|s| s.chars().next()) {
if c == '[' {
depth += 1;
} else if c == ']' {
depth -= 1;
if depth == 0 {
let inner = &source[start..j];
let suffix = if by >= 0 {
format!("+{}", by)
} else {
format!("{}", by)
};
return format!(
"{}[({}) {}]{}",
&source[..i],
inner,
suffix,
&source[j + c.len_utf8()..]
);
}
}
j += c.len_utf8();
}
}
}
if let Some(c) = source[i..].chars().next() {
i += c.len_utf8();
} else {
break;
}
}
source.to_string()
}
#[inline]
pub fn apply_index_clamp(source: &str, new_index: &str) -> String {
let mut i = 0;
while i < source.len() {
if crate::adversarial::mutations::catalog::lexical::is_code_index(source, i)
&& source[i..].starts_with('[')
{
let left_ok = i
.checked_sub(1)
.and_then(|j| source.get(j..=j))
.map(|s| {
let c = s.chars().next().unwrap();
c.is_alphanumeric() || c == '_' || c == ']'
})
.unwrap_or(false);
if left_ok {
let start = i + 1;
let mut depth = 1;
let mut j = start;
while let Some(c) = source.get(j..).and_then(|s| s.chars().next()) {
if c == '[' {
depth += 1;
} else if c == ']' {
depth -= 1;
if depth == 0 {
return format!(
"{}[{}]{}",
&source[..i],
new_index,
&source[j + c.len_utf8()..]
);
}
}
j += c.len_utf8();
}
}
}
if let Some(c) = source[i..].chars().next() {
i += c.len_utf8();
} else {
break;
}
}
source.to_string()
}
#[inline]
pub fn apply_read_write_swap(source: &str) -> String {
let tmp = crate::adversarial::mutations::catalog::lexical::replace_code(
source,
".read(",
".VYRE_TMP_READ.",
usize::MAX,
);
let tmp = crate::adversarial::mutations::catalog::lexical::replace_code(
&tmp,
".write(",
".read(",
usize::MAX,
);
let tmp = crate::adversarial::mutations::catalog::lexical::replace_code_word(
&tmp,
"load",
"VYRE_TMP_LOAD",
usize::MAX,
);
let tmp = crate::adversarial::mutations::catalog::lexical::replace_code_word(
&tmp,
"store",
"load",
usize::MAX,
);
let tmp = crate::adversarial::mutations::catalog::lexical::replace_code(
&tmp,
".VYRE_TMP_READ.",
".write(",
usize::MAX,
);
crate::adversarial::mutations::catalog::lexical::replace_code_word(
&tmp,
"VYRE_TMP_LOAD",
"store",
usize::MAX,
)
}
#[inline]
pub fn apply_ordering_weaken(source: &str) -> String {
let source = crate::adversarial::mutations::catalog::lexical::replace_code(
source,
"Ordering::Release",
"Ordering::Relaxed",
usize::MAX,
);
let source = crate::adversarial::mutations::catalog::lexical::replace_code(
&source,
"Ordering::Acquire",
"Ordering::Relaxed",
usize::MAX,
);
crate::adversarial::mutations::catalog::lexical::replace_code(
&source,
"Ordering::SeqCst",
"Ordering::Acquire",
usize::MAX,
)
}
#[inline]
pub fn apply_acqrel_ordering_weaken(source: &str) -> String {
crate::adversarial::mutations::catalog::lexical::replace_code(
source,
"Ordering::AcqRel",
"Ordering::Relaxed",
usize::MAX,
)
}
#[inline]
pub fn apply_count_shift(source: &str, by: i32) -> String {
let replacement = if by >= 0 {
format!("len.saturating_add({by})")
} else {
format!("len.saturating_sub({})", by.unsigned_abs())
};
let shifted = crate::adversarial::mutations::catalog::lexical::replace_code_word(
source,
"count",
&replacement,
1,
);
if shifted != source {
return shifted;
}
let replacement = if by >= 0 {
format!(".len().saturating_add({by})")
} else {
format!(".len().saturating_sub({})", by.unsigned_abs())
};
crate::adversarial::mutations::catalog::lexical::replace_code(source, ".len()", &replacement, 1)
}