Protect against empty spans

This commit is contained in:
Alexandre Bury 2018-01-11 00:07:44 +01:00
parent 5dcce6a965
commit afb224b860
2 changed files with 35 additions and 13 deletions

View File

@ -44,6 +44,13 @@ where
type Item = Chunk<'b>; type Item = Chunk<'b>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
// Protect agains empty spans
while self.current_span < self.spans.len()
&& self.spans[self.current_span].text.is_empty()
{
self.current_span += 1;
}
if self.current_span >= self.spans.len() { if self.current_span >= self.spans.len() {
return None; return None;
} }
@ -111,6 +118,13 @@ where
// we need to look at the next span first. // we need to look at the next span first.
self.current_span += 1; self.current_span += 1;
// Skip empty spans
while self.current_span < self.spans.len()
&& self.spans[self.current_span].text.is_empty()
{
self.current_span += 1;
}
if self.current_span >= self.spans.len() { if self.current_span >= self.spans.len() {
// If this was the last chunk, return as is! // If this was the last chunk, return as is!
return Some(Chunk { return Some(Chunk {

View File

@ -7,7 +7,6 @@ pub mod markdown;
#[cfg(feature = "markdown")] #[cfg(feature = "markdown")]
pub use self::markdown::MarkdownText; pub use self::markdown::MarkdownText;
use owning_ref::OwningHandle; use owning_ref::OwningHandle;
use owning_ref::StringRef; use owning_ref::StringRef;
use std::borrow::Cow; use std::borrow::Cow;
@ -43,7 +42,6 @@ pub trait Markup {
/// This only wraps the text and indicates how it should be parsed; /// This only wraps the text and indicates how it should be parsed;
/// it does not parse the text itself. /// it does not parse the text itself.
pub trait MarkupText { pub trait MarkupText {
/// Markup format to use to parse the string. /// Markup format to use to parse the string.
type M: Markup; type M: Markup;
@ -67,12 +65,16 @@ impl Markup for Plain {
type Error = (); type Error = ();
fn parse<'a>(input: &'a str) -> Result<Vec<Span<'a>>, Self::Error> { fn parse<'a>(input: &'a str) -> Result<Vec<Span<'a>>, Self::Error> {
Ok(vec![ Ok(if input.is_empty() {
Vec::new()
} else {
vec![
Span { Span {
text: Cow::Borrowed(input), text: Cow::Borrowed(input),
style: Style::none(), style: Style::none(),
}, },
]) ]
})
} }
} }
@ -110,7 +112,8 @@ impl StyledString {
/// ///
/// > You got no style, Dutch. You know that. /// > You got no style, Dutch. You know that.
pub fn plain<S>(content: S) -> Self pub fn plain<S>(content: S) -> Self
where S: Into<String> where
S: Into<String>,
{ {
Self::new(content).unwrap() Self::new(content).unwrap()
} }
@ -138,16 +141,21 @@ impl StyledString {
} }
/// Sets the content of this string to plain text. /// Sets the content of this string to plain text.
pub fn set_plain<S>(&mut self, content: S) where S: Into<String> { pub fn set_plain<S>(&mut self, content: S)
where
S: Into<String>,
{
self.set_content(content).unwrap(); self.set_content(content).unwrap();
} }
/// Append `content` to the end. /// Append `content` to the end.
/// ///
/// Re-parse everything after. /// Re-parse everything after.
pub fn append_content<T>(&mut self, content: T) -> Result<(), <T::M as Markup>::Error> pub fn append_content<T>(
&mut self, content: T
) -> Result<(), <T::M as Markup>::Error>
where where
T: MarkupText T: MarkupText,
{ {
self.with_content::<T::M, _, _>(|c| c.push_str(&content.to_string())) self.with_content::<T::M, _, _>(|c| c.push_str(&content.to_string()))
} }