1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
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`][crate::configuration::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`][crate::configuration::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 {
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)"
);
}
}