Get the source code lines.
This commit is contained in:
		
							parent
							
								
									313313ae53
								
							
						
					
					
						commit
						fb99fd2b39
					
				| @ -1,6 +1,7 @@ | ||||
| use crate::error::CustomError; | ||||
| 
 | ||||
| use super::registry::Registry; | ||||
| use super::util::GetFullLines; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub(crate) struct ISrcBlock { | ||||
| @ -12,9 +13,11 @@ impl ISrcBlock { | ||||
|         registry: &mut Registry<'parse>, | ||||
|         original: &organic::types::SrcBlock<'parse>, | ||||
|     ) -> Result<ISrcBlock, CustomError> { | ||||
|         // let contents = original.contents.
 | ||||
|         Ok(ISrcBlock { | ||||
|             lines: Vec::new(), // TODO
 | ||||
|         }) | ||||
|         let lines = original | ||||
|             .contents | ||||
|             .full_lines() | ||||
|             .map(|s| s.to_owned()) | ||||
|             .collect(); | ||||
|         Ok(ISrcBlock { lines }) | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -46,3 +46,129 @@ enum CoalesceWhitespace { | ||||
|     Normal, | ||||
|     HasWhitespace { in_whitespace: bool, ret: String }, | ||||
| } | ||||
| 
 | ||||
| pub(crate) struct FullLinesIterator<'i> { | ||||
|     inner: Option<&'i str>, | ||||
| } | ||||
| 
 | ||||
| impl<'i> Iterator for FullLinesIterator<'i> { | ||||
|     type Item = &'i str; | ||||
| 
 | ||||
|     fn next(&mut self) -> Option<Self::Item> { | ||||
|         if let Some(inner) = self.inner { | ||||
|             for (i, c) in inner.char_indices() { | ||||
|                 if c == '\n' { | ||||
|                     let (current_line, remainder) = inner.split_at(i + 1); | ||||
|                     self.inner = Some(remainder); | ||||
|                     return Some(current_line); | ||||
|                 } | ||||
|             } | ||||
|             if inner.is_empty() { | ||||
|                 None | ||||
|             } else { | ||||
|                 let final_unterminated_line = Some(inner); | ||||
|                 self.inner = None; | ||||
|                 final_unterminated_line | ||||
|             } | ||||
|         } else { | ||||
|             None | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn size_hint(&self) -> (usize, Option<usize>) { | ||||
|         if let Some(inner) = self.inner { | ||||
|             let line_count = { | ||||
|                 inner.bytes().filter(|b| *b == b'\n').count() | ||||
|                     + (if inner.ends_with('\n') { 0 } else { 1 }) | ||||
|             }; | ||||
|             (line_count, Some(line_count)) | ||||
|         } else { | ||||
|             (0, Some(0)) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ExactSizeIterator for FullLinesIterator<'_> {} | ||||
| 
 | ||||
| pub(crate) trait GetFullLines { | ||||
|     fn full_lines(&self) -> FullLinesIterator<'_>; | ||||
| } | ||||
| 
 | ||||
| impl<'s, S: AsRef<str>> GetFullLines for S { | ||||
|     fn full_lines(&self) -> FullLinesIterator<'_> { | ||||
|         let inner = self.as_ref(); | ||||
|         FullLinesIterator { | ||||
|             inner: if inner.is_empty() { None } else { Some(inner) }, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use super::*; | ||||
| 
 | ||||
|     #[test] | ||||
|     fn test_full_lines_iterator() { | ||||
|         { | ||||
|             let input = "foo\nbar\nbaz"; | ||||
|             assert_eq!(input.lines().count(), input.full_lines().count()); | ||||
|             assert_eq!(input.lines().count(), input.full_lines().len()); | ||||
|             assert_eq!(input.lines().collect::<Vec<_>>(), vec!["foo", "bar", "baz"]); | ||||
|             assert_eq!( | ||||
|                 input.full_lines().collect::<Vec<_>>(), | ||||
|                 vec!["foo\n", "bar\n", "baz"] | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         { | ||||
|             // Trailing newline
 | ||||
|             let input = "foo\nbar\nbaz\n"; | ||||
|             assert_eq!(input.lines().count(), input.full_lines().count()); | ||||
|             assert_eq!(input.lines().count(), input.full_lines().len()); | ||||
|             assert_eq!(input.lines().collect::<Vec<_>>(), vec!["foo", "bar", "baz"]); | ||||
|             assert_eq!( | ||||
|                 input.full_lines().collect::<Vec<_>>(), | ||||
|                 vec!["foo\n", "bar\n", "baz\n"] | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         { | ||||
|             // Leading newline
 | ||||
|             let input = "\nfoo\nbar\nbaz"; | ||||
|             assert_eq!(input.lines().count(), input.full_lines().count()); | ||||
|             assert_eq!(input.lines().count(), input.full_lines().len()); | ||||
|             assert_eq!( | ||||
|                 input.lines().collect::<Vec<_>>(), | ||||
|                 vec!["", "foo", "bar", "baz"] | ||||
|             ); | ||||
|             assert_eq!( | ||||
|                 input.full_lines().collect::<Vec<_>>(), | ||||
|                 vec!["\n", "foo\n", "bar\n", "baz"] | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         { | ||||
|             // Double newline
 | ||||
|             let input = "foo\nbar\n\nbaz"; | ||||
|             assert_eq!(input.lines().count(), input.full_lines().count()); | ||||
|             assert_eq!(input.lines().count(), input.full_lines().len()); | ||||
|             assert_eq!( | ||||
|                 input.lines().collect::<Vec<_>>(), | ||||
|                 vec!["foo", "bar", "", "baz"] | ||||
|             ); | ||||
|             assert_eq!( | ||||
|                 input.full_lines().collect::<Vec<_>>(), | ||||
|                 vec!["foo\n", "bar\n", "\n", "baz"] | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         { | ||||
|             // Empty
 | ||||
|             let input = ""; | ||||
|             assert_eq!(input.lines().count(), input.full_lines().count()); | ||||
|             assert_eq!(input.lines().count(), input.full_lines().len()); | ||||
|             assert_eq!(input.lines().collect::<Vec<_>>(), Vec::<&str>::new()); | ||||
|             assert_eq!(input.full_lines().collect::<Vec<_>>(), Vec::<&str>::new()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Tom Alexander
						Tom Alexander