gritpack-searchlib 0.1.0

Compiler-facing resolver and grammar integration surface for Gritpack
Documentation
//! Build-side grammar model for Gritpack resolver indexes.
//!
//! A driver supplies a [`GrammarSpec`] to the write side. Gritpack uses that data
//! to compile private resolver indexes. The read side never re-runs driver logic.
//!
//! # Example
//!
//! ```rust
//! use gritpack_searchlib::grammar::{
//!     CompletenessRules, DeclarationRules, DirectoryNamespaceMode, ExternalDriverPayload,
//!     ExternalDriverFilePayload, ExternalDriverRule, GrammarCapabilities, GrammarId,
//!     GrammarSpec, NamespaceRules, PathPattern, SourceFileRules, SourceRootStrategy,
//! };
//!
//! let grammar = GrammarSpec {
//!     id: GrammarId {
//!         dialect: "lumen/1.0.0".to_string(),
//!         name: "modules".to_string(),
//!         version: 1,
//!     },
//!     capabilities: GrammarCapabilities {
//!         authoritative_negative_lookup: true,
//!         supports_prefix_queries: true,
//!         supports_child_enumeration: true,
//!         supports_multi_file_modules: false,
//!     },
//!     source_files: SourceFileRules {
//!         include: vec![PathPattern {
//!             value: "src/**".to_string(),
//!         }],
//!         exclude: Vec::new(),
//!         extensions: vec!["zing".to_string()],
//!         root_strategy: SourceRootStrategy::ManifestSourceRoot,
//!     },
//!     namespace: NamespaceRules {
//!         separator: "::".to_string(),
//!         case_sensitive: true,
//!         allow_empty_segments: false,
//!         directory_layout: DirectoryNamespaceMode::AppendDirectories,
//!     },
//!     declarations: DeclarationRules::ExternalDriver(ExternalDriverRule {
//!         name: "lumen/modules".to_string(),
//!     }),
//!     completeness: CompletenessRules {
//!         negative_lookup_authoritative: true,
//!         prefix_authoritative: true,
//!         child_enumeration_authoritative: true,
//!     },
//! };
//!
//! let payload = ExternalDriverPayload {
//!     driver_name: "lumen/modules".to_string(),
//!     files: vec![ExternalDriverFilePayload {
//!         file_path: "/workspace/project/.gritpack/packages/dep/1.0.0/lumen_1.0.0/generic/src/lib.zing"
//!             .to_string(),
//!         declared_names: vec!["demo::thing".to_string()],
//!     }],
//! };
//! # let _ = grammar;
//! # let _ = payload;
//! ```

#![allow(dead_code)]

#[derive(
    Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize, serde::Deserialize,
)]
pub struct GrammarId {
    pub dialect: String,
    pub name: String,
    pub version: u32,
}

#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct GrammarCapabilities {
    pub authoritative_negative_lookup: bool,
    pub supports_prefix_queries: bool,
    pub supports_child_enumeration: bool,
    pub supports_multi_file_modules: bool,
}

#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct GrammarSpec {
    pub id: GrammarId,
    #[serde(default)]
    pub capabilities: GrammarCapabilities,
    #[serde(default)]
    pub source_files: SourceFileRules,
    #[serde(default)]
    pub namespace: NamespaceRules,
    pub declarations: DeclarationRules,
    #[serde(default)]
    pub completeness: CompletenessRules,
}

#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct PathPattern {
    pub value: String,
}

#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct SourceFileRules {
    #[serde(default)]
    pub include: Vec<PathPattern>,
    #[serde(default)]
    pub exclude: Vec<PathPattern>,
    #[serde(default)]
    pub extensions: Vec<String>,
    #[serde(default)]
    pub root_strategy: SourceRootStrategy,
}

impl Default for SourceFileRules {
    fn default() -> Self {
        Self {
            include: Vec::new(),
            exclude: Vec::new(),
            extensions: Vec::new(),
            root_strategy: SourceRootStrategy::PackageRoot,
        }
    }
}

#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum SourceRootStrategy {
    #[default]
    PackageRoot,
    ManifestSourceRoot,
    ExplicitRoots(Vec<String>),
}

#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct NamespaceRules {
    pub separator: String,
    pub case_sensitive: bool,
    pub allow_empty_segments: bool,
    #[serde(default)]
    pub directory_layout: DirectoryNamespaceMode,
}

impl Default for NamespaceRules {
    fn default() -> Self {
        Self {
            separator: "::".to_string(),
            case_sensitive: true,
            allow_empty_segments: false,
            directory_layout: DirectoryNamespaceMode::IgnoreDirectories,
        }
    }
}

#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum DirectoryNamespaceMode {
    #[default]
    IgnoreDirectories,
    AppendDirectories,
}

#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum DeclarationRules {
    TokenSequence(TokenSequenceRule),
    PatternSet(Vec<PatternRule>),
    ExternalDriver(ExternalDriverRule),
}

#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct TokenSequenceRule {
    #[serde(default)]
    pub tokens: Vec<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct PatternRule {
    pub pattern: String,
}

#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct ExternalDriverRule {
    pub name: String,
}

#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct ExternalDriverPayload {
    pub driver_name: String,
    #[serde(default)]
    pub files: Vec<ExternalDriverFilePayload>,
}

#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct ExternalDriverFilePayload {
    pub file_path: String,
    #[serde(default)]
    pub declared_names: Vec<String>,
}

#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct CompletenessRules {
    pub negative_lookup_authoritative: bool,
    pub prefix_authoritative: bool,
    pub child_enumeration_authoritative: bool,
}