pub struct Repo {
pub index_file: String,
pub scanned_folders: HashSet<PathBuf>,
pub queued_folders: HashMap<PathBuf, QueuedFolder>,
pub markdown_files: MarkdownFiles,
pub other_files: OtherFiles,
pub tag_index: Arc<TagIndex>,
pub relationship_index: Arc<RelationshipIndex>,
pub wikilink_index: Arc<WikilinkIndex>,
/* private fields */
}Fields§
§index_file: StringThe configured index file name (e.g., “index.md” or “_index.md”). Exposed in site.json for frontend use.
scanned_folders: HashSet<PathBuf>Every folder walked so far, by its canonical key, so a directory reached twice (a symlink to a folder that is also walked directly) is listed once.
queued_folders: HashMap<PathBuf, QueuedFolder>Folders found but not walked yet, by key (the folder’s path as listed, not canonicalized — the next hop canonicalizes it).
markdown_files: MarkdownFiles§other_files: OtherFiles§tag_index: Arc<TagIndex>Thread-safe index of tagged pages.
relationship_index: Arc<RelationshipIndex>Thread-safe index of typed relationships between notes.
wikilink_index: Arc<WikilinkIndex>Thread-safe global name index for body-wikilink ([[Name]]) resolution.
Always built (independent of relationship tracking).
Implementations§
Source§impl Repo
impl Repo
Sourcepub fn with_change_tracking(self) -> Self
pub fn with_change_tracking(self) -> Self
Records a FileStamp for every file the scan indexes, which is what
Self::diff_vault and Self::snapshot compare against. Call
before scanning.
Sourcepub fn tracks_changes(&self) -> bool
pub fn tracks_changes(&self) -> bool
Whether Self::with_change_tracking was called.
Sourcepub fn snapshot_fingerprint(&self) -> String
pub fn snapshot_fingerprint(&self) -> String
Identifies everything a snapshot’s contents depend on besides the files themselves: this build (the frontmatter simplifier changes between versions) and the scan configuration (which files are notes, which are ignored, how URLs are formed).
Sourcepub fn snapshot(&self) -> RepoSnapshot
pub fn snapshot(&self) -> RepoSnapshot
The repository’s current contents as a RepoSnapshot: every indexed
file of the root vault that has a stamp (so only with change tracking).
Sourcepub fn restore_snapshot(
&self,
snapshot: RepoSnapshot,
) -> Result<usize, SnapshotError>
pub fn restore_snapshot( &self, snapshot: RepoSnapshot, ) -> Result<usize, SnapshotError>
Fills an empty repository from snapshot without reading storage, and
rebuilds the tag index from the restored frontmatter. Returns the
number of files restored.
The caller then does what it does after a scan — build the
relationship and wikilink indexes, mark the scan complete — and runs a
Self::diff_vault to catch what changed since the snapshot. Entries
that no longer parse as vault paths are dropped (the diff re-adds
them if they exist). Stamps are restored with them, so with change
tracking the diff compares against the snapshot’s view.
Sourcepub fn diff_vault(&self) -> RepoDiff
pub fn diff_vault(&self) -> RepoDiff
Re-lists the vault (and an external static overlay) with the scan’s ignore rules and compares every file with its recorded stamp. Reads no file contents. Blocking.
A folder whose listing is not downloaded (see
RepoDiff::not_downloaded_folders) is requested from the vault on
every diff until it lists; the files the index already has under it
are kept, not deleted.
Without change tracking every listed file is “created” — the diff of a repository that recorded nothing.
Sourcepub fn record_diff(&self, diff: &RepoDiff)
pub fn record_diff(&self, diff: &RepoDiff)
Stores the stamps of a diff once its events have been applied, so the same changes are not reported again. A no-op without change tracking.
Sourcepub fn not_downloaded_folder_count(&self) -> usize
pub fn not_downloaded_folder_count(&self) -> usize
How many folders could not be listed because their contents are not
downloaded yet, as of the last scan or Repo::record_diff. Their
download has been requested; a later Repo::diff_vault lists them.
Source§impl Repo
impl Repo
pub fn init_from_config(c: &Config) -> Self
Sourcepub fn with_symlink_mounts(self, enabled: bool) -> Self
pub fn with_symlink_mounts(self, enabled: bool) -> Self
Turns read-only symlink mounts off (enabled == false): the
operator’s --no-symlink-mounts / MBR_NO_SYMLINK_MOUNTS. The vaults
are rebuilt as plain LocalVaults on the same (canonical) roots, so a
link out of the repository or the overlay is OutsideRoot — 404 on the
server, not placed by a build — exactly as before mounts. Hidden-file
blocking is unaffected. Logs one line when it disables anything.
Call before scanning: it replaces the storage the scan reads through.
Re-admits the hidden directories the user named on the command line
(Config::explicit_hidden_dirs) to the scan.
A builder rather than an Self::init parameter: init already carries
eight positional arguments, and every caller but the two live entry
points wants the default of “no exemptions”.
Rebasing happens here, once, and onto canonical_root rather than the
configured root — the scan descends from the canonicalized root, so an
exemption built from the configured spelling would silently never match
wherever the two differ (/tmp vs /private/tmp on macOS).
The hidden directories the user named on the command line, as vault
paths of Self::vault — the exemption to “hidden files are never
served” (see crate::vault::has_hidden_segment).
Sourcepub fn init<S: Into<String>, P: Into<PathBuf>>(
root_dir: P,
static_folder: S,
markdown_extensions: &[String],
ignore_dirs: &[String],
ignore_globs: &[String],
index_file: S,
tag_sources: &[TagSource],
relationship_types: &[RelationType],
) -> Self
pub fn init<S: Into<String>, P: Into<PathBuf>>( root_dir: P, static_folder: S, markdown_extensions: &[String], ignore_dirs: &[String], ignore_globs: &[String], index_file: S, tag_sources: &[TagSource], relationship_types: &[RelationType], ) -> Self
A repository on the local filesystem at root_dir, stored through a
LocalVault (plus a second one for an external static overlay).
Both vaults serve symlinks out of them as read-only mounts
(crate::vault::MountPolicy), each protecting the other’s root, so
the server and the static build — which both start here — mount
exactly the same folders and refuse exactly the same targets.
Sourcepub fn init_with_vault<S: Into<String>>(
vault: Arc<dyn Vault>,
static_folder: S,
markdown_extensions: &[String],
ignore_dirs: &[String],
ignore_globs: &[String],
index_file: S,
tag_sources: &[TagSource],
relationship_types: &[RelationType],
) -> Self
pub fn init_with_vault<S: Into<String>>( vault: Arc<dyn Vault>, static_folder: S, markdown_extensions: &[String], ignore_dirs: &[String], ignore_globs: &[String], index_file: S, tag_sources: &[TagSource], relationship_types: &[RelationType], ) -> Self
A repository stored in vault, which may be anything — the desktop’s
LocalVault, a test’s crate::vault::MemVault, a platform vault.
static_folder is honoured when it names a folder inside the vault;
an external overlay is a second vault, given with
Self::with_static_vault (Self::init does both for a local
repository).
Sourcepub fn with_static_vault(self, static_vault: Option<Arc<dyn Vault>>) -> Self
pub fn with_static_vault(self, static_vault: Option<Arc<dyn Vault>>) -> Self
Sets the vault of an external static overlay (see the field docs). Its assets are indexed with the overlay prefix stripped from their URLs, and markdown inside it is skipped.
Sourcepub fn static_vault(&self) -> Option<&Arc<dyn Vault>>
pub fn static_vault(&self) -> Option<&Arc<dyn Vault>>
The external static overlay’s storage, when there is one.
Sourcepub fn canonical_static_root(&self) -> Option<&Path>
pub fn canonical_static_root(&self) -> Option<&Path>
The external static overlay’s canonical directory, when there is one.
Sourcepub fn locate(&self, key: &Path) -> Option<(&dyn Vault, VaultPath)>
pub fn locate(&self, key: &Path) -> Option<(&dyn Vault, VaultPath)>
Which vault holds the file behind an index key, and where in it.
None for a key under neither — which no scan produces, but the watcher
can report (a configured template folder outside the root).
Self::locate, with the vault shared rather than borrowed — for a
caller that reads it from another task (a streamed response body).
Sourcepub fn mounts(&self) -> Vec<(PathBuf, Mount)>
pub fn mounts(&self) -> Vec<(PathBuf, Mount)>
The symlink mounts both vaults have accepted so far, each with the index
key of its location (where the link is). Grows as the first scan
discovers links; see crate::vault::Mount.
Sourcepub fn static_folder_vault(&self) -> Option<(&Arc<dyn Vault>, VaultPath)>
pub fn static_folder_vault(&self) -> Option<(&Arc<dyn Vault>, VaultPath)>
The vault holding the static folder and the folder’s path in it: the
external overlay from its root, or the configured folder inside the
repository. None when there is no static folder.
Sourcepub fn scan_folder<P: AsRef<Path>>(
&self,
relative_folder_path: &P,
) -> Result<(), RepoError>
pub fn scan_folder<P: AsRef<Path>>( &self, relative_folder_path: &P, ) -> Result<(), RepoError>
Scans one folder of the root vault (non-recursively: subfolders are
queued in Self::queued_folders, not walked).
relative_folder_path is relative to the root. One that climbs out of
it is skipped with a warning, as a folder that resolves out of it is.
Sourcepub fn scan_vault_folder(&self, folder: &VaultPath) -> Result<(), RepoError>
pub fn scan_vault_folder(&self, folder: &VaultPath) -> Result<(), RepoError>
Self::scan_folder for a folder given as a vault path.
pub fn scan_all(&self) -> Result<(), RepoError>
Sourcepub fn scan_static_folder(&self) -> Result<(), RepoError>
pub fn scan_static_folder(&self) -> Result<(), RepoError>
Scan the static folder and its subdirectories. Deferred from scan_all() so mark_scan_complete() fires faster.
Sourcepub fn mark_scan_complete(&self)
pub fn mark_scan_complete(&self)
Mark the initial scan as complete and notify any waiters.
Sourcepub fn full_rescan(&self)
pub fn full_rescan(&self)
Drop every cached view of the repository and rebuild it from disk.
Used by the watcher when a change batch is too large to invalidate file
by file. Blocking; call from spawn_blocking.
No step may return early. clear() resets media_populated, so any
path that skips Repo::notify_media_populated leaves every later
Repo::wait_for_media — that is, /.mbr/media.json — blocked for the
life of the process. A failed scan is logged and the pass continues on
whatever was indexed: clear() already discarded the previous contents,
so the real choice is between serving partial data and hanging.
Sourcepub fn populate_basic_metadata(&self)
pub fn populate_basic_metadata(&self)
Populate basic file metadata (size, timestamps) for all other files. Deferred from scan_folder() to avoid blocking scan_all() completion, so search (which only needs markdown files) can proceed sooner.
Sourcepub fn is_scan_complete(&self) -> bool
pub fn is_scan_complete(&self) -> bool
Returns true if the initial scan has completed.
Sourcepub async fn wait_for_scan(&self)
pub async fn wait_for_scan(&self)
Wait for the initial scan to complete. Returns immediately if already done.
mark_scan_complete() fires exactly once and Notify::notify_waiters()
stores no permit, so a notification observed between a flag check and the
registration of the waiter would be lost forever — and /.mbr/site.json
would block for the life of the process. Registering interest before
re-checking closes that window (same pattern as the in-flight waits in
server.rs).
Sourcepub fn is_media_populated(&self) -> bool
pub fn is_media_populated(&self) -> bool
Returns true if media metadata has been populated.
Sourcepub fn notify_media_populated(&self)
pub fn notify_media_populated(&self)
Notify waiters that media metadata population is complete.
Sourcepub async fn wait_for_media(&self)
pub async fn wait_for_media(&self)
Wait for media metadata to be populated. Returns immediately if already done.
Registers interest before re-checking the flag, for the same reason as
Repo::wait_for_scan.
pub fn to_json(&self) -> Result<String>
Sourcepub fn populate_media_metadata(&self)
pub fn populate_media_metadata(&self)
Populate media metadata (ffmpeg/lopdf) for all static files. This is deferred from initial scan to avoid blocking the first site.json response.
Sourcepub fn ensure_text_extracted(&self)
pub fn ensure_text_extracted(&self)
Extract text from searchable files (PDFs, text files) for search indexing. Deferred from initial scan since text is only needed for search.
Sourcepub fn clear(&self)
pub fn clear(&self)
Clear all cached data, forcing a full rescan on next scan_all() call.
Call this when files are added, removed, or modified to ensure the next scan picks up the changes.
Sourcepub fn invalidate_file(&self, abs_path: &Path, event: &ChangeEventType)
pub fn invalidate_file(&self, abs_path: &Path, event: &ChangeEventType)
Surgically invalidate a single file, updating only the affected cache entries.
Much cheaper than clear() + scan_all() for small batches of file changes.
Sourcepub fn tag_sources(&self) -> &[TagSource]
pub fn tag_sources(&self) -> &[TagSource]
Rebuild the tag index from the current cached markdown files.
Call this after surgical file invalidation when tags may have changed (e.g., after deleting or modifying markdown files). Returns the configured tag sources.
Sourcepub fn build_relationship_index(&self)
pub fn build_relationship_index(&self)
Rebuild the relationship index from the current cached markdown files.
Must run after a scan (or file-change invalidation) once all note titles
are known, since endpoint resolution matches on titles and filename
stems across the whole repo. Modelled on Self::rebuild_tag_index.
Sourcepub fn build_wikilink_index(&self)
pub fn build_wikilink_index(&self)
Rebuild the global wikilink name index from the current cached markdown files.
Unlike Self::build_relationship_index this is ungated — the index
powers Obsidian-style [[Name]] body-link resolution for every repo, so
it is rebuilt whenever the repo is (re)scanned or a file changes. Must run
after a scan once all note titles/stems are known.
pub fn rebuild_tag_index(&self)
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for Repo
impl !RefUnwindSafe for Repo
impl !UnwindSafe for Repo
impl Send for Repo
impl Sync for Repo
impl Unpin for Repo
impl UnsafeUnpin for Repo
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
Source§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();Source§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
Source§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
Source§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
Source§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
Source§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
Source§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
Source§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
Source§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
Source§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();Source§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
Source§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
Source§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
Source§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
Source§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
Source§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
Source§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
Source§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
Source§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
Source§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
Source§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling Attribute value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();Source§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
Source§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi Quirk value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();Source§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
Source§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the Condition value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);