1#![no_std]
2#![doc = include_str!("specs.md")]
3
4use core::{iter::FusedIterator, str::SplitInclusive};
5
6mod sealed {
7 pub trait Sealed {}
8 impl Sealed for str {}
9}
10
11pub trait LinesInclusive: sealed::Sealed {
13 fn lines_inclusive(&self) -> LinesInclusiveIter<'_>;
17}
18
19impl LinesInclusive for str {
20 fn lines_inclusive(&self) -> LinesInclusiveIter<'_> {
21 LinesInclusiveIter::new(self)
22 }
23}
24
25#[derive(Debug, Clone)]
29pub struct LinesInclusiveIter<'a>(SplitInclusive<'a, char>);
30
31impl<'a> LinesInclusiveIter<'a> {
32 fn new(text: &'a str) -> Self {
34 LinesInclusiveIter(text.split_inclusive('\n'))
35 }
36}
37
38impl<'a> Iterator for LinesInclusiveIter<'a> {
39 type Item = &'a str;
40 fn next(&mut self) -> Option<Self::Item> {
41 self.0.next()
42 }
43}
44
45impl DoubleEndedIterator for LinesInclusiveIter<'_> {
46 fn next_back(&mut self) -> Option<Self::Item> {
47 self.0.next_back()
48 }
49}
50
51impl FusedIterator for LinesInclusiveIter<'_> {}
52
53#[doc = include_str!("README.md")]
54mod test_readme {}