// Code that must be included in every language specific formatter crate. Redefining these types // in every formatter crate is necessary because of Rust's orphan rule that prohibits implementing // unowned traits (traits defined in this file) on unowned types (node types) /// Used to get an object that knows how to format this object. pub(crate) trait AsFormat { type Format<'a>: rome_formatter::Format where Self: 'a; /// Returns an object that is able to format this object. fn format(&self) -> Self::Format<'_>; } /// Implement [AsFormat] for references to types that implement [AsFormat]. impl AsFormat for &T where T: AsFormat, { type Format<'a> = T::Format<'a> where Self: 'a; fn format(&self) -> Self::Format<'_> { AsFormat::format(&**self) } } /// Implement [AsFormat] for [SyntaxResult] where `T` implements [AsFormat]. /// /// Useful to format mandatory AST fields without having to unwrap the value first. impl AsFormat for rome_rowan::SyntaxResult where T: AsFormat, { type Format<'a> = rome_rowan::SyntaxResult> where Self: 'a; fn format(&self) -> Self::Format<'_> { match self { Ok(value) => Ok(value.format()), Err(err) => Err(*err), } } } /// Implement [AsFormat] for [Option] when `T` implements [AsFormat] /// /// Allows to call format on optional AST fields without having to unwrap the field first. impl AsFormat for Option where T: AsFormat, { type Format<'a> = Option> where Self: 'a; fn format(&self) -> Self::Format<'_> { self.as_ref().map(|value| value.format()) } } /// Used to convert this object into an object that can be formatted. /// /// The difference to [AsFormat] is that this trait takes ownership of `self`. pub(crate) trait IntoFormat { type Format: rome_formatter::Format; fn into_format(self) -> Self::Format; } impl IntoFormat for rome_rowan::SyntaxResult where T: IntoFormat, { type Format = rome_rowan::SyntaxResult; fn into_format(self) -> Self::Format { self.map(IntoFormat::into_format) } } /// Implement [IntoFormat] for [Option] when `T` implements [IntoFormat] /// /// Allows to call format on optional AST fields without having to unwrap the field first. impl IntoFormat for Option where T: IntoFormat, { type Format = Option; fn into_format(self) -> Self::Format { self.map(IntoFormat::into_format) } } /// Formatting specific [Iterator] extensions pub(crate) trait FormattedIterExt { /// Converts every item to an object that knows how to format it. fn formatted(self) -> FormattedIter where Self: Iterator + Sized, Self::Item: IntoFormat, { FormattedIter { inner: self, options: std::marker::PhantomData, } } } impl FormattedIterExt for I where I: std::iter::Iterator {} pub(crate) struct FormattedIter where Iter: Iterator, { inner: Iter, options: std::marker::PhantomData, } impl std::iter::Iterator for FormattedIter where Iter: Iterator, Item: IntoFormat, { type Item = Item::Format; fn next(&mut self) -> Option { Some(self.inner.next()?.into_format()) } } impl std::iter::FusedIterator for FormattedIter where Iter: std::iter::FusedIterator, Item: IntoFormat, { } impl std::iter::ExactSizeIterator for FormattedIter where Iter: Iterator + std::iter::ExactSizeIterator, Item: IntoFormat, { }