Skip to content

Commit 683af1d

Browse files
authored
Merge pull request #424 from kivikakk/node-from
nodes: add From impls for AstNode.
2 parents b67d406 + 2e74e20 commit 683af1d

File tree

1 file changed

+47
-3
lines changed

1 file changed

+47
-3
lines changed

src/nodes.rs

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ impl From<(usize, usize, usize, usize)> for Sourcepos {
571571
}
572572

573573
/// Represents the 1-based line and column positions of a given character.
574-
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
574+
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
575575
pub struct LineColumn {
576576
/// The 1-based line number of the character.
577577
pub line: usize,
@@ -615,10 +615,54 @@ impl Ast {
615615

616616
/// The type of a node within the document.
617617
///
618-
/// It is bound by the lifetime `'a`, which corresponds to the `Arena` nodes are allocated in.
619-
/// Child `Ast`s are wrapped in `RefCell` for interior mutability.
618+
/// It is bound by the lifetime `'a`, which corresponds to the `Arena` nodes are
619+
/// allocated in. Child `Ast`s are wrapped in `RefCell` for interior mutability.
620+
///
621+
/// You can construct a new `AstNode` from a `NodeValue` using the `From` trait:
622+
///
623+
/// ```no_run
624+
/// # use comrak::nodes::{AstNode, NodeValue};
625+
/// let root = AstNode::from(NodeValue::Document);
626+
/// ```
627+
///
628+
/// Note that no sourcepos information is given to the created node. If you wish
629+
/// to assign sourcepos information, use the `From` trait to create an `AstNode`
630+
/// from an `Ast`:
631+
///
632+
/// ```no_run
633+
/// # use comrak::nodes::{Ast, AstNode, NodeValue};
634+
/// let root = AstNode::from(Ast::new(
635+
/// NodeValue::Paragraph,
636+
/// (4, 1).into(), // start_line, start_col
637+
/// ));
638+
/// ```
639+
///
640+
/// Adjust the `end` position manually.
641+
///
642+
/// For practical use, you'll probably need it allocated in an `Arena`, in which
643+
/// case you can use `.into()` to simplify creation:
644+
///
645+
/// ```no_run
646+
/// # use comrak::{nodes::{AstNode, NodeValue}, Arena};
647+
/// # let arena = Arena::<AstNode>::new();
648+
/// let node_in_arena = arena.alloc(NodeValue::Document.into());
649+
/// ```
620650
pub type AstNode<'a> = Node<'a, RefCell<Ast>>;
621651

652+
impl<'a> From<NodeValue> for AstNode<'a> {
653+
/// Create a new AST node with the given value. The sourcepos is set to (0,0)-(0,0).
654+
fn from(value: NodeValue) -> Self {
655+
Node::new(RefCell::new(Ast::new(value, LineColumn::default())))
656+
}
657+
}
658+
659+
impl<'a> From<Ast> for AstNode<'a> {
660+
/// Create a new AST node with the given Ast.
661+
fn from(ast: Ast) -> Self {
662+
Node::new(RefCell::new(ast))
663+
}
664+
}
665+
622666
pub(crate) fn last_child_is_open<'a>(node: &'a AstNode<'a>) -> bool {
623667
node.last_child().map_or(false, |n| n.data.borrow().open)
624668
}

0 commit comments

Comments
 (0)