diff options
Diffstat (limited to 'src/util/mdx.rs')
-rw-r--r-- | src/util/mdx.rs | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/src/util/mdx.rs b/src/util/mdx.rs new file mode 100644 index 0000000..712b2c7 --- /dev/null +++ b/src/util/mdx.rs @@ -0,0 +1,131 @@ +extern crate alloc; + +use alloc::string::String; + +/// Signal used as feedback when parsing MDX ESM/expressions. +#[derive(Clone, Debug)] +pub enum Signal { + /// A syntax error. + /// + /// `markdown-rs` will crash with error message `String`, and convert the + /// `usize` (byte offset into `&str` passed to `MdxExpressionParse` or + /// `MdxEsmParse`) to where it happened in the whole document. + /// + /// ## Examples + /// + /// ```rust ignore + /// Signal::Error("Unexpected `\"`, expected identifier".into(), 1) + /// ``` + Error(String, usize), + /// An error at the end of the (partial?) expression. + /// + /// `markdown-rs` will either crash with error message `String` if it + /// doesn’t have any more text, or it will try again later when more text + /// is available. + /// + /// ## Examples + /// + /// ```rust ignore + /// Signal::Eof("Unexpected end of file in string literal".into()) + /// ``` + Eof(String), + /// Done, successfully. + /// + /// `markdown-rs` knows that this is the end of a valid expression/esm and + /// continues with markdown. + /// + /// ## Examples + /// + /// ```rust ignore + /// Signal::Ok + /// ``` + Ok, +} + +/// Signature of a function that parses MDX ESM. +/// +/// Can be passed as `mdx_esm_parse` in [`ParseOptions`][] to support +/// ESM according to a certain grammar (typically, a programming language). +pub type EsmParse = dyn Fn(&str) -> Signal; + +/// Expression kind. +#[derive(Clone, Debug)] +pub enum ExpressionKind { + /// Kind of expressions in prose. + /// + /// ```mdx + /// > | # {Math.PI} + /// ^^^^^^^^^ + /// | + /// > | {Math.PI} + /// ^^^^^^^^^ + /// ``` + Expression, + /// Kind of expressions as attributes. + /// + /// ```mdx + /// > | <a {...b}> + /// ^^^^^^ + /// ``` + AttributeExpression, + /// Kind of expressions as attribute values. + /// + /// ```mdx + /// > | <a b={c}> + /// ^^^ + /// ``` + AttributeValueExpression, +} + +/// Signature of a function that parses MDX expressions. +/// +/// Can be passed as `mdx_expression_parse` in [`ParseOptions`][] to support +/// expressions according to a certain grammar (typically, a programming +/// language). +/// +pub type ExpressionParse = dyn Fn(&str, &ExpressionKind) -> Signal; + +#[cfg(test)] +mod tests { + extern crate std; + use super::*; + use alloc::boxed::Box; + + #[test] + fn test_mdx_expression_parse() { + fn func(_value: &str, _kind: &ExpressionKind) -> Signal { + Signal::Ok + } + + let func_accepting = |_a: Box<ExpressionParse>| true; + + assert!( + matches!(func("a", &ExpressionKind::Expression), Signal::Ok), + "should expose an `ExpressionParse` type (1)" + ); + + assert!( + func_accepting(Box::new(func)), + "should expose an `ExpressionParse` type (2)" + ); + } + + #[test] + fn test_mdx_esm_parse() { + fn func(_value: &str) -> Signal { + Signal::Ok + } + + let func_accepting = |_a: Box<EsmParse>| true; + + assert!( + matches!(func("a"), Signal::Ok), + "should expose an `EsmParse` type (1)" + ); + + assert!( + func_accepting(Box::new(func)), + "should expose an `EsmParse` type (2)" + ); + } +} |