#[cfg(feature = "esl")]
use std::ops::Range;
#[cfg(feature = "esl")]
pub(crate) mod api_argument;
#[cfg(feature = "esl")]
pub(crate) mod brackets;
#[cfg(feature = "esl")]
pub(crate) mod escape;
#[cfg(feature = "esl")]
pub(crate) mod execute_on;
#[cfg(feature = "esl")]
pub(crate) mod expansion;
#[cfg(feature = "esl")]
pub(crate) mod inline_hunt;
#[cfg(feature = "esl")]
pub(crate) mod originate_function;
#[cfg(feature = "esl")]
pub(crate) mod originate_legs;
#[cfg(feature = "esl")]
pub(crate) mod pipeline;
pub(crate) mod separate;
#[cfg(all(test, feature = "esl"))]
pub(crate) fn tree_block_parse(tree: &str) -> crate::commands::BlockParse {
let revision = freeswitch_c_oracle::tree(tree)
.unwrap_or_else(|| panic!("the oracle index names no tree {tree}"))
.block_parse();
revision
.parse()
.unwrap_or_else(|e| panic!("tree {tree} block_parse: {e}"))
}
#[cfg(all(test, feature = "esl"))]
pub(crate) fn against_the_c_at_its_revision<S: proptest::strategy::Strategy>(
source: &'static str,
name: &str,
strategy: S,
property: impl Fn(
freeswitch_c_oracle::Oracle,
crate::commands::BlockParse,
S::Value,
) -> proptest::test_runner::TestCaseResult,
) {
freeswitch_c_oracle::on_every_tree(source, name, strategy, |tree, c, value| {
property(c, tree_block_parse(tree), value)
});
}
#[cfg(all(test, feature = "esl"))]
#[test]
fn every_oracle_tree_names_a_known_block_parse() {
for tree in freeswitch_c_oracle::trees() {
tree_block_parse(tree.name());
}
}
#[cfg(feature = "esl")]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum PipelineError {
Empty,
ArgvSplit,
UnclosedBlock { leg: usize },
SplitSeparatorUnreadable,
}
pub(crate) type Traced = (char, usize, usize);
pub(crate) fn trace(s: &str) -> Vec<Traced> {
s.char_indices()
.map(|(at, c)| (c, at, at + c.len_utf8()))
.collect()
}
pub(crate) fn untrace(text: &[Traced]) -> String {
text.iter()
.filter(|entry| !separate::is_continuation(entry))
.map(|&(c, ..)| c)
.collect()
}
#[cfg(feature = "esl")]
pub(crate) fn byte_range(
text: &[Traced],
extent: Range<usize>,
span: Range<usize>,
) -> Range<usize> {
let start = span
.start
.checked_sub(1)
.and_then(|before| text.get(before))
.map_or(extent.start, |&(.., end)| end);
let end = text
.get(span.end)
.map_or(extent.end, |&(_, start, _)| start);
start..end
}
#[cfg(feature = "esl")]
pub(crate) fn extent(text: &[Traced]) -> Range<usize> {
let start = text
.first()
.map_or(0, |&(_, start, _)| start);
let end = text
.last()
.map_or(start, |&(.., end)| end);
start..end
}