(file_path: &str, source: &str)
| 86 | |
| 87 | impl MarkdownExtractor { |
| 88 | pub fn extract_markdown(file_path: &str, source: &str) -> ExtractionResult { |
| 89 | let start = Instant::now(); |
| 90 | let mut state = ExtractionState::new(file_path, source); |
| 91 | |
| 92 | let file_node = Node { |
| 93 | id: generate_node_id(file_path, &NodeKind::File, file_path, 0), |
| 94 | kind: NodeKind::File, |
| 95 | name: file_path.to_string(), |
| 96 | qualified_name: file_path.to_string(), |
| 97 | file_path: file_path.to_string(), |
| 98 | start_line: 0, |
| 99 | attrs_start_line: 0, |
| 100 | end_line: source.lines().count().saturating_sub(1) as u32, |
| 101 | start_column: 0, |
| 102 | end_column: 0, |
| 103 | signature: None, |
| 104 | docstring: None, |
| 105 | visibility: Visibility::Pub, |
| 106 | is_async: false, |
| 107 | branches: 0, |
| 108 | loops: 0, |
| 109 | returns: 0, |
| 110 | max_nesting: 0, |
| 111 | unsafe_blocks: 0, |
| 112 | unchecked_calls: 0, |
| 113 | assertions: 0, |
| 114 | updated_at: state.timestamp, |
| 115 | parent_id: None, |
| 116 | }; |
| 117 | let file_node_id = file_node.id.clone(); |
| 118 | state.nodes.push(file_node); |
| 119 | state |
| 120 | .node_stack |
| 121 | .push((file_path.to_string(), file_node_id, 0)); |
| 122 | |
| 123 | if let Ok(tree) = Self::parse(source) { |
| 124 | let root = tree.root_node(); |
| 125 | Self::visit(&mut state, root); |
| 126 | } |
| 127 | |
| 128 | ExtractionResult { |
| 129 | nodes: state.nodes, |
| 130 | edges: state.edges, |
| 131 | unresolved_refs: Vec::new(), |
| 132 | errors: Vec::new(), |
| 133 | duration_ms: start.elapsed().as_millis() as u64, |
| 134 | } |
| 135 | } |
| 136 | |
| 137 | fn parse(source: &str) -> Result<Tree, String> { |
| 138 | let mut parser = Parser::new(); |
nothing calls this directly
no test coverage detected