Add markup::{Markup, StyledString}

This commit is contained in:
Alexandre Bury 2018-01-10 13:54:15 +01:00
parent 5d8a452b18
commit 7ecf5f540b
2 changed files with 82 additions and 1 deletions

View File

@ -9,7 +9,7 @@ use std::borrow::Cow;
use theme::{Effect, Style}; use theme::{Effect, Style};
use utils::lines::spans::Span; use utils::lines::spans::Span;
/// Parse markdown string into spans of styled text. /// Iterator that parse a markdown text and outputs styled spans.
pub struct Parser<'a> { pub struct Parser<'a> {
first: bool, first: bool,
stack: Vec<Style>, stack: Vec<Style>,
@ -118,6 +118,19 @@ pub fn parse<'a>(input: &'a str) -> Vec<Span<'a>> {
Parser::new(input).collect() Parser::new(input).collect()
} }
/// `Markup` trait implementation for markdown text.
///
/// Requires the `markdown` feature.
pub struct Markdown;
impl super::Markup for Markdown {
type Error = ();
fn parse<'a>(input: &'a str) -> Result<Vec<Span<'a>>, Self::Error> {
Ok(parse(input))
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View File

@ -4,3 +4,71 @@
#[cfg(feature = "markdown")] #[cfg(feature = "markdown")]
pub mod markdown; pub mod markdown;
#[cfg(feature = "markdown")]
pub use self::markdown::Markdown;
use owning_ref::OwningHandle;
use owning_ref::StringRef;
use std::marker::PhantomData;
use utils::lines::spans::Span;
/// Trait for parsing text into styled spans.
pub trait Markup {
/// Possible error happening when parsing.
type Error;
/// Parses text and return the styled spans.
fn parse<'a>(input: &'a str) -> Result<Vec<Span<'a>>, Self::Error>;
}
type StyledHandle = OwningHandle<StringRef, Vec<Span<'static>>>;
/// A String that parses a markup language.
pub struct StyledString<M> {
content: StyledHandle,
_phantom: PhantomData<M>,
}
impl<M> StyledString<M>
where
M: Markup,
{
fn make_handle<S: Into<String>>(
content: S
) -> Result<StyledHandle, M::Error> {
let content = content.into();
OwningHandle::try_new(StringRef::new(content), |input| {
M::parse(unsafe { &*input })
})
}
/// Creates a new styled string, parsing the given content.
pub fn new<S>(content: S) -> Result<Self, M::Error>
where
S: Into<String>,
{
let content = Self::make_handle(content)?;
Ok(StyledString {
content,
_phantom: PhantomData,
})
}
/// Sets the content of this string.
///
/// The content will be parsed; if an error is found,
/// it will be returned here (and the content will be unchanged).
pub fn set_content<S>(&mut self, content: S) -> Result<(), M::Error>
where
S: Into<String>,
{
self.content = Self::make_handle(content)?;
Ok(())
}
/// Gives access to the parsed styled spans.
pub fn spans<'a>(&'a self) -> &'a [Span<'a>] {
&self.content
}
}