1pub mod body;
2pub mod frontmatter;
3pub mod identity;
4
5use std::path::Path;
6
7use crate::config::Config;
8use crate::error::Result;
9use crate::model::{Confidence, Node, RawEdge};
10
11pub struct ParsedDocument {
13 pub node: Node,
14 pub raw_edges: Vec<RawEdge>,
15}
16
17pub fn parse_document(path: &Path, content: &str, config: &Config) -> Result<ParsedDocument> {
19 let (mut node, body) = frontmatter::parse_frontmatter(path, content)?;
21
22 if node.kind.as_str().is_empty() {
24 node.kind = identity::infer_kind(path, config);
25 }
26
27 if node.id.is_empty() {
29 node.id = identity::infer_id(path, &node.kind, config);
30 }
31
32 let mut raw_edges = body::extract_links(&body, &config.parser.link_patterns);
34
35 for target in &node.supersedes {
37 raw_edges.push(RawEdge {
38 target_path: target.clone(),
39 relation: "supersedes".to_string(),
40 confidence: Confidence::Extracted,
41 location: "frontmatter:supersedes".to_string(),
42 });
43 }
44 for target in &node.implements {
45 raw_edges.push(RawEdge {
46 target_path: target.clone(),
47 relation: "implements".to_string(),
48 confidence: Confidence::Extracted,
49 location: "frontmatter:implements".to_string(),
50 });
51 }
52 for target in &node.related {
53 raw_edges.push(RawEdge {
54 target_path: target.clone(),
55 relation: "related".to_string(),
56 confidence: Confidence::Extracted,
57 location: "frontmatter:related".to_string(),
58 });
59 }
60
61 Ok(ParsedDocument { node, raw_edges })
62}