use super::*;
use crate::{ParseResult, ParseState, StopBecause};
use core::str::pattern::{Pattern, Searcher};
#[derive(Copy, Clone, Debug)]
pub struct SurroundPair<'i> {
pub head: StringView<'i>,
pub body: StringView<'i>,
pub tail: StringView<'i>,
}
#[derive(Copy, Clone, Debug)]
pub struct SurroundPattern {
pub lhs: &'static str,
pub rhs: &'static str,
pub lhs_name: &'static str,
pub rhs_name: &'static str,
}
impl<'i> FnOnce<(ParseState<'i>,)> for SurroundPattern {
type Output = ParseResult<'i, SurroundPair<'i>>;
#[inline]
extern "rust-call" fn call_once(self, (input,): (ParseState<'i>,)) -> Self::Output {
let (body_state, head) = input.match_str_pattern(self.lhs, self.lhs_name)?;
let lhs = StringView::new(head, input.start_offset);
let message = self.rhs_name;
let mut searcher = self.rhs.into_searcher(&body_state.residual);
match searcher.next_match() {
Some((start, end)) => unsafe {
let body_str = body_state.residual.get_unchecked(..start);
let rhs_str = body_state.residual.get_unchecked(start..end);
let body = StringView::new(body_str, body_state.start_offset);
let rhs = StringView::new(rhs_str, body_state.start_offset + start);
let new_state = body_state.advance(end);
new_state.finish(SurroundPair { head: lhs, body, tail: rhs })
},
None => StopBecause::missing_string(message, body_state.end_offset())?,
}
}
}