pub(crate) trait Visitor {
fn process(&mut self, _item: &mut crate::Item<'_>) -> ProcessResult {
ProcessResult::default()
}
}
#[must_use]
#[derive(PartialEq)]
pub(crate) struct ProcessResult {
comments_after: Vec<String>,
recurse: bool,
}
impl Default for ProcessResult {
fn default() -> Self {
Self {
comments_after: vec![],
recurse: true,
}
}
}
impl ProcessResult {
pub(crate) fn with_comment_after(mut self, comment: impl Into<String>) -> Self {
self.comments_after.push(comment.into());
self
}
pub(crate) fn stop_recursion(self) -> Self {
Self {
recurse: false,
..self
}
}
pub(crate) fn chain(self, other: Self) -> Self {
Self {
recurse: self.recurse && other.recurse,
comments_after: self
.comments_after
.into_iter()
.chain(other.comments_after)
.collect(),
}
}
}
impl ProcessResult {
#[track_caller]
pub(crate) fn done(self) {
if self != Default::default() {
panic!(
"use_space_before() and use_space_after() have been called, this should be empty."
);
}
}
pub(crate) fn take_recurse(&mut self) -> bool {
let recurse = self.recurse;
self.recurse = true;
recurse
}
pub(crate) fn use_space_before(self, _s: &mut impl crate::space::Spaceish) -> Self {
self
}
pub(crate) fn use_space_after(mut self, s: &mut impl crate::space::Spaceish) -> Self {
for comment in self.comments_after.drain(..) {
s.prepend_comment(&comment);
}
self
}
}
pub(crate) struct ApplicationLiteralsVisitor<F> {
pub(crate) user_fn: F,
}
impl<F: for<'b> FnMut(String, String, &mut crate::Item<'b>) -> Result<(), String>> Visitor
for ApplicationLiteralsVisitor<F>
{
fn process(&mut self, item: &mut crate::Item<'_>) -> ProcessResult {
let Ok((identifier, value)) = item.get_application_literal() else {
return ProcessResult::default();
};
match (self.user_fn)(identifier, value, item) {
Ok(()) => ProcessResult::default(),
Err(e) => ProcessResult::default().with_comment_after(e),
}
}
}
pub(crate) struct TagVisitor<F> {
pub(crate) user_fn: F,
}
impl<F: for<'b> FnMut(u64, &mut crate::Item<'b>) -> Result<(), String>> Visitor for TagVisitor<F> {
fn process(&mut self, item: &mut crate::Item<'_>) -> ProcessResult {
let Ok(tag) = item.get_tag() else {
return ProcessResult::default();
};
match (self.user_fn)(tag, item) {
Ok(()) => ProcessResult::default(),
Err(e) => ProcessResult::default().with_comment_after(e),
}
}
}
pub(crate) struct ArrayElementVisitor<F> {
seen_first: bool,
user_fn: F,
}
impl<F> ArrayElementVisitor<F> {
pub(crate) fn new(user_fn: F) -> Self {
Self {
seen_first: false,
user_fn,
}
}
}
impl<F: for<'b> FnMut(&mut crate::Item<'b>) -> Result<Option<String>, String>> Visitor
for ArrayElementVisitor<F>
{
fn process(&mut self, item: &mut crate::Item<'_>) -> ProcessResult {
if !self.seen_first {
if item.get_array_items_mut().is_err() {
return ProcessResult::default()
.with_comment_after("Expected array".to_string())
.stop_recursion();
}
self.seen_first = true;
return ProcessResult::default();
}
match (self.user_fn)(item) {
Ok(Some(text)) => ProcessResult::default().with_comment_after(text),
Ok(None) => ProcessResult::default(),
Err(e) => ProcessResult::default().with_comment_after(e),
}
.stop_recursion()
}
}
pub(crate) struct MapElementVisitor<F> {
seen_first: bool,
next_value_handler: Option<Option<MapValueHandler>>,
user_fn: F,
}
impl<F> MapElementVisitor<F> {
pub(crate) fn new(user_fn: F) -> Self {
Self {
seen_first: false,
next_value_handler: None,
user_fn,
}
}
}
pub type MapValueHandler =
Box<dyn for<'data> FnOnce(&mut crate::Item<'data>) -> Result<Option<String>, String>>;
impl<
F: for<'b> FnMut(
&mut crate::Item<'b>,
) -> Result<(Option<String>, Option<MapValueHandler>), String>,
> Visitor for MapElementVisitor<F>
{
fn process(&mut self, item: &mut crate::Item<'_>) -> ProcessResult {
if !self.seen_first {
if item.get_map_items().is_err() {
return ProcessResult::default()
.with_comment_after("Expected map".to_string())
.stop_recursion();
}
self.seen_first = true;
return ProcessResult::default();
}
if let Some(handler) = self.next_value_handler.take() {
if let Some(handler) = handler {
match (handler)(item) {
Ok(Some(text)) => ProcessResult::default().with_comment_after(text),
Ok(None) => ProcessResult::default(),
Err(e) => ProcessResult::default().with_comment_after(e),
}
} else {
Default::default()
}
} else {
match (self.user_fn)(item) {
Ok((comment, value_handler)) => {
self.next_value_handler = Some(value_handler);
match comment {
Some(text) => ProcessResult::default().with_comment_after(text),
None => ProcessResult::default(),
}
}
Err(e) => ProcessResult::default().with_comment_after(e),
}
}
.stop_recursion()
}
}