Implement get_contents for document.
This commit is contained in:
		
							parent
							
								
									e0ec5c115f
								
							
						
					
					
						commit
						3fb7cb82cd
					
				| @ -1,12 +1,12 @@ | ||||
| use std::path::PathBuf; | ||||
| 
 | ||||
| use super::remove_trailing::RemoveTrailing; | ||||
| use super::Element; | ||||
| use super::NodeProperty; | ||||
| use super::Object; | ||||
| use super::PostBlank; | ||||
| use super::StandardProperties; | ||||
| use super::Timestamp; | ||||
| use crate::types::remove_trailing::RemoveTrailing; | ||||
| 
 | ||||
| pub type PriorityCookie = u8; | ||||
| pub type HeadlineLevel = u16; | ||||
| @ -64,10 +64,27 @@ impl<'s> StandardProperties<'s> for Document<'s> { | ||||
| 
 | ||||
|     fn get_contents<'b>(&'b self) -> Option<&'s str> { | ||||
|         let post_blank = self.get_post_blank(); | ||||
|         let foo: RemoveTrailing<_, post_blank> = | ||||
|             RemoveTrailing::new(self.source.split_inclusive("\n")); | ||||
|         // self.source.split_inclusive("\n")
 | ||||
|         todo!() | ||||
|         let mut content_lines = self | ||||
|             .source | ||||
|             .split_inclusive('\n') | ||||
|             .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 { | ||||
|  | ||||
							
								
								
									
										56
									
								
								src/types/remove_trailing.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/types/remove_trailing.rs
									
									
									
									
									
										Normal 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 | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Tom Alexander
						Tom Alexander