Skip to main content

omgbase_graph/
lib.rs

1//! # omgbase-graph
2//!
3//! The omgbase graph layer, Rust implementation — the **pure** half: the
4//! semantic nodes a Markdown document's blocks project (links, wikilinks,
5//! tasks, anchors, inline fields) and the authored edge descriptors they and
6//! the frontmatter yield (links, frontmatter relations, inline relations),
7//! plus URI normalization and relative-path resolution. The contract is
8//! `spec/graph/README.md` in the omgbase repository, with the executable
9//! fixtures under `spec/graph/cases`; [`SPEC_VERSION`] is the spec version
10//! this crate conforms to. Resolution to node ids, minting, the edge
11//! intervals and the `doc_edges` rollup read and write the database and live
12//! in `omgbase-store`, which calls this crate inside its commit transaction.
13//!
14//! ```
15//! use omgbase_format::parse_markdown;
16//! use omgbase_graph::{DstKind, NodeKind, Provenance, extract_doc_edges, node_rows, project_nodes};
17//! use omgbase_properties::DocBlock;
18//!
19//! let tree = parse_markdown("# T\n\nSee [x](./x.md#H) and [[note^r1]]\n\nrel:: [[y]]\n");
20//! let ids: Vec<String> = (0..DocBlock::count(&tree.children)).map(|i| format!("b_{i}")).collect();
21//! let blocks = DocBlock::from_blocks(&tree.children, &ids);
22//!
23//! let nodes = project_nodes(&blocks);
24//! let kinds: Vec<NodeKind> = nodes.iter().map(|n| n.kind).collect();
25//! assert_eq!(
26//!     kinds,
27//!     [NodeKind::Link, NodeKind::Wikilink, NodeKind::Anchor, NodeKind::Wikilink, NodeKind::InlineField]
28//! );
29//! assert_eq!(nodes[0].span, Some((4, 17)));
30//! let rows = node_rows("d_0", &nodes);
31//! assert!(rows[0].node_id.starts_with("n_") && rows[0].node_id.len() == 14);
32//!
33//! let edges = extract_doc_edges(&blocks, None);
34//! assert_eq!(edges.len(), 3);
35//! assert_eq!(edges[0].target, "./x.md");
36//! assert_eq!(edges[0].anchor.as_deref(), Some("H"));
37//! assert_eq!(edges[0].dst_kind, DstKind::Document);
38//! assert_eq!(edges[1].dst_kind, DstKind::Block); // `[[note^r1]]`: a block ref
39//! assert_eq!(edges[2].predicate, "rel"); // and `[[y]]` is not also a plain link
40//! assert_eq!(edges[2].provenance, Provenance::InlineField);
41//! ```
42
43#![forbid(unsafe_code)]
44
45pub mod edges;
46pub mod mask;
47pub mod nodes;
48pub mod path;
49pub mod uri;
50
51pub use edges::{
52    AnchorKind, Classified, DstKind, EdgeDescriptor, Provenance, classify, extract_block_edges,
53    extract_doc_edges, extract_frontmatter_edges, split_fragment,
54};
55pub use mask::mask_code_bytes;
56pub use nodes::{NodeKind, NodeRow, ProjectedNode, node_id, node_rows, project_nodes};
57pub use path::{canonical_path, doc_dir, resolve_relative};
58pub use uri::normalize_uri;
59
60/// The `spec/graph/VERSION` this crate implements (`major.minor`).
61pub const SPEC_VERSION: &str = "1.1";
62
63#[cfg(test)]
64mod tests {
65    use super::*;
66
67    #[test]
68    fn spec_version_matches_the_crate_line() {
69        let crate_version = env!("CARGO_PKG_VERSION");
70        assert!(
71            crate_version.starts_with(&format!("{SPEC_VERSION}.")),
72            "crate {crate_version} must track spec {SPEC_VERSION}.x"
73        );
74    }
75}