use std::path::Path;
use crate::error::NapError;
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct Repository {
pub id: String,
pub workspace_id: String,
pub remote_url: String,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct Workspace {
pub repository_id: String,
pub path: String,
pub branch: String,
pub mode: WorkspaceMode,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum WorkspaceMode {
Durable,
Ephemeral,
Virtual,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct Revision {
pub signature: String,
pub number: u64,
pub branch: String,
pub message: String,
pub author: String,
pub parent_signature: Option<String>,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct Label {
pub revision_signature: String,
pub names: Vec<String>,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct Permission {
pub path_prefix: String,
pub principal: String,
pub access: AccessLevel,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum AccessLevel {
Read,
Write,
None,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct ContextDocument {
pub path: String,
pub metadata: std::collections::HashMap<String, String>,
pub depends_on: Vec<String>,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct CommitInfo {
pub id: String,
pub parent: Option<String>,
pub author: String,
pub message: String,
pub timestamp: String,
}
pub trait VcsBackend: Send + Sync {
fn init(&self, path: &Path) -> Result<(), NapError>;
fn commit(&self, path: &Path, message: &str, author: &str) -> Result<String, NapError>;
fn read_file_at_ref(
&self,
repo_path: &Path,
file_path: &str,
reference: Option<&str>,
) -> Result<String, NapError>;
fn log(
&self,
path: &Path,
file: Option<&str>,
limit: usize,
) -> Result<Vec<CommitInfo>, NapError>;
fn create_branch(&self, path: &Path, name: &str) -> Result<(), NapError>;
fn switch_branch(&self, path: &Path, name: &str) -> Result<(), NapError>;
fn create_tag(&self, path: &Path, name: &str) -> Result<(), NapError>;
fn current_branch(&self, path: &Path) -> Result<String, NapError>;
fn head_hash(&self, path: &Path) -> Result<String, NapError>;
fn revert(&self, _path: &Path, _commit_hash: &str) -> Result<String, NapError> {
Err(NapError::VcsError(
"revert not supported by this VCS backend".to_string(),
))
}
fn list_branches(&self, path: &Path) -> Result<Vec<String>, NapError>;
fn list_tags(&self, path: &Path) -> Result<Vec<String>, NapError>;
fn resolve_branch_head(&self, path: &Path, branch: &str) -> Result<String, NapError> {
let _ = (path, branch);
Err(NapError::VcsError(
"resolve_branch_head not supported by this VCS backend".to_string(),
))
}
fn add_remote(&self, path: &Path, name: &str, url: &str) -> Result<(), NapError>;
fn remove_remote(&self, path: &Path, name: &str) -> Result<(), NapError>;
fn list_remotes(&self, path: &Path) -> Result<Vec<(String, String)>, NapError>;
fn push(&self, path: &Path, remote: Option<&str>, branch: Option<&str>)
-> Result<(), NapError>;
fn pull(&self, path: &Path, remote: Option<&str>, branch: Option<&str>)
-> Result<(), NapError>;
}
impl CommitInfo {
pub fn from_lore_revision(
signature: &str,
parent: Option<&str>,
author: &str,
message: &str,
timestamp: &str,
) -> Self {
Self {
id: signature.to_string(),
parent: parent.map(|p| p.to_string()),
author: author.to_string(),
message: message.to_string(),
timestamp: if timestamp.is_empty() {
chrono::Utc::now().to_rfc3339()
} else {
timestamp.to_string()
},
}
}
}