heroforge-core 0.2.2

Pure Rust core library for reading and writing Fossil SCM repositories
Documentation
//! History/commit browsing builder.

use crate::error::Result;
use crate::repo::{CheckIn, Repository};

/// Builder for history operations.
pub struct HistoryBuilder<'a> {
    repo: &'a Repository,
}

impl<'a> HistoryBuilder<'a> {
    pub(crate) fn new(repo: &'a Repository) -> Self {
        Self { repo }
    }

    /// Get the latest commit on trunk.
    pub fn trunk_tip(&self) -> Result<CheckIn> {
        self.repo.branch_tip_internal("trunk")
    }

    /// Get the latest commit on a branch.
    pub fn branch_tip(&self, branch: &str) -> Result<CheckIn> {
        self.repo.branch_tip_internal(branch)
    }

    /// Get recent commits across all branches.
    pub fn recent(&self, limit: usize) -> Result<Vec<CheckIn>> {
        self.repo.recent_checkins_internal(limit)
    }

    /// Get a specific commit by hash.
    pub fn get(&self, hash: &str) -> Result<CheckIn> {
        self.repo.get_checkin_internal(hash)
    }

    /// Query commits on a specific branch.
    pub fn on_branch(&self, branch: &str) -> HistoryQuery<'a> {
        HistoryQuery {
            repo: self.repo,
            branch: Some(branch.to_string()),
            limit: None,
        }
    }

    /// Query commits on trunk.
    pub fn on_trunk(&self) -> HistoryQuery<'a> {
        HistoryQuery {
            repo: self.repo,
            branch: Some("trunk".to_string()),
            limit: None,
        }
    }
}

/// Query for commits with filters.
pub struct HistoryQuery<'a> {
    repo: &'a Repository,
    branch: Option<String>,
    limit: Option<usize>,
}

impl<'a> HistoryQuery<'a> {
    /// Limit the number of results.
    pub fn limit(mut self, n: usize) -> Self {
        self.limit = Some(n);
        self
    }

    /// Execute the query and return commits.
    pub fn list(&self) -> Result<Vec<CheckIn>> {
        // For now, we get recent checkins and filter by branch
        // A more efficient implementation would query the database directly
        let limit = self.limit.unwrap_or(100);
        let all = self.repo.recent_checkins_internal(limit * 2)?;

        if let Some(_branch) = &self.branch {
            // Filter by branch - would need branch info on CheckIn
            // For now, return all and let caller filter
            // TODO: Add branch filtering when CheckIn has branch info
            Ok(all.into_iter().take(limit).collect())
        } else {
            Ok(all.into_iter().take(limit).collect())
        }
    }
}