///|
pub enum WorktreeKind {
Regular
Symlink(target~ : String)
}
///|
pub struct WorktreeEntry {
kind : WorktreeKind
mode : Int
size : Int?
mtime_sec : Int?
mtime_nsec : Int?
}
///|
pub enum WorktreeKindMeta {
Regular
Symlink
}
///|
pub struct WorktreeEntryMeta {
kind : WorktreeKindMeta
mode : Int
size : Int?
mtime_sec : Int?
mtime_nsec : Int?
dev : Int?
ino : Int?
uid : Int?
gid : Int?
}
///|
pub fn WorktreeKindMeta::regular() -> WorktreeKindMeta {
Regular
}
///|
pub fn WorktreeKindMeta::symlink() -> WorktreeKindMeta {
Symlink
}
///|
pub fn WorktreeEntryMeta::new(
kind : WorktreeKindMeta,
mode : Int,
size : Int?,
mtime_sec : Int?,
mtime_nsec : Int?,
dev? : Int? = None,
ino? : Int? = None,
uid? : Int? = None,
gid? : Int? = None,
) -> WorktreeEntryMeta {
{ kind, mode, size, mtime_sec, mtime_nsec, dev, ino, uid, gid }
}
///|
pub fn WorktreeEntryMeta::mtime(self : WorktreeEntryMeta) -> (Int, Int) {
(self.mtime_sec.unwrap_or(0), self.mtime_nsec.unwrap_or(0))
}
///|
pub struct WorktreeProbeProvider {
entry_meta : async (&@types.RepoFileSystem, String) -> WorktreeEntryMeta? noraise
entry_meta_sync : (&@types.RepoFileSystem, String) -> WorktreeEntryMeta?
lstat : (String) -> WorktreeEntryMeta?
symlink_target : (String) -> String?
readdir_typed : (String) -> Array[(String, Int)]?
}
///|
pub fn WorktreeProbeProvider::new(
entry_meta : async (&@types.RepoFileSystem, String) -> WorktreeEntryMeta? noraise,
symlink_target : (String) -> String?,
entry_meta_sync? : (&@types.RepoFileSystem, String) -> WorktreeEntryMeta?,
lstat? : (String) -> WorktreeEntryMeta?,
readdir_typed? : (String) -> Array[(String, Int)]?,
) -> WorktreeProbeProvider {
let sync_fn = match entry_meta_sync {
Some(f) => f
None => fn(_fs, _path) { None }
}
let lstat_fn = match lstat {
Some(f) => f
None => fn(_path) { None }
}
let readdir_fn = match readdir_typed {
Some(f) => f
None => fn(_path) { None }
}
{
entry_meta,
entry_meta_sync: sync_fn,
lstat: lstat_fn,
symlink_target,
readdir_typed: readdir_fn,
}
}
///|
pub fn WorktreeProbeProvider::none() -> WorktreeProbeProvider {
let fallback_meta : (&@types.RepoFileSystem, String) -> WorktreeEntryMeta? = fn(
fs,
path,
) {
if fs.is_file(path) {
Some(
WorktreeEntryMeta::new(
WorktreeKindMeta::regular(),
0o100644,
None,
None,
None,
),
)
} else {
None
}
}
{
entry_meta: fn(
fs : &@types.RepoFileSystem,
path : String,
) -> WorktreeEntryMeta? noraise {
fallback_meta(fs, path)
},
entry_meta_sync: fallback_meta,
lstat: fn(_path) { None },
symlink_target: fn(_ : String) { None },
readdir_typed: fn(_path) { None },
}
}
///|
priv struct WorktreeProbeBox {
mut value : WorktreeProbeProvider
}
///|
let worktree_probe_box : WorktreeProbeBox = {
value: WorktreeProbeProvider::none(),
}
///|
pub fn set_worktree_probe(provider : WorktreeProbeProvider) -> Unit {
worktree_probe_box.value = provider
}
///|
pub async fn worktree_entry_meta(
fs : &@types.RepoFileSystem,
abs_path : String,
) -> WorktreeEntryMeta? noraise {
(worktree_probe_box.value.entry_meta)(fs, abs_path)
}
///|
pub fn worktree_entry_meta_sync(
fs : &@types.RepoFileSystem,
abs_path : String,
) -> WorktreeEntryMeta? {
(worktree_probe_box.value.entry_meta_sync)(fs, abs_path)
}
///|
/// Stat a file without requiring RepoFileSystem. Uses the native lstat provider
/// when available, otherwise returns None.
pub fn lstat_entry_meta(abs_path : String) -> WorktreeEntryMeta? {
(worktree_probe_box.value.lstat)(abs_path)
}
///|
pub fn read_symlink_target_path(path : String) -> String? {
(worktree_probe_box.value.symlink_target)(path)
}
///|
/// Read directory entries with file type info. Returns (name, d_type) pairs.
/// d_type: 4=DT_DIR, 8=DT_REG, 10=DT_LNK, 0=DT_UNKNOWN.
/// Returns None if native readdir is not available (fallback to fs.readdir + is_dir).
pub fn readdir_typed(path : String) -> Array[(String, Int)]? {
(worktree_probe_box.value.readdir_typed)(path)
}
///|
pub async fn worktree_entry(
fs : &@types.RepoFileSystem,
abs_path : String,
) -> WorktreeEntry? noraise {
let meta = worktree_entry_meta(fs, abs_path)
match meta {
None => None
Some(info) =>
match info.kind {
WorktreeKindMeta::Regular =>
Some({
kind: WorktreeKind::Regular,
mode: info.mode,
size: info.size,
mtime_sec: info.mtime_sec,
mtime_nsec: info.mtime_nsec,
})
WorktreeKindMeta::Symlink =>
match read_symlink_target_path(abs_path) {
Some(target) =>
Some({
kind: WorktreeKind::Symlink(target~),
mode: info.mode,
size: info.size,
mtime_sec: info.mtime_sec,
mtime_nsec: info.mtime_nsec,
})
None => None
}
}
}
}