Implement get_contents for document.
Some checks failed
clippy Build clippy has failed
rust-foreign-document-test Build rust-foreign-document-test has failed
rust-build Build rust-build has succeeded
rust-test Build rust-test has failed

This commit is contained in:
Tom Alexander 2023-11-01 01:07:54 -04:00
parent e0ec5c115f
commit 3fb7cb82cd
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
2 changed files with 78 additions and 5 deletions

View File

@ -1,12 +1,12 @@
use std::path::PathBuf; use std::path::PathBuf;
use super::remove_trailing::RemoveTrailing;
use super::Element; use super::Element;
use super::NodeProperty; use super::NodeProperty;
use super::Object; use super::Object;
use super::PostBlank; use super::PostBlank;
use super::StandardProperties; use super::StandardProperties;
use super::Timestamp; use super::Timestamp;
use crate::types::remove_trailing::RemoveTrailing;
pub type PriorityCookie = u8; pub type PriorityCookie = u8;
pub type HeadlineLevel = u16; pub type HeadlineLevel = u16;
@ -64,10 +64,27 @@ impl<'s> StandardProperties<'s> for Document<'s> {
fn get_contents<'b>(&'b self) -> Option<&'s str> { fn get_contents<'b>(&'b self) -> Option<&'s str> {
let post_blank = self.get_post_blank(); let post_blank = self.get_post_blank();
let foo: RemoveTrailing<_, post_blank> = let mut content_lines = self
RemoveTrailing::new(self.source.split_inclusive("\n")); .source
// self.source.split_inclusive("\n") .split_inclusive('\n')
todo!() .remove_trailing(post_blank);
let first_line = content_lines.next();
let last_line = content_lines.last().or(first_line);
match (first_line, last_line) {
(None, None) => None,
(None, Some(_)) | (Some(_), None) => unreachable!(),
(Some(first_line), Some(last_line)) => {
let first_line_offset = first_line.as_ptr() as usize;
let last_line_offset = last_line.as_ptr() as usize + last_line.len();
let source_offset = self.source.as_ptr() as usize;
debug_assert!(super::lesser_element::is_slice_of(self.source, first_line));
debug_assert!(super::lesser_element::is_slice_of(self.source, last_line));
Some(
&self.source[(first_line_offset - source_offset)
..(last_line_offset - first_line_offset)],
)
}
}
} }
fn get_post_blank(&self) -> PostBlank { fn get_post_blank(&self) -> PostBlank {

View File

@ -0,0 +1,56 @@
pub(crate) trait RemoveTrailing: Iterator + Sized {
fn remove_trailing<R: Into<usize>>(self, amount_to_remove: R) -> RemoveTrailingIter<Self>;
}
impl<I> RemoveTrailing for I
where
I: Iterator,
{
fn remove_trailing<R: Into<usize>>(self, amount_to_remove: R) -> RemoveTrailingIter<Self> {
RemoveTrailingIter {
inner: self,
buffer: Vec::new(),
next_to_pop: 0,
amount_to_remove: amount_to_remove.into(),
}
}
}
pub(crate) struct RemoveTrailingIter<I: Iterator> {
inner: I,
buffer: Vec<I::Item>,
next_to_pop: usize,
amount_to_remove: usize,
}
impl<I: Iterator> Iterator for RemoveTrailingIter<I> {
type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
if self.buffer.len() < self.amount_to_remove {
self.buffer.reserve_exact(self.amount_to_remove);
}
while self.buffer.len() < self.amount_to_remove {
if let Some(elem) = self.inner.next() {
self.buffer.push(elem);
} else {
// The inner was smaller than amount_to_remove, so never return anything.
return None;
}
}
let new_value = self.inner.next();
if self.amount_to_remove == 0 {
return new_value;
}
if let Some(new_value) = new_value {
let ret = std::mem::replace(&mut self.buffer[self.next_to_pop], new_value);
self.next_to_pop = (self.next_to_pop + 1) % self.amount_to_remove;
Some(ret)
} else {
// We have exactly the amount in the buffer than we wanted to cut off, so stop returning values.
None
}
}
}