Skip to main content

kdo_resolver/
lib.rs

1//! Manifest parsers for polyglot workspaces.
2//!
3//! Implements [`ManifestParser`] for Cargo, Node (package.json),
4//! Python (pyproject.toml), and Anchor workspaces.
5
6mod anchor;
7mod cargo;
8mod go;
9mod node;
10mod python;
11
12pub use anchor::AnchorParser;
13pub use cargo::CargoParser;
14pub use go::GoParser;
15pub use node::NodeParser;
16pub use python::PythonParser;
17
18use kdo_core::{Dependency, KdoError, Project};
19use std::path::Path;
20
21/// Trait implemented by each language-specific manifest parser.
22pub trait ManifestParser {
23    /// Returns the canonical manifest filename (e.g., `Cargo.toml`).
24    fn manifest_name(&self) -> &str;
25
26    /// Check whether this parser can handle the given manifest path.
27    fn can_parse(&self, manifest_path: &Path) -> bool;
28
29    /// Parse a manifest file, returning a project and its declared dependencies.
30    ///
31    /// `workspace_root` is used to resolve relative path dependencies.
32    fn parse(
33        &self,
34        manifest_path: &Path,
35        workspace_root: &Path,
36    ) -> Result<(Project, Vec<Dependency>), KdoError>;
37}
38
39/// Detects the appropriate parser for a manifest file and parses it.
40///
41/// Tries parsers in order: Anchor, Cargo, Node, Python.
42pub fn parse_manifest(
43    manifest_path: &Path,
44    workspace_root: &Path,
45) -> Result<(Project, Vec<Dependency>), KdoError> {
46    let parsers: Vec<Box<dyn ManifestParser>> = vec![
47        Box::new(AnchorParser),
48        Box::new(CargoParser),
49        Box::new(NodeParser),
50        Box::new(PythonParser),
51        Box::new(GoParser),
52    ];
53
54    for parser in &parsers {
55        if parser.can_parse(manifest_path) {
56            return parser.parse(manifest_path, workspace_root);
57        }
58    }
59
60    Err(KdoError::ManifestNotFound(manifest_path.to_path_buf()))
61}
62
63/// Returns the list of manifest filenames to scan for.
64pub fn manifest_filenames() -> &'static [&'static str] {
65    &[
66        "Anchor.toml",
67        "Cargo.toml",
68        "package.json",
69        "pyproject.toml",
70        "go.mod",
71    ]
72}