use jiff::Timestamp;
use l10n_embed::Localize;
use l10n_embed_derive::localize;
use pijul_extension::FileSystemRepository;
use pijul_extension::file_system::changes::CreditSource;
use pijul_extension::file_system::open_file::OpenFile;
use crate::vscode_sys;
#[localize("l10n/**/inline_credit/line_annotation.ftl")]
enum AuthorKind<'change_header> {
Local,
Remote {
username: &'change_header str,
},
Unknown {
public_key_signature: &'change_header str,
},
}
#[localize("l10n/**/inline_credit/line_annotation.ftl")]
enum LineAnnotation<'change_header> {
Tracked {
authors: l10n_embed::list::AndList<AuthorKind<'change_header>>,
timestamp: Timestamp,
message: String,
},
Untracked {
timestamp: Timestamp,
},
}
pub fn range<'env>(
env: &'env napi::Env,
open_file: &OpenFile,
line: usize,
) -> Result<vscode_sys::Range<'env>, napi::Error> {
let current_line_contents = open_file
.contents
.text
.get_line(line, ropey::LineType::LF_CR)
.ok_or_else(|| napi::Error::from_reason(format!("no contents for line {line}")))?;
let final_character_offset = current_line_contents.len() as u32;
let start = vscode_sys::Position::new(env, line as u32, final_character_offset)?;
let end = vscode_sys::Position::new(env, line as u32, final_character_offset)?;
vscode_sys::Range::new(env, &start, &end)
}
pub fn render(
localization_context: &l10n_embed::Context,
repository: &FileSystemRepository,
text_document: &vscode_sys::TextDocument,
open_file: &OpenFile,
credit_source: &CreditSource,
) -> Result<String, napi::Error> {
let annotation = match credit_source {
CreditSource::Tracked { vertex } => {
let change = repository.get_change(vertex.change).map_err(|error| {
napi::Error::from_reason(format!(
"Unable to get change for vertex {vertex:#?}: {error}"
))
})?;
let authors = repository
.authors_for_change(&change.header)
.into_iter()
.map(|author_source| match author_source {
pijul_extension::author::AuthorSource::Local(_identity) => AuthorKind::Local,
pijul_extension::author::AuthorSource::Remote(identity) => AuthorKind::Remote {
username: &identity.config.author.username,
},
pijul_extension::author::AuthorSource::Unknown(public_key_signature) => {
AuthorKind::Unknown {
public_key_signature,
}
}
})
.collect();
LineAnnotation::Tracked {
authors: l10n_embed::list::AndList::new(authors),
timestamp: change.header.timestamp,
message: change.hashed.header.message,
}
}
CreditSource::Untracked { .. } => {
let timestamp = if text_document.get_is_dirty()? {
Timestamp::now()
} else {
open_file.contents.modified_time
};
LineAnnotation::Untracked { timestamp }
}
};
let mut localized_annotation = String::new();
annotation.localize(localization_context, &mut localized_annotation);
Ok(localized_annotation)
}