Skip to main content

parallax_project/
lib.rs

1//! Language-neutral project semantic graph.
2
3#![deny(unsafe_code)]
4#![warn(missing_docs)]
5
6mod graph;
7mod lang;
8
9pub use graph::{
10    DependencyRef, Entrypoint, GraphEdge, GraphEdgeKind, GraphNode, GraphNodeKind, ProjectFile,
11    ProjectGraph, ProjectPackage, Relationship,
12};
13pub use lang::{detect_languages, SourceLanguage, TargetLanguage};
14
15use chrono::{DateTime, Utc};
16use indexmap::IndexMap;
17use parallax_core::{ErrorCode, ParallaxError};
18use parallax_puir::{PuirProgram, TypeInferenceBundle};
19use serde::{Deserialize, Serialize};
20
21/// Analysis snapshot used before migration planning.
22#[derive(Clone, Debug, Serialize, Deserialize)]
23pub struct ProjectAnalysis {
24    /// Root path (absolute).
25    pub root: String,
26    /// Detected primary source language.
27    pub primary_language: SourceLanguage,
28    /// Language mix percentages (0–100), measured from file counts.
29    pub language_mix: IndexMap<String, f64>,
30    /// Semantic graph.
31    pub graph: ProjectGraph,
32    /// Lowered PUIR program.
33    pub puir: PuirProgram,
34    /// Type inference bundle.
35    pub types: TypeInferenceBundle,
36    /// Detected framework if any (express, fastapi, …).
37    pub framework: Option<String>,
38    /// Detected database layer if any.
39    pub database: Option<String>,
40    /// When analysis ran.
41    pub analyzed_at: DateTime<Utc>,
42}
43
44impl ProjectAnalysis {
45    /// Validate embedded IR versions.
46    pub fn validate(&self) -> Result<(), ParallaxError> {
47        self.puir.validate()?;
48        if self.graph.version == 0 {
49            return Err(ParallaxError::new(
50                ErrorCode::InvalidArgument,
51                "project graph version 0 is invalid",
52            )
53            .with_source("parallax-project")
54            .with_operation("validate"));
55        }
56        Ok(())
57    }
58}