pub struct DepGraph { /* private fields */ }Expand description
Dependency graph mapping consumers to their dependencies.
Persisted to target/ssg-cache/depgraph.json. Loaders are
poisoning-resistant: a missing, truncated, or version-mismatched
file yields an empty graph — caller falls back to a full rebuild
without crashing or producing stale output (AC6).
Implementations§
Source§impl DepGraph
impl DepGraph
Sourcepub fn new() -> Self
pub fn new() -> Self
Creates an empty dependency graph at the current schema version.
§Examples
use ssg::depgraph::DepGraph;
let g = DepGraph::new();
assert_eq!(g.page_count(), 0);Sourcepub fn load(cache_root: &Path) -> Self
pub fn load(cache_root: &Path) -> Self
Loads the graph from <cache_root>/depgraph.json.
Returns an empty graph if the file is missing, unreadable, malformed, or written by an incompatible schema version. The poisoning-resistant return matches AC6.
§Examples
use ssg::depgraph::DepGraph;
use tempfile::tempdir;
let dir = tempdir().unwrap();
// Missing cache file ⇒ empty graph (no panic, no error).
let g = DepGraph::load(dir.path());
assert_eq!(g.page_count(), 0);Sourcepub fn save(&self, cache_root: &Path) -> Result<(), SsgError>
pub fn save(&self, cache_root: &Path) -> Result<(), SsgError>
Persists the graph atomically: writes <file>.tmp then renames.
POSIX rename is atomic on the same filesystem.
§Examples
use ssg::depgraph::DepGraph;
use tempfile::tempdir;
let dir = tempdir().unwrap();
let g = DepGraph::new();
g.save(dir.path()).unwrap();
assert!(dir.path().join("depgraph.json").exists());§Errors
Returns the underlying I/O failure if the cache root can’t be created or the temp file can’t be written / renamed.
Sourcepub fn add_dep(&mut self, consumer: &Path, dep: &Path)
pub fn add_dep(&mut self, consumer: &Path, dep: &Path)
Records that consumer depends on dep.
§Examples
use ssg::depgraph::DepGraph;
use std::path::Path;
let mut g = DepGraph::new();
g.add_dep(Path::new("page.md"), Path::new("layout.html"));
assert!(g.deps_for(Path::new("page.md")).is_some());Sourcepub fn add_output(&mut self, source: &Path, output: &Path)
pub fn add_output(&mut self, source: &Path, output: &Path)
Records that source produces output. Used by the AC5
delete-sweep to remove orphaned outputs when a source is
removed.
§Examples
use ssg::depgraph::DepGraph;
use std::path::Path;
let mut g = DepGraph::new();
g.add_output(Path::new("a.md"), Path::new("a.html"));
assert!(g.outputs_for(Path::new("a.md")).is_some());Sourcepub fn record_hash(&mut self, path: &Path, content: &[u8])
pub fn record_hash(&mut self, path: &Path, content: &[u8])
Records the SHA-256 freshness key for path from a byte slice.
§Examples
use ssg::depgraph::DepGraph;
use std::path::Path;
use std::collections::HashMap;
let mut g = DepGraph::new();
g.record_hash(Path::new("a.md"), b"hello");
// Same content ⇒ no diff.
let mut current = HashMap::new();
current.insert(Path::new("a.md").to_path_buf(), DepGraph::sha256_hex(b"hello"));
assert!(g.diff(¤t).is_empty());Sourcepub fn record_hash_from_disk(&mut self, path: &Path)
pub fn record_hash_from_disk(&mut self, path: &Path)
Records the SHA-256 of path by reading it from disk.
Silently ignores missing files (the caller will catch the
absence elsewhere — typically a delete that we want to record).
§Examples
use ssg::depgraph::DepGraph;
use tempfile::tempdir;
use std::fs;
let dir = tempdir().unwrap();
let p = dir.path().join("a.md");
fs::write(&p, "hi").unwrap();
let mut g = DepGraph::new();
g.record_hash_from_disk(&p);
// Missing files are silently ignored.
g.record_hash_from_disk(&dir.path().join("missing.md"));Sourcepub fn sha256_hex(bytes: &[u8]) -> String
pub fn sha256_hex(bytes: &[u8]) -> String
Returns the SHA-256 hex string for bytes. Exposed so the
populate helpers can hash files exactly once.
§Examples
use ssg::depgraph::DepGraph;
let hex = DepGraph::sha256_hex(b"");
// Empty string has a well-known SHA-256.
assert_eq!(hex, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");Sourcepub fn deps_for(&self, consumer: &Path) -> Option<&HashSet<PathBuf>>
pub fn deps_for(&self, consumer: &Path) -> Option<&HashSet<PathBuf>>
Returns the direct dependencies recorded for consumer.
§Examples
use ssg::depgraph::DepGraph;
use std::path::Path;
let mut g = DepGraph::new();
g.add_dep(Path::new("p.md"), Path::new("layout.html"));
assert_eq!(g.deps_for(Path::new("p.md")).map(|s| s.len()), Some(1));
assert!(g.deps_for(Path::new("none")).is_none());Sourcepub fn outputs_for(&self, source: &Path) -> Option<&HashSet<PathBuf>>
pub fn outputs_for(&self, source: &Path) -> Option<&HashSet<PathBuf>>
Returns the recorded outputs for source.
§Examples
use ssg::depgraph::DepGraph;
use std::path::Path;
let mut g = DepGraph::new();
g.add_output(Path::new("a.md"), Path::new("a.html"));
assert_eq!(g.outputs_for(Path::new("a.md")).map(|s| s.len()), Some(1));Sourcepub fn tracked_sources(&self) -> Vec<PathBuf>
pub fn tracked_sources(&self) -> Vec<PathBuf>
Returns every tracked source path (the keys of the output map).
§Examples
use ssg::depgraph::DepGraph;
use std::path::Path;
let mut g = DepGraph::new();
g.add_output(Path::new("a.md"), Path::new("a.html"));
assert_eq!(g.tracked_sources(), vec![Path::new("a.md").to_path_buf()]);Sourcepub fn page_count(&self) -> usize
pub fn page_count(&self) -> usize
Returns the count of edge consumers (pages + intermediate deps).
§Examples
use ssg::depgraph::DepGraph;
use std::path::Path;
let mut g = DepGraph::new();
assert_eq!(g.page_count(), 0);
g.add_dep(Path::new("p.md"), Path::new("l.html"));
assert_eq!(g.page_count(), 1);Sourcepub fn forget(&mut self, path: &Path)
pub fn forget(&mut self, path: &Path)
Removes every entry that references path as either a consumer
or a dependency. Called by Self::diff when a source is
deleted.
§Examples
use ssg::depgraph::DepGraph;
use std::path::Path;
let mut g = DepGraph::new();
g.add_dep(Path::new("p.md"), Path::new("l.html"));
g.forget(Path::new("p.md"));
assert!(g.deps_for(Path::new("p.md")).is_none());Sourcepub fn clear(&mut self)
pub fn clear(&mut self)
Clears the entire graph.
§Examples
use ssg::depgraph::DepGraph;
use std::path::Path;
let mut g = DepGraph::new();
g.add_dep(Path::new("p.md"), Path::new("l.html"));
g.clear();
assert_eq!(g.page_count(), 0);Sourcepub fn invalidated(&self, changed: &[PathBuf]) -> Vec<PathBuf>
pub fn invalidated(&self, changed: &[PathBuf]) -> Vec<PathBuf>
Returns every consumer reachable from any of changed via the
reverse edge map (transitive closure, AC3). Sources whose own
content changed are always included.
§Examples
use ssg::depgraph::DepGraph;
use std::path::{Path, PathBuf};
let mut g = DepGraph::new();
g.add_dep(Path::new("p.md"), Path::new("l.html"));
let changed = vec![PathBuf::from("l.html")];
// Changing the layout invalidates the page that consumes it.
assert!(g.invalidated(&changed).contains(&PathBuf::from("p.md")));Sourcepub fn invalidated_outputs(&self, changed: &[PathBuf]) -> Vec<PathBuf>
pub fn invalidated_outputs(&self, changed: &[PathBuf]) -> Vec<PathBuf>
Returns the union of output paths for every invalidated source. Sources that don’t appear in the output map (templates, partials, data files) contribute nothing.
§Examples
use ssg::depgraph::DepGraph;
use std::path::{Path, PathBuf};
let mut g = DepGraph::new();
g.add_dep(Path::new("p.md"), Path::new("l.html"));
g.add_output(Path::new("p.md"), Path::new("p.html"));
let outs = g.invalidated_outputs(&[PathBuf::from("l.html")]);
assert_eq!(outs, vec![PathBuf::from("p.html")]);Sourcepub fn diff(&self, current: &HashMap<PathBuf, String>) -> Diff
pub fn diff(&self, current: &HashMap<PathBuf, String>) -> Diff
Compares current (path → sha256) against the cached hashes
and returns (changed, deleted).
changed— paths whose current hash differs from cache, or paths that weren’t in the cache (new files).deleted— paths the cache knew about that are absent fromcurrent.
§Examples
use ssg::depgraph::DepGraph;
use std::collections::HashMap;
use std::path::PathBuf;
let g = DepGraph::new();
let mut current = HashMap::new();
current.insert(PathBuf::from("a.md"), DepGraph::sha256_hex(b"x"));
// Empty graph ⇒ everything in `current` looks new.
let d = g.diff(¤t);
assert_eq!(d.changed, vec![PathBuf::from("a.md")]);
assert!(d.deleted.is_empty());Trait Implementations§
Source§impl<'de> Deserialize<'de> for DepGraph
impl<'de> Deserialize<'de> for DepGraph
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Auto Trait Implementations§
impl Freeze for DepGraph
impl RefUnwindSafe for DepGraph
impl Send for DepGraph
impl Sync for DepGraph
impl Unpin for DepGraph
impl UnsafeUnpin for DepGraph
impl UnwindSafe for DepGraph
Blanket Implementations§
Source§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
Source§type ArchivedMetadata = ()
type ArchivedMetadata = ()
Source§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
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<F, W, T, D> Deserialize<With<T, W>, D> for F
impl<F, W, T, D> Deserialize<With<T, W>, D> for F
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
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<D> OwoColorize for D
impl<D> OwoColorize for D
Source§fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
Source§fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
Source§fn black(&self) -> FgColorDisplay<'_, Black, Self>
fn black(&self) -> FgColorDisplay<'_, Black, Self>
Source§fn on_black(&self) -> BgColorDisplay<'_, Black, Self>
fn on_black(&self) -> BgColorDisplay<'_, Black, Self>
Source§fn red(&self) -> FgColorDisplay<'_, Red, Self>
fn red(&self) -> FgColorDisplay<'_, Red, Self>
Source§fn on_red(&self) -> BgColorDisplay<'_, Red, Self>
fn on_red(&self) -> BgColorDisplay<'_, Red, Self>
Source§fn green(&self) -> FgColorDisplay<'_, Green, Self>
fn green(&self) -> FgColorDisplay<'_, Green, Self>
Source§fn on_green(&self) -> BgColorDisplay<'_, Green, Self>
fn on_green(&self) -> BgColorDisplay<'_, Green, Self>
Source§fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>
fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>
Source§fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>
fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>
Source§fn blue(&self) -> FgColorDisplay<'_, Blue, Self>
fn blue(&self) -> FgColorDisplay<'_, Blue, Self>
Source§fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>
fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>
Source§fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>
fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>
Source§fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
Source§fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>
fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>
Source§fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>
Source§fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>
fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>
Source§fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>
fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>
Source§fn white(&self) -> FgColorDisplay<'_, White, Self>
fn white(&self) -> FgColorDisplay<'_, White, Self>
Source§fn on_white(&self) -> BgColorDisplay<'_, White, Self>
fn on_white(&self) -> BgColorDisplay<'_, White, Self>
Source§fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
Source§fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
Source§fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
Source§fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
Source§fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
Source§fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
Source§fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
Source§fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
Source§fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
Source§fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
Source§fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
Source§fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
Source§fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
Source§fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
Source§fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
Source§fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
Source§fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
Source§fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
Source§fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
Source§fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
Source§fn bold(&self) -> BoldDisplay<'_, Self>
fn bold(&self) -> BoldDisplay<'_, Self>
Source§fn dimmed(&self) -> DimDisplay<'_, Self>
fn dimmed(&self) -> DimDisplay<'_, Self>
Source§fn italic(&self) -> ItalicDisplay<'_, Self>
fn italic(&self) -> ItalicDisplay<'_, Self>
Source§fn underline(&self) -> UnderlineDisplay<'_, Self>
fn underline(&self) -> UnderlineDisplay<'_, Self>
Source§fn blink(&self) -> BlinkDisplay<'_, Self>
fn blink(&self) -> BlinkDisplay<'_, Self>
Source§fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
Source§fn reversed(&self) -> ReversedDisplay<'_, Self>
fn reversed(&self) -> ReversedDisplay<'_, Self>
Source§fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
Source§fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::fg or
a color-specific method, such as OwoColorize::green, Read moreSource§fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::bg or
a color-specific method, such as OwoColorize::on_yellow, Read more