markdown-rs
markdown-rs copied to clipboard
[feature]: `as_<mdast_struct>` api
It would be nice to have a similar api to bson whereby the general (unknown) type has a as_ method for each concrete type.
Something like:
use markdown::{
mdast::{Code, Heading, Paragraph},
ParseOptions,
};
fn main() {
let md = "# Example
A small paragraph.
```rust
fn main() {}
```
";
let mdast = markdown::to_mdast(&md, &ParseOptions::default()).unwrap();
let children = mdast.children().unwrap();
let heading: Heading = children.get(0).unwrap().as_heading().unwrap();
let paragraph: Paragraph = children.get(1).unwrap().as_paragraph().unwrap();
let code: Code = children.get(2).unwrap().as_code().unwrap();
assert_eq!(heading.depth, 1);
assert_eq!(
paragraph.children().unwrap().as_text().unwrap().value,
"A small paragraph."
);
assert_eq!(code.value, "fn main() {}");
}
In other words, something like:
impl Node {
pub fn as_heading(&self) -> Option<&Heading> {
match *self {
Node::Heading(ref h) => Some(h),
_ => None,
}
}
}
I am happy to work on this, if this is something markdown-rs would appreciate.
I am not too well-versed on what’s normal in Rust. But having lots and lots of things on instances seems hard to learn!
The AST here in Rust could be improved though. Not sure what way to go. Perhaps there are good examples of ASTs.
The only AST I am well-versed with is the Babel AST for JavaScript. That is quite different compared to this Markdown structure, because one is hierarchical, and the other is flattened (there is definitely a better word).
Otherwise, it might be useful to look at markedjs for inspiration.
For this instance, if you do not see it fit to include much more access api, then feel free to close this. At the end of the day, it is perfectly easy for me to define and include a trait NodeExt { ... } impl NodeExt for Node { ... } in my code.
I see there are other issues in this repo about improving the AST through stricter types. E.g. what nodes may be (direct) children of other nodes.
Right no, I know JS ASTs! And I think their (babel/marked/etc) choice is incorrect: it is better to treat an AST as data; so plain JSON, no instances. I was wondering about Rust ASTs!
Indeed. Not much time went into the AST here yet.
Closing this specific issue; improving the AST is welcome, as you saw in the other issues; though, it is intentional that ASTs here are data instead of giant complex APIs with tons of methods.